今天本来做一个很简单的项目,要测脉宽,结果陷入莫名奇妙的bug:一开始一切都是对的,但是程序跑一会儿就会进入HardFault中断,我根本没怎么操作内存也没数组怎么就硬件错误呢?仔细分析脉宽测量程序,发现每隔几百毫秒(时间不定),就会出现测量值不正确的情况,遂开始单步调试,得出以下结论:STM32在判断输入捕获时会同时引发定时器更新中断。
请看如下程序:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
void TIM3_IRQHandler(void) { if(TIM_GetITStatus(TIM3,TIM_IT_CC2)!=RESET) //CC2中断 { if(MyCC1.Flag == 0) { MyCC1.Flag = 1; MyCC1.CC1 = (u32)TIM3->CCR2; } else { MyCC1.CC2 = (u32)TIM3->CCR2; Update_CurrCycle(); MyCC1.Flag = 0; MyCC1.Overflow = 0; } TIM_ClearITPendingBit(TIM3,TIM_IT_CC2); TIM_ClearITPendingBit(TIM3,TIM_IT_Update); //这句话是重点 } if(TIM_GetITStatus(TIM3,TIM_IT_Update)!=RESET) //溢出中断 { if(MyCC1.Flag && MyCC1.Overflow++ >= 0xFF) MyCC1.Overflow = 0xFF; TIM_ClearITPendingBit(TIM3,TIM_IT_Update); } } |
如果上述程序19行被去除,你在任何进入TIM3的CC2中断时候单步程序,会发现总是能进Update更新或称溢出中断,所以会引起MyCC1.Overflow的自加不正确,从而无法正确测量超过一个定时器周期的脉宽。
最后友情提醒,当初始化定时器中断时也要先清一下中断标志位,否则可能会出现刚初始化完就莫名其妙进中断的情况,贴出我的程序片段以供参考:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
//上头还有很多代码... TIM_ARRPreloadConfig(TIM3, ENABLE); //使能TIM2重载寄存器ARR TIM_ClearITPendingBit(TIM3, TIM_IT_CC2); //重要 TIM_ClearITPendingBit(TIM3,TIM_IT_Update); //重要 TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE); TIM_ITConfig(TIM3,TIM_IT_CC2,ENABLE); NVIC_InitTypeDef nv; nv.NVIC_IRQChannel = TIM3_IRQn; nv.NVIC_IRQChannelCmd = ENABLE; nv.NVIC_IRQChannelPreemptionPriority = 0; nv.NVIC_IRQChannelSubPriority = 0; NVIC_Init(&nv); //下面还有很多 |
Pingback引用通告: viagra