關於STM32 USART(串口)發送資料丟失第一幀的真實原因探索

來源:互聯網
上載者:User

標籤:

自我介紹為什麼要寫個自我介紹?俗話說,光說不練假把式,光練不說傻把式, 因為本人一直很自負,感覺什麼東西都可以很快上手(當然非對口專業知識要求高的技能除外),如果我不把這自負表現出來,感覺會憋出內傷。本人於2015年畢業於電子科技大學,開始的理想是進入一家國外的遊戲公司,但理想很豐滿,現實很骨感,給育碧、2k Game、Gameloft、EA都投了簡曆,但都被無情pass掉了(在此吐槽一下,這些公司真的是想在校園裡招本科生嗎?明明是研究生的電腦圖形學卻成了這些公司對本科生的要求)。後來畢業了也沒找到工作,為了自力更生,就隨便去了家電氣公司,也就是我現在的公司。這是家才建立的公司,業務是做智能應急疏散照明系統這一塊,雖然老總也給我說以後要搞物聯網,但我感覺這是當初忽悠我來公司的。公司對軟體開發的認識基本停留在零,也不願意花錢請個進階軟體工程師,因此我成了公司的獨苗,既要負責進階程式的開發,又要進行底層開發。雖然在學校裡沒用過C#,但語言都有相通之處,因此對於現在公司的上位機程式的開發還是遊刃有餘,但底層開發的經驗基本沒用。雖然之前在一家公司的試用期中,我開始接觸了單片機,但因為我本人不喜歡純拷貝別人的代碼,所以當公司要我給51單片機寫個串口通訊的時候,瀏覽了下STC的資料手冊就模稜兩可的進行開發,然後卡住了,對比了網上的那些程式,感覺自己的步驟沒有錯啊,這次事件讓自詡學習能力強的我備受打擊,於是從那家公司辭職了,現在回想起來,可能當時我沒注意到51單片機的串口的傳輸速率發生器只能使用T1,而我一直使用T0作為傳輸速率發生器。最近開始接觸STM32系列晶片,因為有韌體庫對底層寄存器的操作進行了封裝,很接近進階編程,學起來跟用起來都很方便,而且現在很多移動晶片也是基於ARM架構的,所以學好ARM晶片也是敲開很多大型企業的敲門磚(我就想用它敲開華為的大門)。問題描述網上搜尋“STM32 BUG”,就會搜到困擾很多STM32開發人員的的兩個問題,一個是關於I2C的,另一個就是關於串口發送資料丟失第一幀的問題。因為我還接觸I2C,所以第一個問題是怎麼回事我不知道。雖然第二個問題,網上也有問題原因的解答,而且按照這些答案中的方式來編寫串口發送程式可以防止丟失第一幀資料。因為我不想照搬別人的程式,因此在機緣巧合中,讓我發現了對這個問題的另一種解釋,而且這種解釋推翻了之前網友們提供的解釋。問題分析以下是官方的STM32的參考手冊對串口發送資料的流程說明:
  1. 通過在USART_CR1寄存器上置位UE位來啟用USART
  2.  編程USART_CR1的M位來定義字長。
  3. 在USART_CR2中編程停止位的位元。
  4. 如果採用多緩衝器通訊,配置USART_CR3中的DMA使能位(DMAT)。按多緩衝器通訊中的描述配置DMA寄存器。
  5. 設定USART_CR1中的TE位,發送一個空閑幀作為第一次資料發送。
  6. 利用USART_BRR寄存器選擇要求的傳輸速率。
  7. 把要發送的資料寫進USART_DR寄存器(此動作清除TXE位)。在只有一個緩衝器的情況下,對每個待發送的資料重複步驟7。
