STM32中断标志:先清理后清理的区别

2025-08-10 21:32:466004

先上总结,再闲聊爬坑过程:

进入中断函数后,先清理中断标志,再执行其它动作。

爬坑过程:

各种教程中,都只解释中断的机制、使用。但对于中断标志的清理顺序,没多少官方准确的资料。

今天在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 的后清理,没区别,经测试都能正常工作的。

原因解释 (2023-07-13补充)

清除中断标志,如果放在中断服务函数的最后,硬件还没有把标志清除完毕,程序已经跳出了中断服务函数,这时候NVIC又会识别到中断标志,再次进入中断服务函数。