秉火429笔记之十四 USART--串口通信
目錄
1. 串口通訊協(xié)議簡介
1.1 物理層
1.2 協(xié)議層
2? ST USART
2.1 功能引腳
2.2 重要狀態(tài)
2.3 編程要點(diǎn)
2.4 代碼實(shí)例
1. 串口通訊協(xié)議簡介
串口通訊(Serial Communication)是一種設(shè)備間常用的串行通訊方式,因?yàn)楹唵伪憬?#xff0c;大部分電子設(shè)備都支持該通訊方式,電子工程師在調(diào)試設(shè)備時(shí)也經(jīng)常使用該通訊方式輸出調(diào)試信息。
對于通訊協(xié)議,我們也以分層的方式來理解,最基本的是把它分為物理層和協(xié)議層。物理層規(guī)定通訊系統(tǒng)中具有機(jī)械、電子功能部分的特性,確保原始數(shù)據(jù)在物理媒體的傳輸。協(xié)議層主要規(guī)定通訊邏輯,統(tǒng)一收發(fā)雙方的數(shù)據(jù)打包、解包標(biāo)準(zhǔn)。
1.1 物理層
串口通訊的物理層有很多標(biāo)準(zhǔn)及變種,我們主要講解RS-232標(biāo)準(zhǔn) ,RS-232標(biāo)準(zhǔn)主要規(guī)定了信號的用途、通訊接口以及信號的電平標(biāo)準(zhǔn)。
兩個(gè)通訊設(shè)備的“DB9接口”之間通過串口信號線建立起連接,串口信號線中使用“RS-232標(biāo)準(zhǔn)”傳輸數(shù)據(jù)信號。由于RS-232電平標(biāo)準(zhǔn)的信號不能直接被控制器直接識別,所以這些信號會經(jīng)過一個(gè)“電平轉(zhuǎn)換芯片”轉(zhuǎn)換成控制器能識別的“TTL校準(zhǔn)”的電平信號,才能實(shí)現(xiàn)通訊。
- 電平標(biāo)準(zhǔn)
根據(jù)通訊使用的電平標(biāo)準(zhǔn)不同,串口通訊可分為TTL標(biāo)準(zhǔn)及RS-232標(biāo)準(zhǔn)
常見的電子電路中常使用TTL的電平標(biāo)準(zhǔn),理想狀態(tài)下,使用5V表示二進(jìn)制邏輯1,使用0V表示邏輯0;而為了增加串口通訊的遠(yuǎn)距離傳輸及抗干擾能力,它使用-15V表示邏輯1,+15V表示邏輯0。因?yàn)榭刂破饕话闶褂肨TL電平標(biāo)準(zhǔn),所以常常會使用MA3232芯片對TTL及RS-232電平的信號進(jìn)行互相轉(zhuǎn)換。
- RS-232信號線
在最初的應(yīng)用中,RS-232串口標(biāo)準(zhǔn)常用于計(jì)算機(jī)、路由與調(diào)制調(diào)解器(MODEN,俗稱“貓”)之間的通訊 ,在這種通訊系統(tǒng)中,設(shè)備被分為數(shù)據(jù)終端設(shè)備DTE(計(jì)算機(jī)、路由)和數(shù)據(jù)通訊設(shè)備DCE(調(diào)制調(diào)解器)。我們以這種通訊模型講解它們的信號線連接方式及各個(gè)信號線的作用。
在舊式的臺式計(jì)算機(jī)中一般會有RS-232標(biāo)準(zhǔn)的COM口(也稱DB9接口)
接線口以針式引出信號線的稱為公頭,以孔式引出信號線的稱為母頭。在計(jì)算機(jī)中一般引出公頭接口,而在調(diào)制調(diào)解器設(shè)備中引出的一般為母頭,使用上圖中的串口線即可把它與計(jì)算機(jī)連接起來。通訊時(shí),串口線中傳輸?shù)男盘柧褪鞘褂们懊嬷v解的RS-232標(biāo)準(zhǔn)調(diào)制的。
| 1 | 載波偵測 | DCD | DTE->DCE | Data Carrier Detect,數(shù)據(jù)載波檢測,用于DTE告知對方,本機(jī)是否收到對方的載波信號 |
| 2 | 接收數(shù)據(jù) | RXD | DET<-DCE | Receive Data,數(shù)據(jù)接收信號,即輸入 。 |
| 3 | 發(fā)送數(shù)據(jù) | TXD | DTE->DCE | Transmit Data,數(shù)據(jù)發(fā)送信號,即輸出。兩個(gè)設(shè)備之間的TXD與RXD應(yīng)交叉相連 |
| 4 | 數(shù)據(jù)終端 (DTE) 就緒 | DTR | DTE->DCE | Data Terminal Ready,數(shù)據(jù)終端就緒,用于DTE向?qū)Ψ礁嬷緳C(jī)是否已準(zhǔn)備好 |
| 5 | 信號地 | GND | -- | 地線,兩個(gè)通訊設(shè)備之間的地電位可能不一樣,這會影響收發(fā)雙方的電平信號,所以兩個(gè)串口設(shè)備之間必須要使用地線連接,即共地。 |
| 6 | 數(shù)據(jù)設(shè)備(DCE)就緒 | DSR | DET<-DCE | Data Set Ready,數(shù)據(jù)發(fā)送就緒,用于DCE告知對方本機(jī)是否處于待命狀態(tài) |
| 7 | 請求發(fā)送 | RTS | DTE->DCE | Request To Send,請求發(fā)送, DTE 請求 DCE 本設(shè)備向DCE端發(fā)送數(shù)據(jù) |
| 8 | 允許發(fā)送 | CTS | DET<-DCE | Clear To Send,允許發(fā)送,DCE回應(yīng)對方的RTS發(fā)送請求,告知對方是否可以發(fā)送數(shù)據(jù) |
| 9 | 響鈴指示 | RI | DET<-DCE | Ring Indicator,響鈴指示,表示DCE端與線路已接通 |
串口線中的RTS、CTS、DSR、DTR及DCD信號,使用邏輯 1表示信號有效,邏輯0表示信號無效。例如,當(dāng)計(jì)算機(jī)端控制DTR信號線表示為邏輯1時(shí),它是為了告知遠(yuǎn)端的調(diào)制調(diào)解器,本機(jī)已準(zhǔn)備好接收數(shù)據(jù),0則表示還沒準(zhǔn)備就緒。
在目前的其它工業(yè)控制使用的串口通訊中,一般只使用RXD、TXD以及GND三條信號線,直接傳輸數(shù)據(jù)信號。
1.2 協(xié)議層
串口通訊的數(shù)據(jù)包由發(fā)送設(shè)備通過自身的TXD接口傳輸?shù)浇邮赵O(shè)備的RXD接口。在串口通訊的協(xié)議層中,規(guī)定了數(shù)據(jù)包的內(nèi)容,它由啟始位、主體數(shù)據(jù)、校驗(yàn)位以及停止位組成,通訊雙方的數(shù)據(jù)包格式要約定一致才能正常收發(fā)數(shù)據(jù)。
- 波特率
兩個(gè)通訊設(shè)備之間需要約定好波特率,即每個(gè)碼元的長度,以便對信號進(jìn)行解碼,圖 中用虛線分開的每一格就是代表一個(gè)碼元。常見的波特率為4800、9600、115200等。
- 通訊的起始和停止信號
串口通訊的一個(gè)數(shù)據(jù)包從起始信號開始,直到停止信號結(jié)束。數(shù)據(jù)包的起始信號由一個(gè)邏輯0的數(shù)據(jù)位表示,而數(shù)據(jù)包的停止信號可由0.5、1、1.5或2個(gè)邏輯1的數(shù)據(jù)位表示,只要雙方約定一致即可
- 有效數(shù)據(jù)
在數(shù)據(jù)包的起始位之后緊接著的就是要傳輸?shù)闹黧w數(shù)據(jù)內(nèi)容,也稱為有效數(shù)據(jù),有效數(shù)據(jù)的長度常被約定為5、6、7或8位長。
- 數(shù)據(jù)校驗(yàn)
在有效數(shù)據(jù)之后,有一個(gè)可選的數(shù)據(jù)校驗(yàn)位。由于數(shù)據(jù)通信相對更容易受到外部干擾導(dǎo)致傳輸數(shù)據(jù)出現(xiàn)偏差,可以在傳輸過程加上校驗(yàn)位來解決這個(gè)問題。校驗(yàn)方法有奇校驗(yàn)(odd)、偶校驗(yàn)(even)、0校驗(yàn)(space)、1校驗(yàn)(mark)以及無校驗(yàn)(noparity)
2? ST USART
2.1 功能引腳
- TX:發(fā)送數(shù)據(jù)輸出引腳。
- RX:接收數(shù)據(jù)輸入引腳。
- SW_RX:數(shù)據(jù)接收引腳,只用于單線和智能卡模式,屬于內(nèi)部引腳,沒有具體外部引腳。
- nRTS:請求以發(fā)送(Request To Send),n表示低電平有效。如果使能RTS流控制,當(dāng)USART接收器準(zhǔn)備好接收新數(shù)據(jù)時(shí)就會將nRTS變成低電平;當(dāng)接收寄存器已滿時(shí),nRTS將被設(shè)置為高電平。該引腳只適用于硬件流控制。
- nCTS:清除以發(fā)送(Clear To Send),n表示低電平有效。如果使能CTS流控制,發(fā)送器在發(fā)送下一幀數(shù)據(jù)之前會檢測nCTS引腳,如果為低電平,表示可以發(fā)送數(shù)據(jù),如果為高電平則在發(fā)送完當(dāng)前數(shù)據(jù)幀之后停止發(fā)送。該引腳只適用于硬件流控制。
- SCLK:發(fā)送器時(shí)鐘輸出引腳。這個(gè)引腳僅適用于同步模式。
STM32F42xxx系統(tǒng)控制器有四個(gè)USART和四個(gè)UART,其中USART1和USART6的時(shí)鐘來源于APB2總線時(shí)鐘,其最大頻率為90MHz,其他六個(gè)的時(shí)鐘來源于APB1總線時(shí)鐘,其最大頻率為45MHz。
UART只是異步傳輸功能,所以沒有SCLK、nCTS和nRTS功能引腳。
2.2 重要狀態(tài)
| 2 | TE | 發(fā)送使能,能力 |
| 3 | TXE | 發(fā)送寄存器為空, |
| 4 | TC | 發(fā)送完成 |
| 5 | TXIE | 發(fā)送完成中斷使能 |
| 6 | RE | 接收使能,能力 |
| 7 | RXNE | 讀數(shù)據(jù)寄存器非空 |
| 8 | RXNEIE | 發(fā)送完成中斷使能 |
?
- ? ? ? ? ? ?空閑字符 可理解為整個(gè)幀周期內(nèi)電平均為“1”(停止位的電平也是“1”),該字符后是下一個(gè)數(shù)據(jù)幀的起始位。
- 停止字符 可理解為在一個(gè)幀周期內(nèi)接收到的電平均為“0”。發(fā)送器在中斷幀的末尾插入 1 或 2 個(gè)停止位(邏輯“1”位)以確認(rèn)起始位。
2.3 編程要點(diǎn)
常規(guī)中斷方式:
- 使能RX和TX引腳GPIO時(shí)鐘和USART時(shí)鐘
- 初始化GPIO,并將GPIO復(fù)用到USART上
- 配置USART參數(shù);
- 配置中斷控制器并使能USART收發(fā)中斷;
- 使能USART;
- 在USART接收中斷服務(wù)函數(shù)實(shí)現(xiàn)數(shù)據(jù)接收和發(fā)送
DMA中斷方式:
- 使能RX和TX引腳GPIO時(shí)鐘和USART時(shí)鐘
- 初始化GPIO,并將GPIO復(fù)用到USART上
- 配置USART參數(shù);
- 配置中斷控制器并使能USART DMA 收發(fā)中斷
- 配置DMA參數(shù)及關(guān)聯(lián)數(shù)據(jù)BUF并配置傳輸完成中斷
- 使能USART
- 通過IDLE空閑中斷來標(biāo)識單幀傳輸完成,計(jì)數(shù)數(shù)據(jù)大小,并配合DMA緩存滿中斷完成數(shù)據(jù)接收判斷
- 通過重置DMA計(jì)數(shù)和使能DMA發(fā)送
- 注意考慮接收超過緩存大小時(shí),關(guān)閉DMA傳輸,進(jìn)入等待IDLE,然后,處理數(shù)據(jù),超出直接丟掉
2.4 代碼實(shí)例
重定向prinft和scanf函數(shù)
在C語言標(biāo)準(zhǔn)庫中,fputc函數(shù)是printf函數(shù)內(nèi)部的一個(gè)函數(shù),功能是將字符ch寫入到文件指針f所指向文件的當(dāng)前寫指針位置,簡單理解就是把字符寫入到特定文件中。我們使用USART函數(shù)重新修改fputc函數(shù)內(nèi)容,達(dá)到類似“寫入”的功能。介于某些情況下,硬件并不一定有UART,亦可以類似方法重定義到RAM來方便調(diào)試,后續(xù)專門介紹。
fgetc函數(shù)與fputc函數(shù)非常相似,實(shí)現(xiàn)字符讀取功能。在使用scanf函數(shù)時(shí)需要注意字符輸入格式。
還有一點(diǎn)需要注意的,使用fput和fgetc函數(shù)達(dá)到重定向C語言標(biāo)準(zhǔn)庫輸入輸出函數(shù)必須在MDK的工程選項(xiàng)把“Use MicroLIB”勾選上,MicoroLIB是缺省C庫的備選庫,它對標(biāo)準(zhǔn)C庫進(jìn)行了高度優(yōu)化使代碼更少,占用更少資源。當(dāng)然,維庫在某些特殊條件下并不需要,比如RL_FLASH,通過其他方式來實(shí)現(xiàn)重定向。
為使用printf、scanf函數(shù)需要在文件中包含stdio.h頭文件。
///重定向c庫函數(shù)printf到串口,重定向后可使用printf函數(shù) int fputc(int ch, FILE *f) {/* 發(fā)送一個(gè)字節(jié)數(shù)據(jù)到串口 */USART_SendData(DEBUG_USART, (uint8_t) ch);/* 等待發(fā)送完畢 */while (USART_GetFlagStatus(DEBUG_USART, USART_FLAG_TXE) == RESET); return (ch); }///重定向c庫函數(shù)scanf到串口,重寫向后可使用scanf、getchar等函數(shù) int fgetc(FILE *f) {/* 等待串口輸入數(shù)據(jù) */while (USART_GetFlagStatus(DEBUG_USART, USART_FLAG_RXNE) == RESET);return (int)USART_ReceiveData(DEBUG_USART); }?
總結(jié)
以上是生活随笔為你收集整理的秉火429笔记之十四 USART--串口通信的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 在react里实现点击回车键执行事件
- 下一篇: 幼儿园小朋友可以教创业者的事