四、s3c2440 裸機開發 通用異步收發器UARN

四、通用異步收發器UARN


原文地址 http://blog.csdn.net/woshidahuaidan2011/article/details/51137047

by jaosn Email: [email protected]


 UART(Universal AsynchronousReceiver/Transmitter,通用異步接收/發送裝置)用於異步通信,可以實現全雙工發送和接收。2440有三個UART:UART0,UART1,UART2其結構圖如下所示:


通過上圖可以看到UART包含baud-rate generator波特率發生器,transmitter發送器,receiver 接收器and a control unit控制單元。在UART使用FIFO模式的時候,其中發送器和接收器分別有一個大小爲64字節的發送緩存器寄存器和接收緩存寄存器FIFO(先進先出),通過上圖還可以看到,假如不使用FIFO模式,接收器分別使用的發送保存寄存器和接收保存寄存器;還可以看到,圖中波特率產生器會受到時鐘源的影響,UART可有三個時鐘源以供選擇,分別爲PCLK,FCLK/n還有外部時鐘UEXTCLK。

對於波特率產生器,首先要提到UBRDIVn(n爲0,1,2下面雷同),可以通過該寄存器設置波特率,設置的公式如下:

UBRDIVn=(int)(UARTclock / (buad ratex 16) ) –1

其中UART clock正如上面說的,可以選擇PCLK, FCLK/n or UEXTCLK

UBRDIVn可以取值爲0到2^16-1,在旁路模式下(bypass mode),該寄存器可以設置爲0,該寄存器圖爲:


此寄存器不用多說明,直接填寫數字就可以。

假設要設置的波特率爲115200,UART的時鐘UART clock爲40M的話,那麼:

UBRDIVn =(int)(40000000 / (115200 x 16) ) -1

= (int)(21.7) -1 [round to the nearestwhole number]

=22 -1 = 21

可以看到,上面的計算取整之後將會出現誤差,這裏的誤差允許範圍爲1.87%,誤差計算方式爲:

tUPCLK = (UBRDIVn + 1)x 16 x 1Frame / PCLK        tUPCLK:   實際UART Clock
tUEXACT = 1Frame / baud-rate                       tUEXACT:  理想UART Clock

UART error = (tUPCLK – tUEXACT) / tUEXACTx 100%

其中1Frame = start bit + data bit + parity bit + stop bit. 開始位+數據位奇偶校驗位+停止位

這裏的幀可以畫圖表示:

start bit(1位)

data bit(5-8位)

parity bit(1位)

stop bit(1或2位)

 

 

 

 

 

 

 

 

 

 

 

 

至於一幀數據到底是怎麼設置的,可以使用ULCONn寄存器,以ULCON0爲例:


ULCON0【1:0】設置數據位的格式,可以設置成5到8位

ULCON0【2】設置停止位,1位或者兩位停止位

ULCON0【5:3】設置校驗模式,0xx表示無校驗

                                                           100表示奇校驗

                            101表示偶校驗

                            101表示發送數據強制設置爲1,接受數據檢測是否爲1

                            101表示發送數據強制設置爲0,接受數據檢測是否爲0

ULCON0【6】設置模式,0表示正常模式,1表示紅外模式

 

通過ULCONn設置幀的傳輸格式是最基本設置,設置完幀格式後就可以設置UART時鐘源和一些模式設置,這個設計的寄存器爲UCONn:

 


這裏,UCONn主要是設置一寫發送或者接收數據模式、中斷觸發形式和UART的時鐘選擇設置。看一下每一位具體含義:

UCONn【1:0】選擇如何接收緩存器讀取數據 00表示禁止接收數據

                                                                                        01表示中斷接收或者查詢法接收

                                                                                        10表示DMA0請求(UART0獨有)

                                                                                               DMA3請求(UART2獨有)                                                                                                                 11表示DMA1請求(UART1獨有)

