单时钟多通道输入捕获
背景:用3个超声波模块同时进行测距,计划通过输入捕获来实现。查找资料发现他人做的多通道输入捕获,不过以看到的好像都是信号单输入的,对同一个信号(PWM)进行上升沿、下降沿的捕获。但是我想实现
一个定时器的多个通道对多个输入信号进行捕获
,对多个方面都做了一点尝试,但是还是未能成功。写一篇记录一下,若是以后有机会完善再在后面加上。
0、单通道单输入信号捕获
代码重点是输入捕获的中断逻辑函数。下面是最简单的单通道对单个信号进行捕获(捕获PWM波的高电平的时长),整个逻辑为:
①捕获初始设置为上升沿触发
②捕获到上升沿,进入中断函数
③判断发生上升沿捕获,使能定时器,开始计数
④同时将捕获设置为下降沿触发
⑤捕获到下降沿,再次进入中断函数
⑥判断发生下降沿捕获,关闭定时器,并读取当前定时器的值
注:本中断函数还包括定时器的溢出中断
//中断服务程序
void TIM5_IRQHandler(void)
{
if((TIM5CH3_CAPTURE_STA&0X80)==0)//还未成功捕获
{
if(TIM_GetITStatus(TIM5, TIM_IT_Update) != RESET)//溢出
{
if(TIM5CH3_CAPTURE_STA&0X40)//已经捕获到高电平了
{
if((TIM5CH3_CAPTURE_STA&0X3F)==0X3F)//高电平太长了
{
TIM5CH3_CAPTURE_STA|=0X80;//标记成功捕获了一次
TIM5CH3_CAPTURE_VAL=0XFFFFFFFF;
}else TIM5CH3_CAPTURE_STA++;
}
}
if(TIM_GetITStatus(TIM5, TIM_IT_CC3) != RESET)//捕获1发生捕获事件
{
if(TIM5CH3_CAPTURE_STA&0X40)//捕获到一个下降沿
{
TIM5CH3_CAPTURE_STA|=0X80;//标记成功捕获到一次高电平脉宽
TIM5CH3_CAPTURE_VAL=TIM_GetCapture3(TIM5);//获取当前的捕获值.
TIM_OC3PolarityConfig(TIM5,TIM_ICPolarity_Rising);//CC3P=0 设置为上升沿捕获
}else//还未开始,第一次捕获上升沿
{
TIM5CH3_CAPTURE_STA=0;//清空
TIM5CH3_CAPTURE_VAL=0;
TIM5CH3_CAPTURE_STA|=0X40;//标记捕获到了上升沿
TIM_Cmd(TIM5,DISABLE );//关闭定时器5
TIM_SetCounter(TIM5,0);
TIM_OC3PolarityConfig(TIM5,TIM_ICPolarity_Falling); //CC3P=1 设置为下降沿捕获
TIM_Cmd(TIM5,ENABLE );//使能定时器5
}
}
}
TIM_ClearITPendingBit(TIM5, TIM_IT_CC3|TIM_IT_Update); //清除中断标志位
}
1、双通道单信号(测PWM占空比)
查找资料看到实现双通道的输入捕获,其实这个功能也完全可以用一个通道实现。中断函数的逻辑为:
①CH1捕获设置为上升沿触发,CH2捕获设置为下降沿触发
②CH1捕获到上升沿,进入中断函数
③判断发生上升沿捕获,读取此时计数器的值TIM_NUM_2,CNT清零,开始计数
④CH2捕获到下降沿,进入中断函数
⑤判断发生下降沿捕获,读取此时计数器的值TIM_NUM_1,CNT不清零,继续计数
注:PWM占空比就是TIM_NUM_1/(TIM_NUM_1+TIM_NUM_2)
2、双通道双信号(获取两个PWM波的高电平时长)
因为一个定时器只有一个计数器,所以在捕获两个信号时我们要租到避免两个信号同时被触发,导致计数器计数紊乱。这里我想到的是定义一个标志位STATE,为0时允许CH1中断,为1时允许CH2中断:
①CH1、CH2都设置为上升沿触发,STATE标志位初始为0,设置允许CH1捕获中断,不允许CH2捕获中断
②CH1捕获到上升沿,进入中断函数
③使能定时器,CNT清零,开始计数,并将CH1设置为下降沿触发
④CH1捕获到下降沿,进入中断函数
⑤停止定时器,读取当前CNT的值,将CNT清空,将CH1设置为上升沿触发;将STATE设置为1,设置不允许CH1捕获中断,允许CH2捕获中断
⑥CH2捕获到上升沿,进入中断函数
⑦使能定时器,CNT清零,开始计数,并将CH2设置为下降沿触发
⑧CH2捕获到下降沿,进入中断函数
⑨停止定时器,读取当前CNT的值,将CNT清空,将CH2设置为上升沿触发;将STATE设置为0,设置允许CH1捕获中断,不允许CH2捕获中断
注:核心即是CH1与CH2轮流使用计数器;实际代码实现中还是会产生bug,CH1对计数器的调用没有问题,CH2调用会产生bug
3、多通道多信号(一点想法)
因为一个定时器只有一个计数器,所以在捕获多个信号时我们要租到避免多个信号同时触发捕获,导致计数器计数紊乱。我设想,在一个比较低得频率下(远小于PWM的频率),让定时器1的CH1、CH2、CH3、CH4对计数器时分复用,而并非自主的判断并使用。
调用定时器2,设置好分频系数和重装载值,让其频率为100Hz:每过10ms会产生一个溢出中断,在这个中断中循环允许定时器1的CH1、CH2、CH3、CH4四个通道产生捕获中断。
优点:减少IO口的使用,只需要4个IO即可完成对4个信号的捕获