久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 3767|回復: 0
打印 上一主題 下一主題
收起左側

S3C2440的UART通信

[復制鏈接]
跳轉到指定樓層
樓主
ID:113276 發表于 2016-4-10 17:40 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
1、UART原理簡介

在介紹2440的UART控制器之前,我們首先來了解一下UART的原理
UART:Universal Asynchronous Receiver/Transmitter(通用異步收發送器),用來傳輸串行數據,發送數據時,CPU將并行數據寫入UART,UART按照一定格式在TxD線上串行發出;接收數據時,UART檢測到RxD線上的信號,將串行收集放到緩沖區中,CPU即可讀取UART獲得的這些數據。
UART最精簡的連線形式只有3根線,TXD用于發送,RXD用于接收,GND用于提供參考電平。UART之間以幀作為數據傳輸單位,幀由具有完整意義的若干位組成,它包含開始位、數據位、校驗位和停止位。發送數據之前,互相通信的UART之間要約定好數據傳輸速率(波特率的倒數)、數據的傳輸格式(多少個數據位、是否使用校驗位、奇校驗還是偶校驗、多少個停止位)。
        
2、S3C2440 UART的特性
S3C2440的通用異步收發器(UART)配有3個獨立異步串行I/O(SIO)端口,每個都可以通過產生中斷或DMA請求來進行CPU和UART之間的數據傳輸。如圖1所示:每個UART包含一個波特率發生器、發送器、接收器和一個控制單元,
圖1 2440UART方框圖(帶FIFO)
波特率發生器可以由PCLK、FCLK/n或UEXTCLK(外部輸入時鐘)時鐘驅動。UART通過使用系統時鐘可以支持最高115.2Kbps的比特率。如果是使用外部器件提供UEXTCLK的UART,則UART可以運行在更高的速度。發送器和接收器各包含一個64字節的FIFO和數據移位器。要發送數據時,先將數據寫入到FIFO接著在發送前復制到發送移位器中,隨后將數據從發送數據引腳(TXDn)移出;接收數據時,從接收數據引腳(RXDn)移入收到的數據,接著從移位器復制到FIFO。

3、S3C2440 UART的使用
對于S3C2440,使用UART之前,首選需要對2440的UART模塊進行初始化,需要設置波特率、傳輸格式(多少個數據位、是否使用校驗位、奇校驗或偶校驗、多少個停止位、是否使用流量控制)、選擇所涉及的管腳為UART功能、選擇UART通道的工作模式為中斷模式或DMA模式。設置好之后,往相關寄存器寫入數據即可發送,讀取相關寄存器即可接收到數據,還可以通過查詢狀態寄存器或設置中斷來獲知數據是否發送完畢、是否接收到數據。
我用的開發板是天嵌的TQ2440,該開發板用SP3232EEN擴展了一個RS232串口,電路連接如圖2 所示:
圖2 RS232原理圖
波特率發生器
每個UART的波特率發生器為發送器和接收器提供串行時鐘,波特率發生器的時鐘源可以選擇S3C2440A的內部時鐘系統或者UEXTCLK。波特率時鐘是通過16和由UART波特率分頻寄存器(UBRDIVn)(n=0,1,2)指定的16位分頻系數來分頻源時鐘(PCLK,FCLK/n或者UEXTCLK)產生的,UBRDIVn由下列表達式確定:
UBRDIVn=(int)(UART時鐘/(波特率*16))-1
UART時鐘:PCLK,FCLK/n或者UEXTCLK,例如,如果波特率為115200bps并且UART時鐘為40MHz,則UBRDIVn為:
UBRDIVn=(int)(40000000/(115200*16))-1=(int)(21.7)-1(取最接近的整數)=22-1=21

       介紹發送和接收操作之前,先介紹幾個重要的寄存器
