1. 程式人生 > >Cortex-A9 UART

Cortex-A9 UART

數據復制 class art use stat per gen fontsize div

一、Exynos4412 UART 的特性

Exynos4412 中UART,有4 個獨立的通道,每個通道都可以工作於中斷模式或DMA 模式,即 UART 可以發出中斷或 DMA 請求以便在UART 、CPU 間傳輸數據。UART 由波特率發生器、發送器、接收器和控制邏輯組成。

使用系統時鐘時,Exynos4412 的 UART 波特率可以達到 4Mbps 。波特率可以通過編程進行 。

Exynos4412 UART 的通道 0有 256 字節的發送 FIFO 和 256 字節的接收FIFO ;通道 1、4有 64 字節的發送 FIFO 和 64 字節的接收FIFO;通道 2、3有 16 字節的發送FIFO 和 16 字節 的接收 FIFO 。發送數據時, CPU 先將數據寫入發送FIFO 中,然後 UART 會自動將FIFO 中的數據復制到“發送移位器” (Transmit Shifter )中,發送移位器將數據一位一位地發送到 TxDn 數據線上 (根據設定的格式,插入開始位 、較驗和停止)。接收數據時,“移位器” (Receive Shifter )將 RxDn 數據線上的數據一位一位的接收進來,然後復制到FIFO 中, CPU即可從中讀取數據。

Exynos4412 UART的每個通道支持停止位有 1位、 2位,數據位有 5、6、7或 8位,支持校驗功能,另外還有紅外發送 /接收功能。

Exynos4412 UART結構圖:

技術分享

二、uart初始化步驟:

1、將所涉及的UART通道管腳設為UART功能

比如 UART 通道 0中, GPA0_0 、GPA0_1 分別用作 RXD0 、TXD0,要使用 UART 通道 0時,先設置 GPA0CON 寄存器將 GPA0_0 、GPA0_1 引腳的功能設為 RXD0 、TXD0 。

2、 選擇UART的時鐘源

技術分享

Exynos4412 UART的時鐘源有八種選擇: XXTI 、XusbXTI 、SCLK_HDMI24M 、SCLK_USBPHY0 、 SCLK_HDMIPHY 、SCLKMPLL_USER_T 、SCLKEPLL 、SCLKVPLL ,由 CLK_SRC_PERIL0 寄存器控制。
選擇好時鐘源後,還可以通過 DIVUART0 ~4設置分頻系數 設置分頻系數 ,由 CLK_DIV_PERIL0 寄存器控制。 從分頻器得到的時鐘被稱為SCLK UART 。

SCLK UART 經過上圖中的“ UCLK Generator”後,得到UCLK ,它的頻率就是UART 的波特率。“ Generator UCLK Generator ”通過這 2個寄存器來設置: UBRDEVn 、UFRACVALn (在下面描述)。

3.、設置波特率:UBRDIVn寄存器(UART BAUD RATE DIVISOR)、UFRACVALn寄存器

根據給定的波特率、所選擇時鐘源頻率,可以通過以下公式計算 UBRDIVn 寄存器 (n 為 0~4,對應 5個 UART 通道 )的值。

UBRDIVn = (int)( UART clock / ( buad rate x 16) ) – 1

上式計算出來的 UBRDIVn 寄存器值不一定是整數, UBRDIVn 寄存器取其整數部分,小部分由 UFRACVALn 寄存器設置, UFRACVALn 寄存器的引入,使產生波特率更加精確。

例如,當UART clock為100MHz時,要求波特率為115200 bps,則:

100000000/(115200 x 16) – 1 = 54.25 – 1 = 53.25

UBRDIVn = 整數部分 = 53

UFRACVALn/16 = 小數部分 = 0.25

UFRACVALn = 4



4. 設置傳輸格式:ULCONn寄存器(UART LINE CONTROL)

ULCONn 寄存器 (n 為 0~4) 格式如下圖所示:

技術分享

5. 設置UART工作模式:UCONn寄存器(UART CONTROL)

技術分享

技術分享

6. UFCONn寄存器(UART FIFO CONTROL)、UFSTATn寄存器(UART FIFO STATUS)

