STM32 串列埠進入中斷,但是沒有檢查到接收資料位!!!!

Aliang2020發表於2024-12-04

最近做專案有機率遇到串列埠進入中斷(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觸發。

RXNE:讀資料暫存器非空 (Read data register not empty):當RDR移位暫存器中的資料被轉移到USART_DR暫存器中,該位被硬體置位。如果USART_CR1暫存器中的RXNEIE為1,則產生中斷。對USART_DR的讀操作可以將該位清零。RXNE位也可以透過寫入0來清除,只有在多快取通訊中才推薦這種清除程式。 0:資料沒有收到; 1:收到資料,可以讀出。

ORE:過載錯誤 (Overrun error):當RXNE仍然是’1’的時候,當前被接收在移位暫存器中的資料,需要傳送至RDR暫存器時,硬體將該位置位。如果USART_CR1中的RXNEIE為’1’的話,則產生中斷。由軟體序列將其清零(先讀USART_SR,然後讀USART_CR)。  0:沒有過載錯誤;  1:檢測到過載錯誤。
注意:該位被置位時,RDR暫存器中的值不會丟失,但是移位暫存器中的資料會被覆蓋。如果設定了EIE位,在多緩衝器通訊模式下,ORE標誌置位會產生中斷的
(ORE會導致硬體復位,如果遇到這個問題是沒有辦法透過軟體復位決絕的,剛開始遇到這個問題,已經是我寫的程式有問題,打算新增看門狗進行軟體復位,發現沒有效果)

在開啟接收使能時,會一起開始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;
}

相關文章