各种教程中,都只解释中断的机制、使用。但对于中断标志的清理顺序,没多少官方准确的资料。
今天在F429的代码里,又遇到问题:进中断后卡死跳不出来,各种排查没发现问题。
快要出门时,才突然想起来,要把清理中断的语句,从最后一行,移到第一行。重新编译烧录,马上通过。
真是奇怪的问题。
例1:后清理,卡死
测试环境:F429IG + TIM6的中断
void TIM6_DAC_IRQHandler()
{
LED_BLUE_TOGGLE ; // 反转LED
TIM6->SR &= ~(0x01); // 清理中断标志
}
上面的两行示例代码,死活没法子看出有啥毛病,但程序卡死。几乎耗了一个上午排查周边代码。
修改成如下顺序,先清理中断标志,马上顺利通过。
void TIM6_DAC_IRQHandler()
{
TIM6->SR &= ~(0x01); // 重点,重点,重点,必须先清中断后处理其它事情,否则卡死
LED_BLUE_TOGGLE ; // 反转LED
}
为什么呢?百度了半晌,真没找到答案。
测试时发现,在F103中,TIM的中断也都必须是先清理中断标示,不然同样会发生卡死、没按预期中断、计时倍减等问题。
例2:先清理后清理,没事
问题:必须是先清中断标志吗?不是的。发现有很多中断函数不是必须先清理。
测试环境:F429IG + 外部中断线中断(项目中是做按键的)
void EXTI15_10_IRQHandler(void)
{
// EXTI->PR |= KEY_2_PIN ; // 位置 1
LED_BLUE_TOGGLE ;
EXTI->PR |= KEY_2_PIN ; // 位置 2
}
同是F4的芯片, 在上面的代码中,位置1 的先清理,与位置2 的后清理,没区别,经测试都能正常工作的。