TIM IC(定时器输入捕获)
输入捕获模式下,当通道输入引脚出现指定电平跳变时,当前CNT的值将被锁存到CCR中。
可用于测量PWM波形的频率、占空比、脉冲间隔、电平持续时间等参数。
每个高级定时器和通用定时器都拥有4个输入捕获通道。
- 可配置为PWMI模式,同时测量频率和占空比。
- 可配合主从触发模式,实现硬件全自动测量。
实现硬件全自动测量可避免频繁进入中断函数,节省CPU资源。
测频法:
- 计次:待测信号在闸门时间内经过的周期数。—— 闸门时间内捕获波形上升沿个数,较简单。
- 适用于高频信号,在闸门时间内越多周期经过,精度越高。
- 更新慢,更新时间取决于闸门时间。测出的是闸门时间内的平均频率。相当于自带滤波。\、
测周法:
- 计次:在待测信号一个周期内经过的标准周期个数。—— 下面主要讨论这个方法。
- 适用于低频信号,在待测波形一个周期内经过的标准周期越多,精度越高。
- 更新快,更新时间取决于待测波形周期。
“+-1误差”:对于测频法,闸门时间已到,最后一个波形没走完;对于测周法,周期已到,标准波形没走完;这都会产生正负一误差。
通用定时器ch1、ch2结构图:
例程 - 测PWM频率和占空比
采用TIM2生成PWM信号,TIM3输入捕获,用PWMI模式测定PWM的频率和占空比。此处不列出生成PWM信号的代码,可以参考:PWM控制SG90舵机,生成频率1kHz,占空比千分之500的PWM信号。
// main.c #include "stm32f10x.h" // Device header #include "OLED.h" #include "Delay.h" #include "PWM.h" #include "InputCapture.h" int main(void) { OLED_Init(); PWM_Init(); InputCapture_Init(); PWM_Set_PSC(72-1); // Freq = 72M / (PSC + 1) / 1000,PSC=72-1,Freq = 1KHz PWM_Set_CCR1(500); // Duty = CCR / 1000 OLED_ShowString(1, 1, "Freq:00000Hz"); OLED_ShowString(2, 1, "Duty:0000/1000"); while(1) { OLED_ShowNum(1, 6, InputCapture_Get_Freq(), 5); OLED_ShowNum(2, 6, InputCapture_Get_Duty(), 4); Delay_ms(200); } }
// InputCapture.c #include "stm32f10x.h" // Device header void InputCapture_Init(void) { // 时钟 RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); TIM_InternalClockConfig(TIM3); // GPIO - TIM3 CH1 - PA6 GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); // 时基单元 TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStrucure; TIM_TimeBaseInitStrucure.TIM_ClockDivision = TIM_CKD_DIV1; TIM_TimeBaseInitStrucure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInitStrucure.TIM_Period = 65535; // ARR TIM_TimeBaseInitStrucure.TIM_Prescaler = 72 - 1; // PSC 决定测周法的标准频率f。PSC=72-1, f=1M // 关于测频率上下限和修改,看江科大视频34:00处 TIM_TimeBaseInitStrucure.TIM_RepetitionCounter = 0; TIM_TimeBaseInit(TIM3, &TIM_TimeBaseInitStrucure); // 输入捕获单元 TIM_ICInitTypeDef TIM_ICInitStructure; TIM_ICStructInit(&TIM_ICInitStructure); TIM_ICInitStructure.TIM_Channel = TIM_Channel_1; TIM_ICInitStructure.TIM_ICFilter = 0xF; TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising; TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1; TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; TIM_PWMIConfig(TIM3, &TIM_ICInitStructure); // PWMI模式,江科大视频28:49处 // 主从触发模式 - 触发源和从模式 TIM_SelectInputTrigger(TIM3, TIM_TS_TI1FP1); TIM_SelectSlaveMode(TIM3, TIM_SlaveMode_Reset); // 启动定时器 TIM_Cmd(TIM3, ENABLE); } uint32_t InputCapture_Get_Freq(void) // 读取频率,单位赫兹 { uint32_t n = TIM_GetCapture1(TIM3); return 1000000 / n; } uint16_t InputCapture_Get_Duty(void) // 读取占空比,0-1000,单位千分之 { return TIM_GetCapture2(TIM3) * 1000 / TIM_GetCapture1(TIM3); }