Telink之UART篇

本文關於UART的介紹,首先借助百度百科,進行基礎部分闡述

一、UART基礎知識

定義:通用異步收發傳輸器(Universal Asynchronous Receiver/Transmitter),通常稱作UART,是一種異步收發傳輸器。主要功能實現串並行數據的轉換,具體實物表現爲模塊化芯片,常常被用來作爲嵌入式芯片的外設模塊,與外部設備進行通信。

UART常常也被理解爲一種通信協議,用來實現異步串行通信,規定了數據傳輸格式和波特率,多是數據鏈路層的概念。常常被用來和UART做對比的RS-232和RS-485則規定了數據通信的電氣接口,更多的是物理層的概念。

二、UART基本結構

⑴ 輸出緩衝寄存器,它接收CPU從數據總線上送來的並行數據,並加以保存。
⑵ 輸出移位寄存器,它接收從輸出緩衝器送來的並行數據,以發送時鐘的速率把數據逐位移出,即將並行數據轉換爲串行數據輸出
⑶ 輸入移位寄存器,它以接收時鐘的速率把出現在串行數據輸入線上的數據逐位移入,當數據裝滿後,並行送往輸入緩衝寄存器,即將串行數據轉換成並行數據。
⑷ 輸入緩衝寄存器,它從輸入移位寄存器中接收並行數據,然後由CPU取走。
控制寄存器,它接收CPU送來的控制字,由控制字的內容,決定通信時的傳輸方式以及數據格式等。例如採用異步方式還是同步方式,數據字符的位數,有無奇偶校驗,是奇校驗還是偶校驗,停止位的位數等參數。
狀態寄存器。狀態寄存器中存放着接口的各種狀態信息,例如輸出緩衝區是否空,輸入字符是否準備好等。在通信過程中,當符合某種狀態時,接口中的狀態檢測邏輯將狀態寄存器的相應位置“1”,以便讓CPU查詢。
三、UART設計思想

 數據發送的思想是,當啓動字節發送時,通過TxD先發起始位,然後發數據位和奇偶數校驗位,最後再發停止位,發送過程由發送狀態機控制,每次中斷只發送1個位,經過若干個定時中斷完成1個字節幀的發送。

  數據接收的思想是,當不在字節幀接收過程時,每次定時中斷以3倍的波特率監視RxD的狀態,當其連續3次採樣電平依次爲1、0、0時,就認爲檢測到了起始位,則開始啓動一次字節幀接收,字節幀接收過程由接收狀態機控制,每次中斷只接收1個位,經過若干個定時中斷完成1個字節幀的接收。

爲了提高串口的性能,在發送和接收上都實現了FIFO功能,提高通信的實時性。FIFO的長度可以進行自由定義,適應用戶的不同需要。
波特率的計算按照計算公式進行,在設置最高波特率時一定要考慮模擬串口程序代碼的執行時間,該定時時間必須大於模擬串口的程序的規定時間。單片機的執行速度越快,則可以實現更高的串口通訊速度。

四、UART工作原理

(1)發送與接收

發送邏輯對從發送FIFO 讀取的數據執行“並→串”轉換。控制邏輯輸出起始位在先的串行位流,並且根據控制寄存器中已編程的配置,後面緊跟着數據位(注意:最低位 LSB 先輸出)、奇偶校驗位和停止位。

在檢測到一個有效的起始脈衝後,接收邏輯對接收到的位流執行“串→並”轉換。此外還會對溢出錯誤、奇偶校驗錯誤、幀錯誤和線中止(line-break)錯誤進行檢測,並將檢測到的狀態附加到被寫入接收FIFO 的數據中。

(2)波特率產生

波特率除法器(baud-rate divisor)是一個22 位數,它由16 位整數和6 位小數組成。波特率發生器使用這兩個值組成的數字來決定位週期。通過帶有小數波特率的除法器,在足夠高的系統時鐘速率下,UART 可以產生所有標準的波特率,而誤差很小。

(3)基於FIFO的數據收發

