最近做專案有機率遇到串列埠進入中斷(LED閃爍來判斷),但是沒有檢查到接收資料位 USART_IT_RXNE ,導致一直卡在判斷語句 USART_GetITStatus(USART2, USART_IT_RXNE) != RESET,導致程式卡死。透過keil 除錯模式的軟體復位都沒有用,需要硬體復位才行。透過百度發現這個現象挺常見的。這邊我也整理一下,方便後面的檢視。
1.問題定位:透過硬體發現問題後,進入keil 除錯模式判斷下問題在何處
在接收判斷前後加入printf,來定位問題在何處。透過PC串列埠輸出來定位,發現只能輸出111111,不輸出222222,說明中斷是有觸發,但是沒有檢查到接收資料位
2.問題分析
遇到問題先百度:透過檢視大佬的分析----產生ORE中斷了,但使用USART_GetITStatus()函式卻無法讀到這個中斷被SET起來!(https://blog.csdn.net/love_maomao/article/details/8234039)
本質問題:RXNE還沒來得及復位(資料可能可能被讀傳走也有可能沒有被傳走),就接收到新的字元,導致溢位錯誤,從而觸發串列埠2的中斷相應,這和HardFault_Handler錯誤挺像的,都是都是溢位導致的硬體錯誤,後面也會講下這個問題。
並不是RXNE 觸發的USART2_IRQHandler中斷,而是ORE觸發USART2_IRQHandler中斷,和我一開始理解的有誤,我理解成是RXNE觸發。
在開啟接收使能時,會一起開始ORE中斷使能,沒有辦法透過關閉ORE使能來規避問題。因此需要檢查到ORE標誌位後,需要手動清除ORE標誌位。
3.解決辦法:
使用USART_ClearITPendingBit();無法清除ORE的標誌位,該函式只有CTS,LDB,TC和RXNE。
查詢庫函式手冊:
最終加一個判斷:
if(USART_GetFlagStatus(USART2,USART_FLAG_ORE) == SET) // 檢查 ORE 標誌
{
USART_ClearFlag(USART2,USART_FLAG_ORE);
USART_ReceiveData(USART2);
rxIndex = 0;
}