UART:Universal Asynchronous Receiver / Transmitter,通用異步收發(fā)傳輸器,即我們通常說的串口。
串口是工程師最常用的一種串行外設,但在實際應用中還是會經(jīng)常遇到各種問題。比如:丟失一字節(jié)數(shù)據(jù)。
今天我們就結合STM32來講講UART相關內容,以及容易丟失一字節(jié)數(shù)據(jù)的問題。
這里重點說一下UART狀態(tài)寄存器中的幾個標志位:TXE、 TC、 RXNE、 ORE。
223609y7u927rz5rha9poh.png (47.52 KB, 下載次數(shù): 14)
下載附件
保存到相冊
2021-5-5 22:36 上傳
這幾個標志位在編程中經(jīng)常使用,數(shù)據(jù)丟失有可能就是對它們操作不當而導致出錯。
TXE:發(fā)送數(shù)據(jù)寄存器為空 (Transmit data register empty)
TC:發(fā)送完成 (Transmission complete)
RXNE:讀取數(shù)據(jù)寄存器不為空 (Read data register not empty)
0:未接收到數(shù)據(jù)
1:已準備好讀取接收到的數(shù)據(jù)
ORE:上溢錯誤 (Overrun error)
UART常見通信接口有:TTL、 RS232、 RS485。在編程時需要考慮通信接口方式,在長距離通信的時候,需要考慮線路上的延時,如果操作不當也會導致數(shù)據(jù)丟失。TTL比較簡單,就是直接連接UART的Tx和Rx引腳,不需要外部轉換。如圖:
223609j1y4ymsslsoq17do.png (24.01 KB, 下載次數(shù): 15)
下載附件
保存到相冊
2021-5-5 22:36 上傳
RS-232標準接口是常用的串行通信接口標準之一,規(guī)定邏輯“1”的電平為-5V~-15 V,邏輯“0”的電平為+5 V~+15 V。選用該電氣標準的目的在于提高抗干擾能力,增大通信距離。
223610ms44kjhvx4xqvvgk.png (63.34 KB, 下載次數(shù): 12)
下載附件
保存到相冊
2021-5-5 22:36 上傳
RS485一般采用兩線制接線方式,這種接線方式為總線式拓撲結構,在同一總線上可以掛接多個節(jié)點。在低速、短距離、無干擾的場合可以采用普通的雙絞線;反之,在高速、長線傳輸時,則必須采用阻抗匹配(一般為120Ω)的RS485專用電纜;而在干擾惡劣的環(huán)境下還應采用鎧裝型雙絞屏蔽電纜。
223610rv4v171kvk8v84nl.png (57.25 KB, 下載次數(shù): 16)
下載附件
保存到相冊
2021-5-5 22:36 上傳
UART接收丟失數(shù)據(jù)與軟件和硬件都有可能有關系,下面說幾個常見丟失數(shù)據(jù)的原因及解決辦法。指未及時取走數(shù)據(jù)導致溢出錯誤而丟失數(shù)據(jù),通常是發(fā)生在大量數(shù)據(jù)、以查詢方式接收數(shù)據(jù)的情況下。在MCU啟動過程中、接收數(shù)據(jù)過多處理不及時、復雜系統(tǒng)響應不及時等情況都會出現(xiàn)數(shù)據(jù)丟失的情況。使用UART中斷接收數(shù)據(jù)相比查詢接收數(shù)據(jù)的方式更常見,中斷方式比查詢方式響應更及時,但不合理處理同樣也會存在數(shù)據(jù)丟失的情況。在數(shù)據(jù)量大時,UART接收中斷函數(shù)耗時、優(yōu)先級低等情況下容易丟失數(shù)據(jù)。中斷函數(shù)里減少不必要的耗時
合理分配中斷優(yōu)先級
使能中斷前清除標志位
在通信波特率較高的情況下,如果時鐘誤差加大,很可能導致數(shù)據(jù)丟失。
UART發(fā)送丟失數(shù)據(jù)很多工程師都遇到過,通常情況下是傳輸未完成的原因。HAL庫已經(jīng)有幾年了,但還是有很多工程師都使用標準外設庫,這時如果自己封裝接口不當,就會存在發(fā)送最后一字節(jié)數(shù)據(jù)丟失的問題。
1.UART傳輸未完成導致數(shù)據(jù)丟失void UART_SendByte(uint8_t Data)
{
while(RESET == USART_GetFlagStatus(USART1, USART_FLAG_TXE));
USART_SendData(USART1, Data);
}
但發(fā)送非空不代表發(fā)送完成,雖然在某些場合更高效,但某些場合就會導致數(shù)據(jù)丟失。比如:使用此函數(shù)發(fā)送之后進入休眠、關閉接收端設備電源等情況下。void UART_SendByte(uint8_t Data)
{
while(RESET == USART_GetFlagStatus(USART1, USART_FLAG_TXE));
USART_SendData(USART1, Data);
while(RESET == USART_GetFlagStatus(USART1, USART_FLAG_TC));
}
如果使用標準外設庫,要根據(jù)實際情況封裝函數(shù),比如發(fā)送超時。
HAL_StatusTypeDef HAL_UART_Transmit(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout)
UART通常會使用232或者485以增加傳輸距離和增強干擾。但是一旦數(shù)據(jù)線路太長就存在傳輸延時的情況,特別是485傳輸長距離,并使用MCU控制傳輸方向的情況下。軟件增加延時處理
使用通信協(xié)議增加應答機制
UART應用的場景比較多,有些應用在復雜的工廠,干擾較大從而導致數(shù)據(jù)丟失;有些應用在溫差較大的環(huán)境,時鐘偏移較大導致數(shù)據(jù)丟失。解決辦法需要根據(jù)實際情況,有針對性解決問題。比如:使用更好的通信線,軟件做好容錯處理等。
轉載聲明:本文轉載自「8號線攻城獅」,搜索「BHXGCS」即可關注,[
閱讀原文]。