對於導致串口遺失資料的步驟我同意網友的觀點,那就是步驟5中,在置位TE的時候,發送了一個空閑幀作為第一次資料發送。但對於為何發送空閑幀會導致使用者資料丟失第一幀的原因,我和網友的看法不一致。網友的觀點可以概括為兩個字,覆蓋。這是網友的普遍看法,http://blog.csdn.net/kevinhg/article/details/40991655,看到一些網友引用了這篇部落格,而且很多網友的觀點基本跟這篇部落格中的一致。從這篇部落格中可以看出,網友覺得是在發送第一個資料的時候,沒有讀USART_SR,所以TC仍然處於置位,在寫入第二個資料的時候,就覆蓋掉了第一個資料。於是我就按照這篇部落格中的解釋,寫了個發送程式,關鍵代碼如下:
/* 發送資料 */if(USART_GetFlagStatus(USART3,USART_FLAG_TC)!=RESET){if(TxCount3<buf3_len){USART_SendData(USART3,rx3_buf[TxCount3]);TxCount1=USART_GetFlagStatus(USART3,USART_FLAG_TC);TxCount3++;}else{USART_ITConfig(USART3,USART_IT_TXE,DISABLE);//發送完成,關閉TXE,避免TDR空中斷}}
if語句中我讀取USART_SR的狀態,然後發送第一個資料,根據官方參考手冊的說明,此時TC被清零,那麼就不存在第二個資料覆蓋第一個資料的情況發生,但實際上,第一幀資料仍然丟失了。網友可能會說,按照這種方式,向USART_DR中寫入第一個資料並沒有讓TC清零,那麼以下是我修改了的程式,主要監視向USART_DR中寫入第一個資料後,TC是否被清理:
if(USART_GetFlagStatus(USART3,USART_FLAG_TC)!=RESET){if(TxCount3<buf3_len){USART_SendData(USART3,rx3_buf[TxCount3]);TxCount1=USART_GetFlagStatus(USART3,USART_FLAG_TC);TxCount3++;}else<span style="color:#ff6666;"></span>{USART_ITConfig(USART3,USART_IT_TXE,DISABLE);//發送完成,關閉TXE,避免TDR空中斷}}

調試如下:
從監看式視窗中可以看到,TxCount3=0,表示我發送的是第一個資料,而向USART_DR中寫入了第一個資料後,TxCount1=0,說明TC被清零,跟官方參考手冊說法一致,那麼就不應該出現第二個資料覆蓋第一個資料的啊。因為缺少對硬體的具體實現的瞭解,我的觀點只是一種猜測。在置位TE後,TC與TXE都是被置位的(這解釋了為何置位TE後,並使能TXE,TC會不斷進入中斷程式),並且發送一幀空閑幀作為第一個資料,根據官方參考手冊,TC置位表示發送移位寄存器已空,可以向USART_DR中寫入資料,照理說此時可以寫入使用者的第一個資料,但真實情況是發送移位寄存器還裝有空閑幀的資料,即空閑幀並未發送完成(這解釋了為何置位TE後,延時一段時間再發送資料就不會丟失第一個資料,因為這段延時期間空閑幀發送完成了),在空閑幀還沒發送完成的時候,推測官方提供了對移位寄存器的硬體保護,即即使TC置位,此時USART_DR中的資料也不會裝入發送移位寄存器,而是被忽略掉了。推測發送移位寄存器的硬體保護條件:移位寄存器為發送完成,TC已經被置位,雖然想寫個程式驗證下,但TC只能由硬體置位。第一個資料被寫進了TDR中:
/* 發送資料 */if(USART_GetFlagStatus(USART3,USART_FLAG_TXE)!=RESET){if(TxCount3<buf3_len){USART_SendData(USART3,rx3_buf[TxCount3]);TxCount1=USART_GetFlagStatus(USART3,USART_FLAG_TXE);TxCount3++;}else{USART_ITConfig(USART3,USART_IT_TXE,DISABLE);//發送完成,關閉TXE,避免TDR空中斷}}

進入了if 的內部,說明之前TXE被置位,而寫入第一個資料後,TxCount1=0,即TXE被清零,說明第一個資料寫入了TDR中。因此在之前推測基礎上進一步補充串口的細節。當發送移位寄存器發送完成後,會先讀取TC的狀態,若TC已被置位,則串口忽略TDR中的資料(這也符合官方參考文檔的描述,當TC置位時,表示發送移位寄存器為空白,向USART_DR中寫入資料會直接放進發送移位寄存器,而存放了第一個資料的TDR被忽略掉了,這也解釋了第一個資料丟失的問題),若TC未被置位,檢測TXE是否置位,若TXE置位,則置位TC,若TXE複位,則從TDR中載入資料到發送移位寄存器,載入結束後,置位TXE。所以,其實這並不是什麼STM32的串口發送bug,而是STM32提供了對發送移位寄存器的非空保護(該非空並不是說非零,記錄移位的計數器非零),而其執行過程都是按照了官方參考文檔的描述。非要說是bug的話,就是STM32置位TE後,在發送空閑幀的過程中,不應將TC置位。總結當發送移位寄存器發送完成後,會先讀取TC的狀態,若TC已被置位,則串口忽略TDR中的資料(這也符合官方參考文檔的描述,當TC置位時,表示發送移位寄存器為空白,向USART_DR中寫入資料會直接放進發送移位寄存器,而存放了第一個資料的TDR被忽略掉了,這也解釋了第一個資料丟失的問題),若TC未被置位,檢測TXE是否置位,若TXE置位,則置位TC,若TXE複位,則從TDR中載入資料到發送移位寄存器,載入結束後,置位TXE。

關於STM32 USART(串口)發送資料丟失第一幀的真實原因探索

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.