UCONn【3:2】選擇如何發送緩存器發送數據   00表示禁止發送數據

                                                                                        01表示中斷髮送或者查詢法發送

                                                                                        10表示DMA0請求(UART0獨有)

                                                                                               DMA3請求(UART2獨有)                                                                                                                 11表示DMA1請求(UART1獨有)

UCONn【4】 設置此位,UART會在一幀的時間內發送一個break信號,發送完之後改位自動清除。

UCONn【5】 自循環模式,這種模式僅用於測試,該位設置爲1可以,在內部,RX和TX會連接起來。

UCONn【6】設置接收錯誤狀態接收使能,此位設置爲1時,當發生比如幀錯誤,溢出錯誤時將產生中斷。

UCONn【7】當使用UART的FIFO的時,此位設置爲1時,當接收超時時,會觸發中斷。

UCONn【8】接收中斷設置,設置爲1表示電平觸發,設置爲0表示脈衝觸發,在FIFO模式時,當FIFO的值達到設置的閾值會觸發中斷,在非FIFO模式時,有一個數據便觸發中斷。

UCONn【9】發送中斷設置,設置爲1表示電平觸發,設置爲0表示脈衝觸發,在FIFO模式時,當FIFO的值達到設置的閾值會觸發中斷,在非FIFO模式時,有一個數據便觸發中斷。

UCONn【11:10】UART時鐘選擇: 00/10 PCLK  01外部時鐘UEXTCLK   11  FCLK/n

UCONn【15:12】選擇FCLK/n模式的時候,用來確定n的具體數值。下面詳細介紹一下:

n的值要受到UCON0【15:12】、UCON1【15:12】和UCON2【14:12】共同決定的,且當其中的一個設置爲非0時,其餘兩個必須設置爲0,其中要注意的是:

UCON2[15]起到決定性因素,是FCLK/n的使能位。

n的值設置方式爲:

當n的範圍爲7到21時,UART時鐘=FCLK/( UCON0【15:12】的設定值+6)

當n的範圍爲22到36時,UART時鐘=FCLK/(UCON1【15:12】的設定值+21)

當n的範圍爲37到43時,UART時鐘=FCLK/(UCON2【14:12】的設定值+36)

 

通過閱讀上面的寄存器的含義結合自己實際的需求就可以完成其模式的選擇即使時鐘的配置,剛纔有有提到UART發送和接收都可以使用一款緩衝區FIFO,這裏介紹一下UART的FIFO,控制FIFO的寄存器UFCONn:


這裏仍以UFCON0爲例:

UFCON0【0】FIFO使能位,決定是否使用FIFO

UFCON0【1】接收FIFO復位位,設置爲1,將自動清除接收FIFO的內容

UFCON0【2】發送FIFO復位位,設置爲1,將自動清除發送FIFO的內容

UFCON0【5:4】接收FIFO觸發閾值設定

UFCON0【7:6】發送FIFO觸發閾值設定

 

UART的FIFO總體來說比較簡單,結合前面所講解的幀格式,時鐘,基本就設置的差不多了,通過上面的基本設置就可以使用UART,但是,2440爲了是數據在傳輸的過程中儘量避免數據的丟失,也有有關自動流控制AFC(Auto Flow Control)的寄存器UMCONn,介紹該寄存器之前,需要對流控制做有關的說明:

數據在兩個串口之間傳輸時,常常會出現丟失數據的現象,或者兩臺計算機的處理速度不同,如臺式機與單片機之間的通訊,接收端數據緩衝區已滿,則此時繼續發送來的數據就會丟失。現在我們在網絡上通過MODEM進行數據傳輸,這個問題就尤爲突出。流控制能解決這個問題,當接收端數據處理不過來時,就發出“不再接收”的信號,發送端就停止發送,直到收到“可以繼續發送”的信號再發送數據。因此流控制可以控制數據傳輸的進程,防止數據的丟失。 PC機中常用的兩種流控制是硬件流控制(包括RTS/CTS、DTR/CTS等)和軟件流控制XON/XOFF(繼續/停止)

