加入星計劃,您可以享受以下權(quán)益:

  • 創(chuàng)作內(nèi)容快速變現(xiàn)
  • 行業(yè)影響力擴散
  • 作品版權(quán)保護
  • 300W+ 專業(yè)用戶
  • 1.5W+ 優(yōu)質(zhì)創(chuàng)作者
  • 5000+ 長期合作伙伴
立即加入
  • 正文
  • 相關推薦
  • 電子產(chǎn)業(yè)圖譜
申請入駐 產(chǎn)業(yè)圖譜

串口跑著跑著又死掉了,是怎么回事?

09/15 11:00
2377
閱讀需 4 分鐘
加入交流群
掃碼加入
獲取工程師必備禮包
參與熱點資訊討論

串口是MCU最經(jīng)常使用的外設之一,我遇到過多起串口在使用過程中出現(xiàn)死掉的實際案例。

這種問題在測試階段如果發(fā)現(xiàn)了還好,一旦批量出去在現(xiàn)場發(fā)生就更加麻煩了。今天說的死掉,其實真實現(xiàn)象是MCU一直在不停的進串口中斷,導致其他代碼無法正常執(zhí)行。

遇到該問題的罪魁禍首是串口Overrun,即溢出所致。Overrun其實很好理解,串口在接收數(shù)據(jù)的時候,每一字節(jié)數(shù)據(jù)經(jīng)移位寄存器數(shù)據(jù)寄存器,所謂溢出就是指,上一個字節(jié)的數(shù)據(jù)在數(shù)據(jù)寄存器還沒有被讀取走,新的1字節(jié)數(shù)據(jù)又已經(jīng)被移入到移位寄存器的現(xiàn)象。以STM32F030為例,其他家的MCU也類似,Overrun錯誤標志位位于USART_ISR寄存器中。

Overrun現(xiàn)象我們可以這么產(chǎn)生:在串口中斷服務函數(shù)剛開始處加一個斷點,debug全速運行,通過串口調(diào)試助手一下發(fā)送2個字節(jié)的數(shù)據(jù),這時就會出現(xiàn)Overrun,原因就是進入到斷點處還沒有去讀數(shù)據(jù),但是新的數(shù)據(jù)又來了。

手冊中描述當此標志位置位時,RDR寄存器中的數(shù)據(jù)沒有丟失,我們可以看到RDR內(nèi)容就是第一個字節(jié)0x31。

默認情況下,Overrun檢測功能時開啟的,USART_CR3寄存器的OVRDIS位可以把該功能關掉。

當把溢出檢測功能給關掉,要注意的是新來的數(shù)據(jù)會覆蓋USART_RDR寄存器中的數(shù)據(jù)。

我們在代碼串口初始化中把溢出功能關閉,同樣做之前的實驗,這時可以看到RDR的值就不是之前的0x31,而是0x32了,ISR里ORE標志位也不會置位了。

出現(xiàn)死掉的問題是因為來了ORE中斷,但是中斷服務函數(shù)沒有去處理所致,所以就會一直進中斷。

其實解決該問題的方法也非常簡單,就是在中斷服務函數(shù)里加入該標志位的清除操作即可?;蛘吒纱嗑桶岩绯龉δ荜P閉不使用也行。

MCU里Overrun這個標志本來目的是為了提醒數(shù)據(jù)傳輸過程中出錯了,接收端需要通知發(fā)送端重傳。但是實際應用中大家一般也不這么用,為了保證串口數(shù)據(jù)通信的正確性,一般都會在應用層上加上數(shù)據(jù)幀的校驗,有了校驗其實用不用溢出功能也無所謂了。

最后強調(diào)一下:如果MCU開啟了Overrun功能,一定要在中斷服務函數(shù)里加入清溢出標志的操作。不加Overrun標志位處理大部分情況下也許不會出問題,但是一旦溢出可就麻煩大了。

相關推薦

電子產(chǎn)業(yè)圖譜

TopSemic,讓芯片使用更簡單。 專注分享:嵌入式,單片機,STM32,ARM,RTOS,Linux, 軟硬件,半導體,電子技術(shù)等相關內(nèi)容。