UBRDIVn寄存器:設置波特率,S3C2440 UART的時鐘源有兩種選擇:PCLK、UEXTCLK、FCLK/n,其中n的值通過UCON0-UCON2聯合設置
ULCONn寄存器:設置傳輸格式
UCONn寄存器:它用于選擇UART時鐘源、設置UART中斷方式
UFCONn寄存器、UFSTATn寄存器,UFCONn寄存器用于設置是否使用FIFO,設置各FIFO的觸發闕值,即發送FIFO中有多少個數據時產生中斷、接收FIFO中有多少個數據時產生中斷。并可以通過設置UFCONn寄存器來復位各個FIFO。讀取UFSTATn寄存器可以知道各個FIFO是否已經滿,其中有多少個數據。
UMCONn寄存器、UMSTATn寄存器,這兩類寄存器用于流量控制,具體看數據手冊
UTRSTATn寄存器,它用來表明數據是否已經發送完畢、是否已經接收到數據
UERSTATn寄存器,用來表示各種錯誤是否發生
UTXHn寄存器,CPU將數據寫入這個寄存器,UART即會將它保存到緩沖區中,并自動發送出去
URXHn寄存器,當UART接收到數據時,CPU讀取這個寄存器,即可獲得數據。
下面通過實際的代碼來理解2440的UART
首選是UART的初始化,TQ2440將UART0引了一個接口出來,就介紹UART0吧
2440的UART引腳是掛接在GPH上的,所以使用UART之前需要先對GPH的引腳功能進行配置。
void uart0_init(void)
{
    GPHCON  |= 0xaa;    // GPH0,GPH1,GPH2,GPH3分別nCTS0,nRTS0,TXD0,RXD0
    GPHUP   = 0x7ff;     //內部上拉被禁止
UFCON0  = 0x00;     // 不使用FIFO
    UMCON0  = 0x00;     // 不使用流控

    ULCON0  = 0x03;     // 8N1(8個數據位,無校驗,1個停止位)
    UCON0   = 0x245;   
// 查詢方式,UART時鐘源為PCLK,中斷請求方式為Tx-電平,Rx-脈沖
   rUBRDIV0=( (int)(pclk/16./baud+0.5) -1 );   //設置波特率
}
接下來幾個是進行數據的發送和接收的函數
//======此函數的作用是向UART發送一個字符,不用FIFO,直接用UART發送
void Uart_SendByte(char data)
{
if(data=='\n')
{
while(!(rUTRSTAT0 & 0x2));
取出rUTRSTAT0(UART0發送/接收寄存器)寄存器中的第2位,含義為Transmit buffer是否為空,為1時表示空。在發送緩沖器為空時,再發送
// Delay(1);                 //because the slow response of hyper_terminal
       WrUTXH0('\r');  //將數據寫入到UART0發送緩沖器中
}
while(!(rUTRSTAT0 & 0x2));   //Wait until THR is empty.
//  Delay(1);
WrUTXH0(data);
}              
//========發送字符串的函數
void Uart_SendString(char *pt)
{
    while(*pt)
        Uart_SendByte(*pt++);
}

//C語言的可變參數,為了達到printf的功能
//例如:Uart_Printf(“my name is %s”a[10]) ;就相當于Uart_SendString(“my name is XX”);XX是a[10]的內容
void Uart_Printf(char *fmt,...)  
{
       va_list ap;
       char string[256];

       va_start(ap,fmt);
       vsprintf(string,fmt,ap);
       Uart_SendString(string);
       va_end(ap);
}

//==等待,直到UART的發送器為空,就是發送完畢
void Uart0_TxEmpty()
{
while(!(rUTRSTAT0 & 0x4));  //Wait until Tx shifter is empty.
}

//===從終端上獲取敲入的字符,返回值為char類型。RdURXH0有數據時,返回URXH的數據。當URXH沒有數據時,總是等待,直到有數據。

char Uart_Getch(void)
{
while(!(rUTRSTAT0 & 0x1)); //接收緩沖器接收到有效數據
return RdURXH0();   //從UART0接收緩沖器(URXH0)接收數據
}
//===Uart_GetKey 這個與Uart_Getch 不同的是,當URXH沒有數據時返回0。有數據時,返回數據,這個函數可以用來查看當前URXH中的值。
char Uart_GetKey(void)
{
if(rUTRSTAT0 & 0x1)    //Receive data ready
return RdURXH0();
else
return 0;
}
//==這個函數用于從終端得到一個字符串,并儲存到string中
void Uart_GetString(char *string)
{
    char *string2 = string;
    char c;
    while((c = Uart_Getch())!='\r')//’\r’是回車鍵
    {
        if(c=='\b')//’\b’是backspace按鍵
        {
            if( (int)string2 < (int)string )
            {
                Uart_Printf("\b \b");//因為backspace,所以刪除最后一個顯示的字符
                string--;
            }
        }
        else
        {
            *string++ = c;       //不是回車和退格鍵,則儲存到string中
            Uart_SendByte(c);   //每輸入一個字符,都將它輸出到終端中
        }
    }
    *string='\0';
    Uart_SendByte('\n');
}



分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 亚洲国产精品一区二区久久 | 国产男女猛烈无遮掩视频免费网站 | 在线成人免费视频 | 热99视频 | 天天天操 | 成人影音 | 天天精品综合 | 九九热精品视频 | 国产欧美日韩一区二区三区在线 | 中文在线播放 | 国产精品久久久久久久久 | www.888www看片 | 91国自视频| 国产亚洲成av人在线观看导航 | 日韩电影一区二区三区 | 午夜免费| 99一级毛片 | 综合天天久久 | 国产精品久久久久久久久久 | 精品国产欧美一区二区 | a级黄色片视频 | 日日噜噜噜夜夜爽爽狠狠视频97 | 伊人免费在线观看高清 | 午夜视频在线播放 | 日韩综合一区 | 九一在线观看 | 在线观看国产www | 日韩精品中文字幕在线 | 日日日视频 | 久久男人 | 欧美一区二区在线观看 | 久久国产精彩视频 | 日韩av在线一区二区三区 | 日韩一区中文字幕 | 欧美黄视频 | 亚洲中午字幕 | 国产精品视频区 | 国产美女一区二区 | 超碰人人91 | 久久精品女人天堂av | 国产高清自拍视频在线观看 |