對於硬件流控制常用的有RTS/CTS流控制和DTR/DSR(數據終端就緒/數據設置就緒)流控制。硬件流控制必須將相應的電纜線連上,用RTS/CTS(請求發送/清除發送)流控制時,應將通訊兩端的RTS、CTS線對應相連,數據終端設備(如計算機)使用RTS來起始調制解調器或其它數據通訊設備的數據流,而數據通訊設備(如調制解調器)則用CTS來起動和暫停來自計算機的數據流。這種硬件握手方式的過程爲:我們在編程時根據接收端緩衝區大小設置一個高位標誌(可爲緩衝區大小的75%)和一個低位標誌(可爲緩衝區大小的25%),當緩衝區內數據量達到高位時,我們在接收端將CTS線置低電平(送邏輯0),當發送端的程序檢測到CTS爲低後,就停止發送數據,直到接收端緩衝區的數據量低於低位而將CTS置高電平。RTS則用來標明接收設備有沒有準備好接收數據。常用的流控制還有還有DTR/DSR(數據終端就緒/數據設置就緒)。我們在此不再詳述。

由於電纜線的限制,我們在普通的控制通訊中一般不用硬件流控制,而用軟件流控制。一般通過XON/XOFF來實現軟件流控制。常用方法是:當接收端的輸入緩衝區內數據量超過設定的高位時,就向數據發送端發出XOFF字符(十進制的19或Control-S,設備編程說明書應該有詳細闡述),發送端收到XOFF字符後就立即停止發送數據;當接收端的輸入緩衝區內數據量低於設定的低位時,就向數據發送端發出XON字符(十進制的17或Control-Q),發送端收到XON字符後就立即開始發送數據。一般可以從設備配套源程序中找到發送的是什麼字符。 當軟件裏用了流控制時,應做詳細的說明,如何接線,如何應用。應該注意,若傳輸的是二進制數據,標誌字符也有可能在數據流中出現而引起誤操作,這是軟件流控制的缺陷,而硬件流控制不會有這個問題。

接下來看下2440自動流控制有關的寄存器UMCONn:


通過下面的註釋可以注意到只有UART0和UART1擁有AFC功能,下面對寄存器的位做出簡要說明

UMCONn【0】:設置爲1使能nRTS(請求發送),但是假如使能使能AFC功能,該位是無效的,該位的值是2440自動設置的

UMCONn【1:3】:保留位,必須爲0

UMCONn【1】:AFC使能位,設置爲1使能AFC

UMCONn【5:7】:保留位,必須爲0

與之對應的狀態寄存器是UMSTATn,主要是讀取一些請求發送的狀態信息,這裏不再詳細說明,具體查閱手冊。

設置部分已經介紹完畢,通過上面的設置,即可完整的完成通信。但是當數據發送或者接收的時候,用戶往往想知道是否發送完畢,或者已經發送了多少還差多少可以發送完畢等,也不比如在接收數據的時候,用戶要知道已經接收到了多少數據,是否已經接收完畢或者還差多少纔可以接收完畢。所以我們還需要幾個狀態寄存器來了解UART的運行狀態:

 

UTSTATn寄存器用於表明收發的一些狀態,是一些只讀寄存器:

UTSTATn【0】收到數據該位自動置1,當使用FIFO,應該配合查詢檢測UFSTAT寄存器

UTSTATn【1】當發送緩衝區沒有數據時該位置1,當使用FIFO,應該配合查詢檢測UFSTAT寄存器

UTSTATn【2】當發送緩存器沒有數據且最後一個數據發送完畢的時候該爲置1.

剛纔有提到UFSTATn寄存器,看下下他的作用:


UFSTATn寄存器是使用FIFO需要注意的:

UFSTATn【5:0】接收FIFO緩存器的數據的數目

UFSTATn【6】當接收FIFO緩存器的滿了之後該位自動爲置1

UFSTATn【13:8】發送FIFO緩存器的數據的數目