UFCON n寄存器用於設置是否使用FIFO,設置各 FIFO的觸發閥值,即發送 FIFO中有多少個數據時產生中斷、接收 FIFO 中有多少個數據時產生中斷。並可以通過設置UFCON n寄存器來復位各個 FIFO 。

讀取 UFSTAT n寄存器可以知道各個 FIFO 是否已經滿、其中有多少個數據。

不使用 FIFO 時,可以認為 FIFO 的深度為1,使用 FIFO 時 Exynos4412 的 FIFO 深度最高可達到256 。


7. UMCONn寄存器(UART MODEM CONTROL)、UMSTATn寄存器(UART MODEM STATUS)

這兩類寄存器用於流量控制,這裏不介紹。


8. UTRSTATn寄存器(UART TX/RX STATUS)

UTRSTAT n寄存器用來表明數據是否已經發送完畢、是否已經接收到數據,格式如下表所示,下面說的“緩沖區”,其實就是下圖中的 FIFO ,不使用 FIFO 功能時可以認為其深度為 1。

技術分享

9. UERSTATn寄存器(UART ERROR STATUS)

用來表示各種錯誤是否發生,位 [0] 至位 [3] 為 1時分別表示溢出錯誤、校驗錯誤、幀錯誤、檢測到“ break ”信號。讀取這個寄存器時,它會自動清 0。

需要註意的是,接收數據時如果使用 FIFO ,則 UART 內部會使用一個“錯誤 FIFO ”來表明接收 FIFO 中哪個數據在接收過程發生了錯誤。 CPU 只有在讀出這個錯誤的數據時,才會覺察到發生了錯誤 。要想清除“FIFO ”,則必須讀出錯誤的數據,並讀出UERSTATn 寄存器。

10. UTXHn寄存器(UART TRANSMIT BUFFER REGISTER)

CPU 將數據寫入這個寄存器, UART即會將它保存到緩沖區中,並自動發送出去。

11. URXHn寄存器(UART RECEIVE BUFFER REGISTER)

當 UART 接收到數據時,讀取這個寄存器,即可獲得數據。

三、示例程序編寫

技術分享
#include "exynos_4412.h"

void delay_ms(unsigned int time);
void sendch(const char ch);
void sendstr(const char *str);
void recvch(char *ch);
void recvstr(char *str);

void myuart_init(void)
{
    //設置引腳功能 UART RX TX
    GPA1.CON = GPA1.CON & ~0xff | 0x22;
    //設置傳輸格式  無校驗 停止位:1 數據位:8
    UART2.ULCON2 = UART2.ULCON2 & ~0x7f | 0x3;
    //設置接收、發送方式
    UART2.UCON2 = UART2.UCON2 & ~0xf | 0x5;
    //設置波特率 115200
    UART2.UBRDIV2 = 53;
    UART2.UFRACVAL2 = 4;
    //DIV_VAL = (SCLK_UART / (bps * 16)) - 1
}

int main()
{
    char buf[] = "uart send: hello world!\r\n";
    char recvbuf[100];
    myuart_init();

    while(1)
    {
        sendstr(buf);
        delay_ms(1000);
    }

    return 0;
}

void delay_ms(unsigned int time)
{
    int i, j;
    while(time--)
    for(i = 0; i < 5; i++)
        for(j = 0; j < 610; j++);
}
void sendch(const char ch)
{
    /*等待發送器發送完成*/
    while(!(UART2.UTRSTAT2 & 0x2));
    UART2.UTXH2 = ch;
    if (ch == \n)
    {
        sendch(\r);
    }
}

void sendstr(const char *str)
{
    while(*str != \0)
    {
        sendch(*str++);
    }
}

void recvch(char *ch)
{
    /*等待接收完成*/
    while(!(UART2.UTRSTAT2 & 0x1));
    *ch = UART2.URXH2;
}

void recvstr(char *str)
{
    while(1)
    {
        recvch(str);
        if(*str == \r )
        {
            *str = \0;
            break;
        }
        str++;
    }
}

Cortex-A9 UART