通用異步收發(fā)傳輸器,也就是我們常說的UART模塊,是一種串行通信外設(shè),它允許用戶將其與其他兼容UART的設(shè)備進行連接。UART模塊具有高度的可編程性,它提供了諸如帶過采樣功能的可編程波特率發(fā)生器、可配置的數(shù)據(jù)位大小(5位、6位、7位或8位)等特性。對于單主多從總線方案,還實現(xiàn)了第9位。
其他特性,比如奇偶校驗位的生成和檢測、線路中斷檢測以及硬件流量控制,在大多數(shù)微控制器的UART中都是標準配置。所有的UART都會有一個單獨的數(shù)據(jù)緩沖區(qū),用于發(fā)送和接收數(shù)據(jù)。有些UART可能會包含固定大小或可編程大小的先進先出(FIFO)緩沖區(qū),以減輕CPU中斷服務的負載。
從功能層面來看,UART有三個主要特性,即發(fā)送器、接收器和時鐘發(fā)生器。發(fā)送器有一個發(fā)送緩沖區(qū)和移位寄存器,用于執(zhí)行并行到串行的轉(zhuǎn)換。一個字節(jié)被加載到UART的發(fā)送緩沖區(qū)中,然后通過移位寄存器一位一位地進行轉(zhuǎn)換和發(fā)送。
發(fā)送控制邏輯輸出串行比特流,根據(jù)控制寄存器中的程序配置,該比特流以起始位開頭,接著是數(shù)據(jù)位、奇偶校驗位和停止位。當發(fā)送緩沖區(qū)為空時,發(fā)送邏輯也會通知CPU,并且至少會有一個發(fā)送數(shù)據(jù)緩沖寄存器。其他的可能會提供多個緩沖區(qū),帶有固定或可編程的閾值,也就是我們所說的FIFO。這些FIFO緩沖區(qū)有助于減輕CPU中斷服務的負載。
接收器也有一個移位寄存器和一個接收緩沖區(qū),在接收器控制邏輯檢測到有效的起始位后,對接收到的比特流執(zhí)行串行到并行的轉(zhuǎn)換。溢出、奇偶校驗、幀錯誤檢查以及線路中斷檢測也由控制邏輯來執(zhí)行。在檢測到停止位后,這些位會被重新組合成一個數(shù)據(jù)字節(jié),并放入接收緩沖區(qū)中。當接收到數(shù)據(jù)時,控制邏輯會通知CPU。
發(fā)送和接收移位寄存器以及邏輯的時鐘定時由UART的時鐘發(fā)生器提供。時鐘發(fā)生器接收一個輸入的系統(tǒng)時鐘,并生成兩個輸出時鐘,一個時鐘用于發(fā)送部分,通常被稱為位時鐘或波特率時鐘,而一個更快的時鐘則被接收器用于位采樣。
發(fā)送器和接收器模塊也有控制邏輯,它為每個模塊以及UART所支持的各種協(xié)議提供狀態(tài)信息和控制,這里就不詳細介紹這些協(xié)議了。
UART的發(fā)送模塊負責將一個數(shù)據(jù)字節(jié)轉(zhuǎn)換為比特,并將每個比特從UART的發(fā)送數(shù)據(jù)引腳(TXD)串行發(fā)送出去。這一功能通過一個緩沖區(qū)、串行移位寄存器以及發(fā)送狀態(tài)和控制邏輯來實現(xiàn)。
UART的緩沖區(qū)大小可以是一個數(shù)據(jù)字節(jié),也可以是先進先出(FIFO)隊列中的多個數(shù)據(jù)字節(jié),具體取決于UART本身。該緩沖區(qū)可減少CPU管理UART發(fā)送緩沖區(qū)所需的時間。發(fā)送控制邏輯負責管理每個數(shù)據(jù)字節(jié)向UART移位寄存器的移動。數(shù)據(jù)的并行到串行轉(zhuǎn)換是通過將數(shù)據(jù)逐位從TXD引腳移出實現(xiàn)的。
要發(fā)送一個字節(jié),CPU會檢查發(fā)送緩沖區(qū)標志,查看緩沖區(qū)是否為空。如果發(fā)送緩沖區(qū)為空,CPU會將一個字節(jié)寫入發(fā)送緩沖區(qū)。如果UART有多個緩沖區(qū)或采用FIFO結(jié)構(gòu),CPU可以持續(xù)加載額外的字節(jié),直至FIFO被填滿。
若移位寄存器為空,緩沖區(qū)中的第一個字節(jié)會立即從緩沖區(qū)轉(zhuǎn)移到移位寄存器中??刂七壿嫊⒂梦粫r鐘,開始將比特從發(fā)送引腳輸出。當移位寄存器中的最后一位被移出后,緩沖區(qū)或FIFO中的下一個字節(jié)會自動轉(zhuǎn)移到移位寄存器中,如此循環(huán)往復。
和發(fā)送器一樣,UART的接收模塊也有一個串行移位寄存器、接收緩沖區(qū)和控制邏輯,其職責是將傳入的串行比特流組合成一個并行的數(shù)據(jù)字節(jié),以便CPU讀取。這個過程始于將傳入的比特移入移位寄存器。
由于UART的異步特性,接收模塊會對接收數(shù)據(jù)引腳(RXD)進行采樣,以此判斷何時有比特到達,并準確判定該比特是0還是1。接收邏輯能夠通過檢測比特流中第一個比特(即起始位)的下降沿,與每個新比特流的起始同步。
當移位寄存器被填滿時,這些比特會被轉(zhuǎn)移到接收器的輸入緩沖區(qū)或FIFO中,同時設(shè)置一個標志。CPU可以監(jiān)控接收緩沖區(qū)標志,從而知曉何時從接收緩沖區(qū)讀取數(shù)據(jù)。
時鐘發(fā)生器的時鐘源通常來自系統(tǒng)時鐘。借助分頻器和過采樣特性,UART的時鐘發(fā)生器會生成兩個時鐘,一個供發(fā)送器使用,稱為比特率時鐘或波特時鐘;另一個供接收器使用,在文中,我們稱之為采樣時鐘。
雖然發(fā)送器以比特率時鐘頻率運行,但接收器需要更高的時鐘頻率,通常是比特率時鐘頻率的數(shù)倍。接收器邏輯利用這個更高頻率的采樣時鐘,通過在每個比特周期內(nèi)多次采樣邏輯電平,來確定到達RXD引腳的每個比特的值。
如上圖所示,接收器需要一個高于發(fā)送時鐘頻率的時鐘頻率來生成采樣時鐘。這個采樣時鐘通常是發(fā)送時鐘的3倍、8倍或16倍。
這個更高頻率的采樣時鐘使接收器的移位寄存器和控制邏輯能夠在一個比特時鐘周期內(nèi)對RXD引腳上的輸入電壓電平進行多次采樣。接收器利用這些采樣結(jié)果來判斷輸入的比特是有效的1還是0。
在此,我們給出一個時序圖示例,展示了16倍過采樣時鐘與以波特時鐘頻率到達RXD引腳的接收比特之間的關(guān)系。此示例中涉及的概念同樣適用于3倍和8倍過采樣情況。
在解釋時序之前,要明白對于每個發(fā)送的字節(jié),數(shù)據(jù)位之前總是有一個單獨的起始位。起始位表現(xiàn)為RXD引腳上的高到低的跳變,它標志著一個 UART數(shù)據(jù)包的開始。
在接收數(shù)據(jù)包的間隙,接收器會在每個采樣時鐘周期持續(xù)評估RXD引腳上的電壓電平,等待檢測起始位的下降沿。當檢測到RXD引腳的下降沿時,接收器的采樣時鐘就會與UART數(shù)據(jù)包同步。每次接收到數(shù)據(jù)包都會進行這種同步,所以這為發(fā)送器和接收器的同步提供了一種簡單的方法。
接下來的操作被稱為“多數(shù)原則”,不同的UART可能會有所不同。但通常情況下,接收器會在第7、第8和第9個采樣時鐘周期對RXD引腳進行采樣。如果在這三次采樣中,RXD引腳都為低電平,那么這個比特就被判定為0。
另一方面,如果在這三次采樣中,RXD引腳都為高電平,那么這個比特就被判定為1。需要注意的是,在某些UART中,起始位可能會被采樣多次而非三次,并且可能會在比特周期的更早階段進行采樣。
那么,使用哪種過采樣率最好呢?這取決于具體情況。不過要考慮到,使用16倍過采樣時,功耗可能會比使用8倍或3倍過采樣時更高。使用16倍采樣時鐘時,還有一個需要考慮的因素,即采樣部分的比特邊沿與實際接收到的邊沿之間存在1/16的時間差。這意味著在比特周期的1/16(即6%)處就可能已經(jīng)出現(xiàn)誤差了;而使用8倍采樣時鐘時,這個誤差是1/8(即12.5%)。
一般來說,與使用8倍過采樣相比,使用16倍過采樣時,不同UART之間的波特率頻率差異可以更寬松一些。使用8倍過采樣時,不同UART之間的波特率差異必須控制得更嚴格。由于任意兩個UART的系統(tǒng)時鐘源存在差異,將UART配置為以相同的波特率頻率運行并不能保證它們的頻率完全相同。
實際上,在大多數(shù)情況下,頻率永遠不會完全相同,尤其是考慮到一個或兩個UART的頻率可能會隨溫度變化,或者可能會引入一些時鐘抖動。如果這些差異較小,是很容易被容忍的,因為接收器會在每個比特的中點附近進行采樣。
在這部分內(nèi)容中,我們了解了如何配置UART的分頻器和過采樣特性,以實現(xiàn)所需的傳輸波特率和接收器采樣頻率。如前文所述,分頻器的目的是降低輸入時鐘頻率,以支持各種較低的發(fā)送波特率。
UART的分頻器通常由兩個除數(shù)組成。一個是整數(shù)除數(shù),我們稱之為整數(shù)波特率除數(shù)(IBRD);另一個是小數(shù)除數(shù),即小數(shù)波特率除數(shù)(FBRD)。它們共同構(gòu)成了UART的除數(shù),即波特率除數(shù)(BRD)。根據(jù)輸入頻率和除數(shù)的組合,通常可以達到所需的波特率。
某些輸入時鐘和除數(shù)的組合可能無法產(chǎn)生所需的確切波特率。除數(shù)的小數(shù)部分用于幫助實現(xiàn)非常精確的時鐘頻率,而僅使用整數(shù)除數(shù)是無法做到這一點的。
計算波特率除數(shù)很簡單。將UART的輸入時鐘除以過采樣配置值(16、8或3)與目標波特率的乘積。讓我們來看一個例子,假設(shè)我們希望以16倍過采樣、輸入時鐘頻率為20Mhz的條件實現(xiàn)19200bps。
根據(jù)所示的公式,計算出的波特率除數(shù)是65.104。因此,整數(shù)部分65就是IBRD的值。但小數(shù)部分0.104必須轉(zhuǎn)換為可以在FBRD中使用的格式。有關(guān)如何處理小數(shù)格式的詳細信息,請參考你所使用的UART的文檔。
在最后這部分內(nèi)容中,我們來看看UART通常是如何相互連接的。大多數(shù) UART應用支持兩線接口。發(fā)送數(shù)據(jù)引腳(TXD)用于發(fā)送數(shù)據(jù),而接收數(shù)據(jù)引腳(RXD)用于接收數(shù)據(jù)。為了讓兩個UART進行通信,兩個UART的TXD引腳都必須連接到另一個UART的RXD引腳,就像這里的圖示一樣。首先要檢查TXD和RXD引腳是否與通用輸入輸出(GPIO)引腳或其他功能復用,如果有必要,相應地配置這些引腳。
在這種配置下,UART可以一次發(fā)送和接收一個數(shù)據(jù),這被稱為半雙工通信;也可以同時發(fā)送和接收數(shù)據(jù),這被稱為全雙工通信。兩個UART 必須使用相同的頻率或速率來發(fā)送和接收數(shù)據(jù),這個頻率或速率就稱為波特率。
一些UART還可以支持四線接口,通過另外兩個引腳 —— 請求發(fā)送引腳(RTS)和清除發(fā)送引腳(CTS)來進行流量控制。RTS輸出信號表示 UART 已準備好接收數(shù)據(jù),而CTS信號則控制來自發(fā)送UART的數(shù)據(jù)流。和TXD與RXD引腳一樣,UART的RTS和CTS引腳在兩個UART之間也是交叉連接的。
請注意,在許多微控制器(MCU)中,UART的引腳輸入和輸出并不總是在專用的輸入輸出引腳上。相反,UART的信號會與其他輸入和輸出功能復用,比如定時器輸出、模擬數(shù)字轉(zhuǎn)換器(ADC)輸入以及通用輸入輸出功能。對于引腳數(shù)量較少的器件來說尤其如此。如果是這種情況,請按照微控制器文檔中的建議配置輸入輸出引腳。
總結(jié):UART是一種串行通信外設(shè),具有高度可編程性,提供如可編程波特率發(fā)生器、可配置數(shù)據(jù)位大小等特性,支持單主多從總線方案。其功能模塊包括發(fā)送器、接收器和時鐘發(fā)生器,分別負責數(shù)據(jù)發(fā)送、接收和時鐘定時。發(fā)送器將數(shù)據(jù)字節(jié)轉(zhuǎn)為比特流,接收器將串行比特流組合為數(shù)據(jù)字節(jié)。UART時鐘發(fā)生器生成發(fā)送和接收時鐘,接收器利用更高頻率的采樣時鐘確定比特值。UART通過兩線或四線接口通信,支持半雙工或全雙工模式,且引腳常與其他功能復用,需按文檔配置。