UFSTATn【14】當發送FIFO緩存器的滿了之後該位自動爲置

 

還有一個錯誤狀態寄存器UERSTATn需要需要注意:


UERSTATn【0】在接受數據時,發生溢出錯誤是該位置1

UERSTATn【1】在接受數據時,有校驗錯誤則置1

UERSTATn【2】在接受數據時,有幀錯誤則置1

UERSTATn【3】在接受數據時,到BREAK信號的時候則置1

注意,當讀取該寄存器時,UERSTATn寄存器將自動清零。

寄存器UFSTATn和寄存器UERSTATn就像一個顯示器一樣,通過這兩個顯示器,你可以知道UART的收發數據狀態及其FIFO的狀態。

到現在爲止,有關UART的原理及其寄存器已經介紹完畢,一切設置完畢後就可接收或者發送數據了,接收和發送比較簡單,只需要向着UTXHn 和URXHn寫入數據或者讀取數據就可以(都是以byte爲單位):

UTXHn:將要發送的數據發到此寄存器,UART會把數據放到發送緩衝區,自動發送出去,數值0到255

URXHn :從該寄存器讀取數據,數值0到255

 

現在對串口接收實例進行總結:

1、  設置相關的引腳爲UART功能的引腳 可以通過GPnCON寄存器來設置,一般情況下要使能上拉電阻功能以使端口穩定,通過GPnUP設置上拉使能

2、  設置UART的數據幀格式 可通過ULCONn來設置

3、  設置UART的時鐘源,及其發送接收方式  可通過UCONn來設置

4、  對於有關FIFO的設置 通過UFCONn來設置

5、  設置是否使用自動流控 可通過UMCONn來設置

6、  設置UART的波特率 UBRDIVn

 

給出一個初始化的例子:

voiduart0_init(void)

void uart0_init(void) //初始化函數

{

 

          //1、設置相關的引腳爲UART功能的引腳可以通過GPnCON寄存器來設置,一般情況下要使能上拉電阻功能以使端口穩定,通過GPnUP設置上拉使能

           //   TXD0=GPH2 RXD0=GPH3

           rGPHCON &=~(3<<4);

           rGPHCON|=(2<<4);  //TXD0

           rGPHCON&=~(3<<6);

           rGPHCON|=(2<<6);  //TXD0

           rGPHUP  &=~(3<<2);//使能上拉

 

           //2設置UART的數據幀格式可通過ULCONn來設置

//8個數據位1位停止位無校驗位正常模式

           rULCON0 |= 0x03 ;

           //3設置UART的時鐘源,及其發送接收方式 可通過UCONn來設置

          rUCON0 |=(1|(1<<2));//設置查詢或者中斷接收,查詢或者中斷髮送,時鐘源爲PCLK其餘採用默認值

 

           //4對於有關FIFO的設置通過UFCONn來設置

 

           rUFCON0 &=~1;//不使用FIFO

 

           //5設置是否使用自動流控可通過UMCONn來設置

           rUMCON0 &=~(1<<4);//不使用AFC

 

           //6設置UART的波特率  UBRDIVn

           rUBRDIV0=(int)( PCLK_DATA /( BUAD_RATE * 16) )-1;//PCLK=50m 波特率115200

}

 

 

 

void send_c(unsigned char c)  //發送一個字符函數

{

    /* 等待,直到發送緩衝區中的數據已經全部發送出去 */

    while(!(rUTRSTAT0 & (1<<2)));

    /* 向UTXH0寄存器中寫入數據,UART即自動將它發送出去 */

    rUTXH0 = c;

}

 

unsigned char get_c(void) //接收函數

{

    /* 等待,直到接收緩衝區中的有數據 */

    while(!(rUTRSTAT0 & 1));

   

    /* 直接讀取URXH0寄存器,即可獲得接收到的數據 */

    returnrURXH0;

}

參考:http://blog.csdn.net/g1036583997/article/details/12717297

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