STM32的单时钟多通道输入捕获的尝试

  • Post author:
  • Post category:其他




单时钟多通道输入捕获

背景:用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个信号的捕获



版权声明:本文为qq_43646449原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。