stm32發送數據給上位機用串口調試助手接收爲什麼只接收到第一個字節數據?

    最近剛好要做一個舵機的狀態包反饋,用串口調試助手接收調試。然後發現中斷接收數據後,將數據發送給上位機(調試助手)時只接收到了最後一個字節的數據,後來以爲數據發送的太快了,然後在每個字節發送完都加了延時,結果發現只接收到第一個數據。

1、 在這個過程中,通過調試我發現中斷似乎可以接收到完整的數據。但只要通過串口發給上位機,就只接收到第一個數據。所以我用下面的代碼來調試。

            

wKioL1nRjtvDtSLbAABn9ZdX3kU732.png-wh_50

wKiom1nRkNmzK1g0AAC-l6zGzQQ926.png-wh_50

wKioL1nRnUbx95ZEAACw5RN1OIY197.png-wh_50

 

    其中,串口配置爲USART1波特率9600,8位數據位,1位停止位,收發模式,無流控。接收中斷打開。串口使能。delay_ms(1500)使用systick定時器設置的1.5s的延時函數。

    經過測試,這段代碼只能接收到第一個1個字節的數據,也就是只收到0x01。如果延時函數去掉只接收到最後一個字節,即0x03。

    這是爲什麼呢?

    原來在發送第一個字節數據的時候我沒有等待TXE(發送寄存器爲空)標誌位被置位,導致了第一個數據沒有傳輸完成,第二個就已經在發送了。所以產生了錯誤。有人想說那我加了延時是吧?按道理說延時1.5S已經夠一個字節的傳輸了,但是這種方法不行,具體原因我也不太清楚,只有通過等待TXE標誌置位才能接着發送第二個字節數據。

    代碼如下:

wKiom1nRleeC5EZ6AAAyRPX3Rkk190.png-wh_50

wKioL1nRlaGyl-0mAAAV8oWz-sk575.png-wh_50

    這樣就可以接收到完整的數據了。

 2、上面講到的是我們可以接收到完整的數據來進行發送,解決了發送端的問題。其實我當時的感覺是不對的。haha。我並沒有接收到完整的數據包。因爲我用上面的代碼來發送接收到的數據包時,也只接收到一個字節數據,0xff。下面來說說接收端的可能出現的問題。

    (1)首先,我們先來了解一下接收到的這個數據0xff是什麼?

    原來,在發送的時候,當TE位被激活時,USART會發送一個空閒幀數據,即0xff。空閒幀是什麼請自行查閱數據手冊。

    也就是說我除了空閒幀,我一個數據都沒接收到。

    (2)爲什麼一個數據都沒接收到?

    當我們的中斷接收處理程序處理時間太長時,會發生溢出錯誤,導致後面的數據接收不到。

    當一個字符被接收時,RXNE位被置位。它表明移位寄存器的內容被轉移到RDR(數據寄存器),換句話說,數據已經被接收並且可以被讀出了。如果RXNE還沒有被複位,又接收到一個字符,則發生溢出錯誤。數據只有當RXNE位被清零後才能從移位寄存器轉移到RDR寄存器。RXNE標記是接收到每個字節後被置位的。如果下一個數據已被收到或先前DMA請求還沒被服務時,RXNE標誌仍是置起的,溢出錯誤產生。

    溢出錯誤產生時:

    ----RDR內容將不會丟失。讀USART_DR寄存器仍能得到先前的數據。

    ----移位寄存器中以前的內容將被覆蓋。隨後接收到的數據都將丟失。

    ----如果RXNE=1,上一個有效數據還在接收寄存器RDR上,可以被讀出。

    ----如果RXNE=0,這意味着上一個有效數據已經被讀走,RDR已經沒有東西可讀。當上一個有效數據在RDR中被讀取的同時又接收到新的(也就是丟失的)數據時,此種情況可能發生。在讀序列期間(在USART_SR寄存器讀訪問和USART_DR讀訪問之間)接收到新的數據,此種情況也可能發生。

    解決了溢出錯誤,只接收到一個字節數據的問題基本已經解決了。

    本博文多參考數據手冊,建議讀者使用USART時將有關部分仔細閱讀。

    

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章