在嵌入式領(lǐng)域,UART(通用異步接收器 / 發(fā)送器)通信協(xié)議是一種被廣泛應(yīng)用的串行、異步、全雙工通信協(xié)議。接下來(lái),我們將詳細(xì)介紹 UART 通信協(xié)議及其工作原理。
UART 通道由兩條數(shù)據(jù)線(xiàn)構(gòu)成,每個(gè)設(shè)備都配備一個(gè) RX 引腳(用于接收)和一個(gè) TX 引腳(用于發(fā)送)。連接時(shí),一個(gè)設(shè)備的 RX 引腳需連接到另一個(gè)設(shè)備的 TX 引腳。值得注意的是,UART 沒(méi)有共享時(shí)鐘線(xiàn),這正是其 “異步” 特性的體現(xiàn)。
UART 作為異步串行通信協(xié)議,其工作原理是逐位傳輸數(shù)據(jù)的每個(gè)二進(jìn)制位。在 UART 通信中,信號(hào)線(xiàn)上高電平代表 “1”,低電平代表 “0”。例如,當(dāng)傳輸一字節(jié)數(shù)據(jù)時(shí),信號(hào)線(xiàn)上會(huì)呈現(xiàn)八種高低電平組合。
串行通信利用一根傳輸線(xiàn)逐位依次傳輸數(shù)據(jù),也可用兩根信號(hào)線(xiàn)實(shí)現(xiàn)全雙工通信,如 rs232。其優(yōu)點(diǎn)是通信線(xiàn)路簡(jiǎn)單,使用普通電纜即可,成本較低,適合遠(yuǎn)距離通信,但傳輸速度相對(duì)較慢。
異步通信以字符為傳輸單位,字符間時(shí)間間隔不固定,但同一字符內(nèi)相鄰位的時(shí)間間隔固定。通常,兩個(gè) UART 設(shè)備通信無(wú)需時(shí)鐘線(xiàn),不過(guò)需要指定相同的傳輸速率、空閑位、起始位、奇偶校驗(yàn)位和結(jié)束位,即遵循相同的協(xié)議。
數(shù)據(jù)傳輸速率用波特率表示,即每秒傳輸?shù)奈粩?shù)。例如,若數(shù)據(jù)傳輸速率為 120 個(gè)字符 / 秒,每個(gè)字符包含 1 個(gè)起始位、7 個(gè)數(shù)據(jù)位、1 個(gè)校驗(yàn)位和 1 個(gè)停止位,共 10 位,則波特率為 10×120 = 1200 波特。
- 起始位:每次通信開(kāi)始時(shí),發(fā)送方發(fā)送一個(gè)邏輯 “0” 信號(hào)(VOL),以表明傳輸字符的開(kāi)始。由于總線(xiàn)空閑時(shí)為高電平,所以起始信號(hào)與空閑狀態(tài)差異明顯。
- 數(shù)據(jù)位:起始位之后是要傳輸?shù)臄?shù)據(jù),數(shù)據(jù)位可以是 5、6、7、8、9 位等組成一個(gè)字符,通常為 8 位,如 ASCII 碼(7 位)、擴(kuò)展 BCD 碼(8 位)。數(shù)據(jù)傳輸時(shí)先發(fā)送位,發(fā)送位,低電平表示 “0”,高電平表示 “1”。
- 奇偶校驗(yàn)位:該位添加在數(shù)據(jù)位之后,用于驗(yàn)證數(shù)據(jù)傳輸?shù)恼_性。串口校驗(yàn)方式有多種:
- 無(wú)奇偶校驗(yàn);
- 奇校驗(yàn):若數(shù)據(jù)位中 “1” 的個(gè)數(shù)為偶數(shù),奇偶校驗(yàn)位為 “1”;若為奇數(shù),奇偶校驗(yàn)位為 “0”;
- 偶校驗(yàn):若數(shù)據(jù)中 “1” 的個(gè)數(shù)為偶數(shù),奇偶校驗(yàn)位為 “0”;若為奇數(shù),奇偶校驗(yàn)位為 “1”;
- 標(biāo)記奇偶校驗(yàn):校驗(yàn)位始終為 1(不常用);
- 奇偶校驗(yàn):奇偶校驗(yàn)位始終為 0(不常用)。
- 停止位:作為字符數(shù)據(jù)的結(jié)束標(biāo)記,它可以是 1 位、1.5 位或 2 位 VOH。由于數(shù)據(jù)傳輸時(shí)各設(shè)備時(shí)鐘可能存在小的不同步,停止位不僅表示傳輸結(jié)束,還為計(jì)算機(jī)提供了糾正時(shí)鐘的機(jī)會(huì)。停止位越多,數(shù)據(jù)傳輸越穩(wěn)定,但速度越慢。
在協(xié)議層,規(guī)定了數(shù)據(jù)包由起始位、主要數(shù)據(jù)、校驗(yàn)位和停止位組成。雙方必須約定一致的數(shù)據(jù)包格式,才能正常收發(fā)數(shù)據(jù)。例如 mavlink 協(xié)議。
此外,異步通信沒(méi)有時(shí)鐘信號(hào),兩個(gè)通信設(shè)備需要就波特率達(dá)成一致,常見(jiàn)的波特率有 4800、9600、115200 等。串行通訊的數(shù)據(jù)包從起始信號(hào)開(kāi)始,以停止信號(hào)結(jié)束,起始信號(hào)用邏輯 0 的數(shù)據(jù)位表示,停止信號(hào)可以用 0.5、1、1.5 或 2 個(gè)邏輯 1 的數(shù)據(jù)位表示,只要雙方協(xié)商一致即可。為解決數(shù)據(jù)通信受外界干擾導(dǎo)致傳輸錯(cuò)誤的問(wèn)題,有效數(shù)據(jù)后可添加可選的數(shù)據(jù)校驗(yàn)位,校驗(yàn)方式包括奇校驗(yàn)、偶校驗(yàn)、0 校驗(yàn)(空格)、1 校驗(yàn)(標(biāo)記)、無(wú)奇偶校驗(yàn)。
- 幀錯(cuò)誤:當(dāng)接收器在預(yù)期位時(shí)間未看到停止位時(shí),就會(huì)發(fā)生幀錯(cuò)誤。若在預(yù)期停止位時(shí)數(shù)據(jù)線(xiàn)未處于預(yù)期的高狀態(tài)(取決于 UART 的數(shù)據(jù)和奇偶校驗(yàn)位設(shè)置),UART 將發(fā)出幀錯(cuò)誤信號(hào)。
- 奇偶校驗(yàn)錯(cuò)誤:僅在 UART 處于奇偶校驗(yàn)?zāi)J綍r(shí)會(huì)引發(fā)。在該模式下,會(huì)發(fā)送一個(gè)額外位保存所有傳輸數(shù)據(jù)位的奇偶校驗(yàn)信息。若數(shù)據(jù)位出錯(cuò),奇偶校驗(yàn)位也會(huì)錯(cuò)誤,并拋出指定錯(cuò)誤。
- 溢出錯(cuò)誤:當(dāng)接收器在下一個(gè)字符到達(dá)之前未處理(從輸入緩沖區(qū)刪除一個(gè)字符)時(shí),會(huì)發(fā)生溢出錯(cuò)誤。
- 中斷條件:中斷條件不一定是錯(cuò)誤。當(dāng)接收器輸入處于邏輯低狀態(tài)超過(guò)一定持續(xù)時(shí)間(通常超過(guò)一個(gè)字符時(shí)間)時(shí)會(huì)出現(xiàn)。對(duì)于接收者而言,這看起來(lái)像一個(gè)帶有幀錯(cuò)誤的全零字符,可用于軟件復(fù)位電路。在 python 代碼中,可通過(guò)發(fā)送 break 觸發(fā) reset,將數(shù)據(jù)線(xiàn)拉低足夠長(zhǎng)時(shí)間使 MCLR 拉低,實(shí)現(xiàn)電路板復(fù)位。
并不存在 “的” 通信外設(shè),用戶(hù)應(yīng)根據(jù)項(xiàng)目需求選擇合適的通信外設(shè)。例如,若追求快的通信速度,SPI 是理想選擇;若想連接多個(gè)設(shè)備且不想過(guò)于復(fù)雜,I2C 則更為合適,因?yàn)樗嗫蛇B接 127 個(gè)設(shè)備且易于管理。