發送時,數據被寫入發送FIFO。如果UART 被使能,則會按照預先設置好的參數(波特率、數據位、停止位、校驗位等)開始發送數據,一直到發送FIFO 中沒有數據。一旦向發送FIFO 寫數據(如果FIFO 未空),UART 的忙標誌位BUSY 就有效,並且在發送數據期間一直保持有效。BUSY 位僅在發送FIFO 爲空,且已從移位寄存器發送最後一個字符,包括停止位時才變無效。即 UART 不再使能,它也可以指示忙狀態。

在UART 接收器空閒時,如果數據輸入變成“低電平”,即接收到了起始位,則接收計數器開始運行,並且數據在Baud16 的第8 個週期被採樣。如果Rx 在Baud16 的第8 週期仍然爲低電平,則起始位有效,否則會被認爲是錯誤的起始位並將其忽略。

如果起始位有效,則根據數據字符被編程的長度,在 Baud16 的每第 16 個週期對連續的數據位(即一個位週期之後)進行採樣。如果奇偶校驗模式使能,則還會檢測奇偶校驗位。

最後,如果Rx 爲高電平,則有效的停止位被確認,否則發生幀錯誤。當接收到一個完整的字符時,將數據存放在接收FIFO 中。

(4)中斷控制

出現以下情況時,可使UART 產生中斷:

1.FIFO 溢出錯誤

2.線中止錯誤(line-break,即Rx 信號一直爲0 的狀態,包括校驗位和停止位在內)

3.奇偶校驗錯誤

4.幀錯誤(停止位不爲1)

5.接收超時(接收FIFO 已有數據但未滿,而後續數據長時間不來)

6.發送

7.接收

由於所有中斷事件在發送到中斷控制器之前會一起進行“或運算”操作,所以任意時刻 UART 只能向中斷產生一箇中斷請求。通過查詢中斷狀態函數,軟件可以在同一個中斷服務函數裏處理多箇中斷事件(多個並列的if 語句)。

五、UART的FIFO操作

FIFO 是“First-In First-Out”的縮寫,意爲“先進先出”,是一種常見的隊列操作。 Stellaris 系列ARM 的UART 模塊包含有2 個16 字節的FIFO:一個用於發送,另一個用於接收。可以將兩個FIFO 分別配置爲以不同深度觸發中斷。可供選擇的配置包括:1/8、 1/4、1/2、3/4 和7/8 深度。例如,如果接收FIFO 選擇1/4,則在UART 接收到4 個數據時產生接收中斷。

發送FIFO的基本工作過程: 只要有數據填充到發送FIFO 裏,就會立即啓動發送過程。由於發送本身是個相對緩慢的過程,因此在發送的同時其它需要發送的數據還可以繼續填充到發送 FIFO 裏。當發送 FIFO 被填滿時就不能再繼續填充了,否則會造成數據丟失,此時只能等待。這個等待並不會很久,以9600 的波特率爲例,等待出現一個空位的時間在1ms 上下。發送 FIFO 會按照填入數據的先後順序把數據一個個發送出去,直到發送 FIFO 全空時爲止。已發送完畢的數據會被自動清除,在發送FIFO 裏同時會多出一個空位。

接收FIFO的基本工作過程: 當硬件邏輯接收到數據時,就會往接收FIFO 裏填充接收到的數據。程序應當及時取走這些數據,數據被取走也是在接收FIFO 裏被自動刪除的過程,因此在接收 FIFO 裏同時會多出一個空位。如果在接收 FIFO 裏的數據未被及時取走而造成接收FIFO 已滿,則以後再接收到數據時因無空位可以填充而造成數據丟失。

收發FIFO 主要是爲了解決UART 收發中斷過於頻繁而導致CPU 效率不高的問題而引入的。在進行 UART 通信時,中斷方式比輪詢方式要簡便且效率高。但是,如果沒有收發 FIFO,則每收發一個數據都要中斷處理一次,效率仍然不夠高。如果有了收發FIFO,則可以在連續收發若干個數據(可多至14 個)後才產生一次中斷然後一併處理,這就大大提高了收發效率。

完全不必要擔心FIFO 機制可能帶來的數據丟失或得不到及時處理的問題,因爲它已經幫你想到了收發過程中存在的任何問題,只要在初始化配置UART 後,就可以放心收發了, FIFO 和中斷例程會自動搞定一切。

