UART工作原理详解
目錄
概述
發展過程
硬件定義(DP9-RS232)
工作原理(DP9-RS232)
起始位、停止位、校驗位(DP9-RS232)
速率計算
波特率
FIFO
FIFO存儲器
FIFO的概念
超時設計
FIFO緩沖區的清空
FIFO 輸入與輸出中斷
FIFO緩沖區取數據時的原理
UART FIFO
USART
概述
UART全拼Universal Asynchronous Receiver/Transmitter,即通用異步收發傳輸器
發展過程
在個人計算機誕生之前就已經存在了串口設備,如電傳打字機,工控測量設備,通信調制解調器(現在的路由器),最初的串口就是用一根線直連另外一方,一方發一方收,后來廠商為了完善自己的串口又增加了一根線用于做信號位,主要用于判斷流是否可用,同時當時的廠商們的設備不同,芯片的工作頻率也不同以及電平信號也不同,導致廠商的設備只能跟自己通訊,沒有一個統一的標準非常混亂,后來由無線電制造商協會(Radio Manufacturers' Association:RMA,現:美國電子工業協會(EIA))聯合貝爾實驗室在1970年代一起制定了一個標準,即歷史上第一個通用串口協議標準:RS-232,它規定了波特率(即芯片工作頻率),數據線,接受線,流控制線的接法,采用DB25針串口,支持異步。
支持的波特率有:50b/s、75b/s、110b/s、150b/s、300b/s、600b/s、1200b/s、2400b/s、4800b/s、9600b/s、19200b/s
115200這個速率最初是沒有的,是后來才加上去的,因為人們發現9600太慢,19200頻率又太高,頻率越高功耗越高,所以推出一個115200這個合適的頻率。
最后隨著個人電腦的出現,個人電腦最初的上的接口較小,PCB板子空間也很小,DB25較大,EIA將其中保留的一些針位去除了,形成了后來的DB9針串口,協議依然是RS-232。
由于DB9接口只定義了信號量,但是沒有定義與每個引腳的直接關系,導致當時的廠商需要自己去定義每個引腳的作用,這就導致了不同廠商每個引腳的作用不一樣,但是功能是一樣的,無法相互接在一起,最初有一個比較知名的公司:IBM,它規定了一種定義,后來大多數廠商為了統一都采用IBM的定義。
所以最終IBM成為了PC行業里DB9串口引腳關系的工業標準。
在這一刻UART才叫UART,這里的U即是通用的意思,最初叫ART之類的,因為它沒有一個統一的標準,后來IBM統一了之后,才有了U,不同廠商之間的設備可以通過串口進行通訊了。
硬件定義(DP9-RS232)
工作原理(DP9-RS232)
DTR由計算機控制,當為高電平時即告訴目標設備,我已經準備好了,可以給我發送數據了
DSR由目標設備控制,當為高電平時即目標設備告訴計算機,我也可以發送數據了
RTS由計算機控制,告訴目標設備給我發送數據,此時目標設備需要立即給計算機發送數據
CTS由目標設備控制,告訴計算機給目標設備發送數據
DCD是由計算機控制,計算機需要拉高它來告訴目標設備我還在線
在RS232里要求每個字節只能一次傳輸一個BIT位,所以就需要一個起始位與停止位,為了確保正確性還會有個校驗位,這些會在后面說,當將對應的線調整好了之后,需要TXD來確認位的開始與停止
起始位、停止位、校驗位(DP9-RS232)
起始位(Start Bit)
發送器是通過發送起始位而開始一個字符傳送,起始位使數據線處于邏輯0狀態,提示接受器數據傳輸即將開始,當設定好起始位后,如起始信號為01,那么串口內部時鐘開始周期性的采樣,如串口內部使用8個時鐘周期作為一個采樣周期的因子,則每4個周期進行一次采樣,如當第4個時鐘周期的時候采樣為0那么會記到標志寄存器中,當第8個周期采樣為1則視為起始信號,這樣一個周期就完成了,現在的起始信號一般都不能設置,都采用默認的,即默認的兩個低電平,以16個時鐘周期為采樣因子,每8個時鐘周期采一次,若兩次之后都為低電平則視為起始信號
起始位為兩個低電平00,因為RS232規定要求空閑時電平必須是1,即高電平
數據位(Data Bits)
起始位之后就是傳送數據位。數據位一般為8位一個字節的數據(也有6位、7位的情況),低位(LSB)在前,高位(MSB)在后,無法修改高低位的傳輸優先級
停止位(Stop Bit)
最后一個BIT位,一般為1位,可以設置,一般設置為1或2,最常用的是1,它與數據位相接,當雙方通訊協議一致后(停止位數據位都是一樣的),當讀取完數據位之后在讀取一位是高電平的1時則認為收到了停止位,則代表一個數據的結束
校驗位(parity Bit)
這是一個比較特殊的位,它使用奇偶的方式校驗數據位是否正確,它通常是不用的,因為它屬于一個對應的校驗控制器來完成,總耗時需要1s,所以如果要添加它的話意味著你每次傳輸至少要在1s以上,它用來確認數據位上的BIT為1的數量是奇數還是偶數,是一個最簡單的狀態位,因為傳輸無法避免干擾等情況,在一些場景惡劣的環境下這個位是非常有用的,當BIT為1的數量為偶數時,校驗位為1,為奇數時為0,接收方需要確認這個位與自己實際接收到的是否一致,不一致則可以要求目標方重發,它無法矯正數據,因為它無法確認哪個位有錯。
小插曲
現在市面上流行的路由器有一個閉源的算法,就是能夠將包的30%損壞修復,類型QR二維碼的原理,有興趣可以研究一下,QR二維碼里有一段數據是放矯正信息的,當二維碼有一部分無法識別時,會從這個矯正信息里在用特定的算法計算出原始信息,所以我們平時在掃二維碼時你可以遮住一小部分,會發現還是可以識別出來,有些工業二維碼修復能力更強,因為工業環境很容易出現油漆,污漬等其它遮擋物,遮擋住。
傳輸過程
如現在要傳輸“OK”兩個字符,O對應的二進制數據為01001111?,K對應的二進制數據為01001011,傳輸過程如下:
以下過程以RS-232起始信號為標準,數據位為8位,停止位為1位,沒有校驗位
速率計算
如果想計算一個BIT在當前波特率下每次傳輸需要耗時多久可以用倒數的方式計算。
如當前的波特率為115200
計算公式:
1/115200=868ns,如果加了奇偶校驗位別忘記在加上1s的耗時
即每868ns傳輸1bit。
波特率
波特率與時鐘頻率不同,串口允許兩個時鐘頻率不同的設備進行通訊,但要求波特率一致,波特率即你當前的芯片在一定周期內傳輸BIT的數量,這個波特率就是一定周期,因為兩個設備之間的時鐘頻率不同,一方快,另外一方可能慢,那么就協商一個固定周期,在這個固定周期里只能傳輸多少BIT位,且這個固定周期里是兩個設備的時鐘頻率都能達到的,如A設備的時鐘頻率是80hz,B設備的時鐘頻率是120hz,明顯B設備快于A設備,如果不協商明顯是無法通訊的,因為不在一個時間線上,則這里進行一次協商,則告訴AB設備我不管你們的時鐘頻率是快也好,慢也罷,我要求你們在100us里傳輸8個10個bit位,其中每10US傳輸一個BIT,那么此時A設備比較慢,但是它的頻率也剛好能夠達標每10US傳遞一個BIT,而B設備呢由于比較快,它10us甚至可以傳輸兩個BIT,但是快也沒用,因為協商好了規定時間,所以B設備每次到10毫秒時就傳輸一次,剩下時間則等待時間的到來,這個在芯片內部其實是可以根據設置當前工作時鐘頻率來完成,如當前波特率要求115200,它每86.8us傳輸一個bit位,那么只需要將當前工作時鐘頻率設置為每86.8us為一個周期即可與波特率對應起來。
這樣就完成了即便兩個設備頻率不同也能完成一次正常的通訊,這里需要明確波特率與時鐘頻率不同,實現波特率的方法不止設置時鐘頻率一種,也有另外一種方法就是外設時鐘,如芯片內部有一個外設時鐘,通過設置這個外設時鐘的工作頻率和中斷來完成這個工作,設置外設時鐘的好處在于芯片可以做別的事情,等時鐘中斷來了去發一次數據或接一次數據就可以了。
FIFO
FIFO存儲器
在了解UART FIFO功能先說一下FIFO存儲器,UART的功能就是基于FIFO存儲器
FIFO的概念
隨著芯片性能的提升的同時通訊速率也隨之提高,因傳輸率的問題,A設備的傳輸率要快于B設備的處理能力時就會產生數據流過多的情況,導致B設備的芯片無法及時處理這些數據就會導致部分數據丟失,為了解決這個問題提出了一種存儲模式,即FIFO,FIFO全拼是First-In First-Out 即先進先出,就是涉及一個存儲器用來臨時保存這些數據,然后芯片不再從數據寄存器里去取數據而是在FIFO存儲器里去取數據,因為芯片拿到數據后要進行一個處理,這個處理周期可能比較耗時,這就導致外面有新的數據來了沒能及時處理,這些數據又被新的數據給覆蓋掉了,導致數據的丟失,因為在串口的設計中只有一個數據寄存器,一般是8位寄存器,只能放下一個字節,當又來一個字節串口芯片就會將新的字節填充到數據寄存器里去,它不會等待CPU將數據取走后才填充,因為這樣會導致丟失新的數據。
FIFO的出現就是為了解決上述丟包的問題,當數據來了之后串口芯片將數據丟到FIFO的緩沖區里,通過設置最大深度字節來產生一次中斷告訴CPU來取走它們,這樣就解決了當CPU工作較忙無法取數據時產生丟失的問題,FIFO緩沖區多大取決于你當前芯片的設計,這些可以在你的芯片手冊上看到
同時FIFO還提供了一個功能,填充超時,因為有的時候在傳輸時設備可能會出現不定時的包,如A與B之間傳輸數據,B設備開啟了FIFO功能,并設置填充超出10個字節產生一次中斷告知CPU取走數據,但是由于A設備出現了一些問題,暫時不給B設備發數據了,那B設備里的一些數據就永遠無法產生中斷,那么就有了一個填充超時的中斷,即如果特定的時間里沒有將FIFO緩沖區填充到設定的指定深度時就會產生這個中斷,告訴CPU填充超時了,來處理一下這些沒有填滿的數據
以下是超時中斷的處理流程圖
超時設計
這里的超時設計有點特殊,FIFO的超時是指間隔,因為有時候可能是A設備數據發慢了或者其它原因堵塞了導致的,所以FIFO每次收到數據之后會有一個時間間隔,比如我們設置為3,那么當收到一個數據后超過3個周期收到周期沒有收到數據,就會產生超時中斷,若恰好2個周期數據來了,那么這個周期計數就會被清空置0,這里設置的方式也不是直接設毫秒的,設置是以1分之幾為單位,如當前FIFO緩沖區大小是12字節,設置1/8字節為填滿字節,1/3為超時間隔,即8個字節產生填滿中斷,超過3個接收字節時間間隔沒有收到數據產生超時中斷
有的MCU里的FIFO存儲器沒有超時中斷的功能,用戶可以自己寫一個,使用自己內部時鐘或者寫一段時間代碼,來定時將RXIFLSEL與TXIFLSEL標志位置1產生中斷,這兩個位是用于輸入與輸出中斷的。
FIFO緩沖區的清空
FIFO在設計時是不需要用戶去清空緩沖區的,我們只需要讀就可以了,FIFO是以填充的形式的去覆蓋緩沖區的,FIFO自己也不會去清空緩沖區,它只會覆蓋緩沖區,通過用戶設定的大小將新數據填充到緩沖區里然后產生中斷,這樣舊數據就被新數據替代也省去一個時間周期來清空緩沖區,那么這就產生一個問題,就是接收時,出現了超時的情況,如我們預設是8個字節為填滿,在經過上一次工作后新數據還沒有填滿8個,只填了4個,那么此時產生超時中斷,也就意味著其中4個是新數據剩下4個是舊的沒有填充的數據,所以這里需要注意一下
FIFO 輸入與輸出中斷
輸入的中斷條件是緩沖區里的數據達到用戶設置的長度后產生中斷告知用戶來取走
輸出的中斷條件是緩沖區里的數據達到用戶設置的長度并發出去后產生中斷
FIFO緩沖區取數據時的原理
FIFO去取數據時不能指定地址位且只能一次取一個字節,不能取指定地址上的字節,每次產生輸入中斷取數據時FIFO里有個地址寄存器,當我們每次去取一次以后,這個地址位自動加1,需要用戶手動判斷是否取完然后清空標志位
其它
一般情況下我們是不會用FIFO的因為UART是低速通訊方式,它每次只傳一個BIT在波特率的速率計算下其實速度是很慢的
FIFO在對一些一個字節就要求有響應的一些工作條件下是不建議使用的
UART FIFO
跟上面說的一樣,UART這里也只不過將FIFO存儲器設計到了UART串口芯片里去了,會提供對應的寄存器讓你去配置FIFO存儲器,也提供了對應的標志位用于表示當FIFO存儲器的當前狀態,如TX Ready與RX Ready位用于表示輸入與輸出緩沖區里是否有數據,當完成一次中斷后它倆會被清0,當有新數據覆蓋時才會置1,RXIFLSEL與TXIFLSEL標志位用于表示輸入與輸出緩沖區里的數據長度是否達到用戶設置的長度,這兩個位會置1并產生中斷,這個位不是自動清空的,是需要用戶手動去置0,如果不置0會無限進入中斷
FIFO緩沖區是有最大字節數的,這個具體要看你的MCU手冊里UART這塊針對FIFO的設置,UART若支持FIFO功能則會有對應的FIFO寄存器用于控制與開啟即nofifo模式與fifo模式
FIFO有兩種中斷,一種是填滿深度中斷,一種是超時中斷,這兩個參數都需要手動設置,第一個中斷即需要設置好當前FIFO的深度,如設置為8字節,當FIFO緩沖區填滿為8個字節時則響應中斷
FIFO針對發送與接收都有對應的緩沖區,當緩沖區達到標準時會將對應的中斷標志位置1
?
USART
USART是支持同步的一種串口模式,它基于UART,全名是:Universal Synchronous/Asynchronous Receiver/Transmitter(通用同步/異步串行接收/發送器)
這里說一下同步、異步,半雙工與全雙工的意思
異步
異步是一種通訊方式,是指不需要知道何時開始通訊,也不需要知道目標方的時鐘頻率是多少,只需要一個起始信號,來告訴別人開始通訊了,即異步操作,不需要另外一方一直等著或者每隔一段時間來一次通訊,另外一方只需要在一個周期里進行采樣,當采樣到了起始信號則開始通訊
半雙工
即一個線可以傳也可以收,但是不能一邊傳一邊收
全雙工
即兩根線,一根線穿,一根線收,UART就是異步全雙工,可以同時傳也可以同時收
同步
同步要求兩根線在傳輸時必須保證數據的一致性,異步是不考慮這個的,異步是可以一邊發一邊收,它不管發送的與接收的數據是否具有一致性,異步是非阻塞的,而同步是阻塞的,它要求數據發送之后在沒有接收到數據之前是不會進行下次通訊的
即同步要求發送與接收都完成之后才開學下一次傳輸,保證兩根線是同步工作。
總結
以上是生活随笔為你收集整理的UART工作原理详解的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 内存条上的数字代表的意义
- 下一篇: 什么是IP化改造