1.描述
输入捕获模式下,当通道输入引脚出现指定电平跳变时,当前CNT的值将被锁存到CCR中,可用于测量PWM波形的频率、占空比、脉冲间隔、电平持续时间等参数。
每个高级定时器和通用定时器都拥有4个输入捕获通道。
可配置为PWMI模式,同时测量频率和占空比。
可配合主从触发模式,实现硬件全自动测量。
2.频率测量
• 测频法:在闸门时间 T 内,对上升沿计次,得到 N ,则频率 (高频信)𝑓𝑥 =N / T• 测周法:两个上升沿内,以标准频率 f c 计次,得到 N ,则频率 (低频信号)𝑓𝑥 =fc / N• 中界频率:测频法与测周法误差相等的频率点 (±1误差;令N相等求fm)𝑓𝑚=√(fc / T)
注:如需测量正弦波要用运放搭建比较器 ,把正弦波转换为数字信号,在输入STM32;频率高加隔离装置。
3.主从触发模式
这部分对应三个函数在应用是调用即可,不同模式对应的功能查手册。
4.代码逻辑配置
注:读取CCR1=N,选择测量方法就得到信号频率了。
CNT有上限,ARRmax=CNTmax=65535,即信号频率不能太大,否则CNT会溢出。
因为触发源选择只有通道1、2,所以想要用从模式只能使用通道1、2;对于通道3、4只能用中断手动清零(代码复杂,消耗软件资源)。
用TI1FP1捕获CCRI是整个周期的计数值;用TI1FP2捕获CCR2是高电平的计数值。即PWM=CCR2/CCR1
5.代码部分(标准库)
用信号发生器产生方波(高电平3.3V,共地;也可以用LM324焊)接TIM3_CH1,PA6引脚进行测量。
void IC_Init(void)
{
//开启时钟
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
//配置GPIO
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //上拉输入
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
//配置时基单元
TIM_InternalClockConfig(TIM3);
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInitStructure.TIM_Period = 65536 - 1; //ARR;防止溢出;最低频率15Hz
TIM_TimeBaseInitStructure.TIM_Prescaler = 72 - 1; //PSC;1MHz
TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseInitStructure);
//初始化输入捕获单元
TIM_ICInitTypeDef 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; //分频值1,2,4,8
TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;//数据选择器;直连通道
TIM_PWMIConfig(TIM3, &TIM_ICInitStructure); //自动配置TIM_Channel_2为下降沿触发
TIM_SelectInputTrigger(TIM3, TIM_TS_TI1FP1); //选择触发源
TIM_SelectSlaveMode(TIM3, TIM_SlaveMode_Reset); //配置从模式
TIM_Cmd(TIM3, ENABLE); //启动定时器
}
uint32_t IC_GetFreq(void) //Freq = 72M / (PSC + 1) / 100
{
return 1000000 / (TIM_GetCapture1(TIM3) + 1); //消除误差±1
}
uint32_t IC_GetDuty(void) //Duty = CCR / 100
{
return (TIM_GetCapture2(TIM3) + 1) * 100 / (TIM_GetCapture1(TIM3) + 1); //CCR2/CCR1
}
注:代码采用测周法适合低频率;15Hz~10KHz
误差在0.1%=1M/1000=1KHz
误差在1%=1M/100=10KHz
提高标准频率,上限会提高;在高频改用测频法。
晶振误差还没想好怎么消除