六、UART的迴環模式

UART 可以進入一個內部迴環(Loopback)模式,用於診斷或調試。在迴環模式下,從Tx 上發送的數據將被Rx 輸入端接收。

七、UART與串行紅外協議

在某些 Stellaris 系列 ARM 芯片裏,UART 還包含一個 IrDA 串行紅外(SIR)編碼器/ 解碼器模塊。IrDA SIR 模塊的作用是在異步UART數據流和半雙工串行SIR 接口之間進行轉換。片上不會執行任何模擬處理操作。SIR 模塊的任務就是要給UART 提供一個數字編碼輸出和一個解碼輸入。UART 信號管腳可以和一個紅外收發器連接以實現IrDA SIR物理層連接。


------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

完成基礎部分的介紹之後,我們以Telink的TLSR8255F512爲例(又稱爲5562),具體介紹該模塊的組成原理及使用方法

5562的UART模塊是通過UART Tx和UART Rx接口實現全雙工模式的數據傳輸和接收;硬件流控是通過RTS和CTS接口實現的。


如圖所示,數據是先通過MCU或者DMA寫入到發送buffer,再通過發送引腳將數據傳輸給其他設備;接收數據時,數據先是通過接收引腳將數據存放到接收buffer中,再被MCU或者DMA讀取。

當5562的UART模塊的接收buffer接近飽和的時候,UART模塊就會通過RTS發送level signal(configurable)給發送端,阻止數據發送;反之,當UART模塊通過CTS引腳接收到來自接收端的level signal(configurable),也會停止數據的發送

                                

在沒有使用DMA模式的情況下,數據的發送或者接收會通過循環訪問4個字節的寄存器來實現。


寄存器uart_clk_div[14:0]用來配置時鐘分頻因子,計算公式爲:

uart_sclk=sclk/(uart_clk_div[14:0]+1)

  

寄存器uart_clk_div[15]用來使能時鐘分頻器,只有使能了時鐘分頻器之後,才能通過時鐘分頻因子對系統時鐘進行分頻,從獲得UART模塊的時鐘。

寄存器uart ctrl0[3:0]用來配置位寬(bwpc>2),設置波特率,計算公式爲:

Baudrate = uart_sclk/(uart ctrl0[3:0]+1)

根據sclk=(uart_clk_div[14:0]+1)*(uart ctrl0[3:0]+1)*Baudrate可知:在編寫軟件代碼時,爲獲得標準的波特率,必須適當配置uart_clk_div[14:0]和uart ctrl0[3:0]


寄存器Uart ctrl0[5:4]用來使能UART的Tx和Rx的DMA模式。關於DMA模式做如下介紹:

常規工作情況下,UART的數據收發可由MCU控制UART的內部FIFO來完成,但具體不論是以中斷還是以查詢的形式,過程中總是會佔用MCU的時間,即便FIFO的有效利用率達到最高時也是如此。這樣,在實際應用中,當串口數據包量較大時,UART的發送過程會佔用MCU很長時間,其中大多數時間是在等待一次數據傳輸的完成。爲了節省這段時間,提高MCU的使用效率,以完成更多的數據處理,將會用到DMA控制器。

DMA(英文全稱:Direct Memory Access)直接內存訪問,是指不經由MCU而直接從內存中存取數據的數據交換模式。當UART使用DMA控制器控制發送過程時,MCU會將發送的控制權交給DMA控制器,從而在數據發送的時期間去處理其它過程。

UART_DmaInit();

5562的UART模塊在使用DMA模式時,需要先通過配置Uart ctrl0[5:4]使能Tx和Rx的DMA模式;再者,通過配置寄存器DMA0MODE[0]和DMA1MODE[0]爲UART的發送和接收選擇相應的DMA 通道channel;

UART_RecBuffInit(recBuff,16);

完成上述配置之後,需要進行DMA模式下的接收buffer的配置,通過配置DMA0AL[7:0],DMA0AM[7:0],DMA0AH[2:0]來實現DMA模式下接收buffer起始地址的配置;接下來配置寄存器DMA0SIZE[7:0]設置DMA模式下的buffer大小:DMA0SIZEx16,因此在設置時,需要先除以16字節!


 

