各種教程中,都只解釋中斷的機制、使用。但對於中斷標誌的清理順序,沒多少官方準確的資料。
今天在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 的後清理,沒區別,經測試都能正常工作的。
總結:進中斷後,首先清理中斷標誌!