STM32输入捕获中断函数逻辑理解
写在前面:
本人最近在初学stm32定时器的应用之输入捕获的时候,发现其中断函数处理上升沿和下降沿的逻辑比较难理解,于是花了一些时间写下理解的过程。若有不正确之处,望请指正!!!
问题描述:首先,本篇没有讲述输入捕获的原理,寄存器状态等,重点在于中断函数逻辑层的分析。
----实验目的是检测输入信号的脉冲宽度,那么就需要检测到输入波形的上升沿和同一周期的下降沿。如果两个边沿都处于一个时钟周期之内(计数器没有溢出),那么用两个得到的计数值相减再乘以周期就得到时间;若信号长度大于一个时钟(计数器溢出),那么计数值将会在过程中重置若干次。怎么解决这种情况呢?
2. 自定义变量:
TIM3CH1_CAPTURE_VAL | TIM3CH1_CAPTURE_STA |
---|---|
用来记录计数器的值 | ![]() |
3.总过程描述:
(思路来自正点原子stm32定时器输入捕获讲解)
这里以初始化开启上升沿捕获为例(捕获到上升沿触发中断进入中断程序):首先,判断捕获是否完成(第七位是否为1),若完成,则不执行任何中断代码,若未完成,则判断计数器是否发生溢出和是否发生捕获。若发生捕获且为上升沿,则要将此点设为起点,TIM3CH1_CAPTURE_VAL设为0,TIM3CH1_CAPTURE_STA的第7位设为0,计数器置零,最后将中断设置为下降沿捕获,为捕获下降沿做好准备。若发生捕获且为下降沿,则表示已经捕获到完整的电平信号了,此时将TIM3CH1_CAPTURE_STA第8位设为1,不再进入中断程序(想要开启须在外部开启,如在主程序中将第八位置0),然后用TIM3CH1_CAPTURE_VAL记录下计数器的值。
如果触发了更新标志,则用最后六位记录更新次数。当达到最大值,也就是第六位全部为1时(不能再增大了),则要强制结束捕获(TIM3CH1_CAPTURE_STA最高位置1),将TIM3CH1_CAPTURE_VAL设为最大值0xFFFF,若未到最大值,则TIM3CH1_CAPTURE_STA++。
4. 最后展示TIM 中断函数中的全部代码(注释自加,帮助理解):
void TIM3_IRQHandler(void)
{
if(TIM3CH1_CAPTURE_STA&0X80==0) //表示未捕获完成
{
if(TIM_GetITStatus(TIM3,TIM_IT_Update) != RESET) //计数器溢出(更新)
{
if(TIM3CH1_CAPTURE_STA&0X40)//捕获到下降沿
{
if(TIM3CH1_CAPTURE_VAL&0x3f==0x3f) //如果达到最大值,因为这8位中的低六位都是用来计数的,当低六位都为1时,就达到了记录次数的最大值,所以不能再加了
{
TIM3CH1_CAPTURE_VAL=0xffff; //最大值65535
TIM3CH1_CAPTURE_STA|=0x80;//标记为捕获完成,此时最高位为1了,不能再进入中断,只能在其他地方开启中断(标志位设为0)
//TIM3_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising; //重新开启上升沿捕获
}
else TIM3CH1_CAPTURE_STA++;
}
}
if(TIM_GetITStatus(TIM3,TIM_IT_CC1)!=RESET) //发生捕获 (捕获到高/低电平(取决于初始化中的上升沿或者下降沿捕获))
{
if(TIM3CH1_CAPTURE_STA&0x40) //捕获到下降沿
{
TIM3CH1_CAPTURE_STA|=0x80;//标记为捕获完成,此时最高位为1了,不能再进入中断,只能在其他地方开启中断(标志位设为0)
TIM3CH1_CAPTURE_VAL=TIM_GetCapture1(TIM3);//记录下此时的计数值
TIM3_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising; //重新开启上升沿捕获
}
else
{
TIM3CH1_CAPTURE_VAL=0; //设为开启
TIM_SetCounter(TIM3,0); //计数器置0
TIM3CH1_CAPTURE_STA=0; //捕获未完成
TIM3CH1_CAPTURE_STA|=0x40; //标记捕获到上升沿
TIM3_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Falling; //开启下降沿捕获
}
}
}
TIM_ClearITPendingBit(TIM3, TIM_IT_CC1|TIM_IT_Update);
}
~~以上~~