IRQ_UartDmaIrqEnable(FLD_UART_IRQ_RX|FLD_UART_IRQ_TX);

配置UART中斷屏蔽寄存器DMAMASK[1:0],根據需要分別進行接收中斷屏蔽寄存器DMAMASK[0]和發送中斷屏蔽寄存器DMAMASK[1]的配置([0]和[1]分別對應通道0和通道1,這是之前已經選擇好的);最後,通過配置MASK_0[4]=1使能DMA中斷。

      


至此,完成了對UART的DMA模式的基本配置,現在我們來看一下,UART的發送函數UART_Send(unsigned char* Addr)

                          

如上圖所示,DMA模式下,數據的發送原理:存儲在SRAM中的數據,在DMA控制器作用下開始執行數據搬運工作:

1.將數據從SRAM中搬運到UART,搬運完成後產生0x526:DMA1 packetx transferred flag=1;

2.再由UART將數據發送出去,發送完成後產生0x9e:Txdone:irq_sts[0]=1;

在操作第一步時首先設置SRAM buffer size,該設置是通過所發送數據的前4個字節實現的,硬件默認將所發送數據的前4個字節作爲SRAM buffer size ,比如發送的數據字節存放在trans_buf[16]數組中,那麼trans_buf[0]~trans_buf[3]依次存放SRAM buffer size 的低字節到高字節,trans_buf[0]=0x6,trans_buf[1]=0x00,trans_buf[2]=0x00,trans_buf[3]=0x00,即SRAM buffer size=6,數據發送從trans_buf[4]開始,總共6個字節;

完成SRAM buffer size的設置之後,需要通過配置0xc24:DMAREADY0[1]=1啓動DMA數據包搬運工作;

第二步操作由UART模塊自動完成,我們只需要在再次發送前檢查發送完成標識位0x9e:Txdone:irq_sts[0]即可。

------------------------------------------------------------------------------------------------------------------------------------

總結一下,DMA模式下所用到的配置寄存器如下:

1.與波特率相關的寄存器:uart_clk_div[14:0],uart ctrl0[3:0] 

(關鍵公式:sclk=(uart_clk_div[14:0]+1)*(uart ctrl0[3:0]+1)*Baudrate)

2.與FIFO相關的寄存器:uart_data_buf0~uart_data_buf3

(4層FIFO,常規模式下循環訪問它來進行數據收發;DMA模式下,由DMA控制,自動訪問實現數據收發,不需設置

3.與DMA模式相關的寄存器:

1) Uart ctrl0[5:4],DMA0MODE[0]DMA1MODE[0]

(前者使能Rx和Tx的DMA模式;後者爲Rx和Tx配置DMA通道,這裏分別配置的是通道0和通道1)

2) DMA0AL[7:0],DMA0AM[7:0],DMA0AH[2:0],DMA0SIZE[7:0]

(前三個是進行DMA模式下的接收buffer的首地址配置;後者是進行接收buffer大小配置)

     3)  DMAMASK[1:0],MASK_0[4]

(前者是開啓通道0和通道1的中斷屏蔽寄存器;後者是開啓DMA中斷)

4.與發送相關的寄存器:

      1)  DMA1AL[7:0],DMA1AM[7:0],DMA1AH[2:0]

(設置待發送緩存區的首地址;硬件默認將所發送數據的前4個字節作爲SRAM buffer size,自動偏移4個地址作爲待發

送數據的首地址)

      2)  設置DMAREADY0[1]=1,來啓動DMA數據的搬運工作,此時,UART就會在DMA的控制下完成數據的發送工作

    3)  兩個重要的標識位(再次發送時只需要判斷髮送完成標識位即可):

(1)將數據從SRAM中搬運到UART,搬運完成後產生0x526:DMA1 packetx transferred flag=1;

(2)再由UART將數據發送出去,發送完成後產生0x9e:Txdone:irq_sts[0]=1(只讀);

注意:標識位在被讀取完成之後是被自動清除的

------------------------------------------------------------------------------------------------------------------------------------

以上詳細描述了整個UART的DMA模式下寄存器配置使用和基本工作原理,


  




                        uart基本結構
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章