標(biāo)題: S3C2440的UART通信 [打印本頁(yè)]
作者: 51黑小牛 時(shí)間: 2016-4-10 17:40
標(biāo)題: S3C2440的UART通信
1、UART原理簡(jiǎn)介
在介紹2440的UART控制器之前,我們首先來(lái)了解一下UART的原理
UART:Universal Asynchronous Receiver/Transmitter(通用異步收發(fā)送器),用來(lái)傳輸串行數(shù)據(jù),發(fā)送數(shù)據(jù)時(shí),CPU將并行數(shù)據(jù)寫(xiě)入U(xiǎn)ART,UART按照一定格式在TxD線上串行發(fā)出;接收數(shù)據(jù)時(shí),UART檢測(cè)到RxD線上的信號(hào),將串行收集放到緩沖區(qū)中,CPU即可讀取UART獲得的這些數(shù)據(jù)。
UART最精簡(jiǎn)的連線形式只有3根線,TXD用于發(fā)送,RXD用于接收,GND用于提供參考電平。UART之間以幀作為數(shù)據(jù)傳輸單位,幀由具有完整意義的若干位組成,它包含開(kāi)始位、數(shù)據(jù)位、校驗(yàn)位和停止位。發(fā)送數(shù)據(jù)之前,互相通信的UART之間要約定好數(shù)據(jù)傳輸速率(波特率的倒數(shù))、數(shù)據(jù)的傳輸格式(多少個(gè)數(shù)據(jù)位、是否使用校驗(yàn)位、奇校驗(yàn)還是偶校驗(yàn)、多少個(gè)停止位)。
2、S3C2440 UART的特性
S3C2440的通用異步收發(fā)器(UART)配有3個(gè)獨(dú)立異步串行I/O(SIO)端口,每個(gè)都可以通過(guò)產(chǎn)生中斷或DMA請(qǐng)求來(lái)進(jìn)行CPU和UART之間的數(shù)據(jù)傳輸。如圖1所示:每個(gè)UART包含一個(gè)波特率發(fā)生器、發(fā)送器、接收器和一個(gè)控制單元,
圖1 2440UART方框圖(帶FIFO)
波特率發(fā)生器可以由PCLK、FCLK/n或UEXTCLK(外部輸入時(shí)鐘)時(shí)鐘驅(qū)動(dòng)。UART通過(guò)使用系統(tǒng)時(shí)鐘可以支持最高115.2Kbps的比特率。如果是使用外部器件提供UEXTCLK的UART,則UART可以運(yùn)行在更高的速度。發(fā)送器和接收器各包含一個(gè)64字節(jié)的FIFO和數(shù)據(jù)移位器。要發(fā)送數(shù)據(jù)時(shí),先將數(shù)據(jù)寫(xiě)入到FIFO接著在發(fā)送前復(fù)制到發(fā)送移位器中,隨后將數(shù)據(jù)從發(fā)送數(shù)據(jù)引腳(TXDn)移出;接收數(shù)據(jù)時(shí),從接收數(shù)據(jù)引腳(RXDn)移入收到的數(shù)據(jù),接著從移位器復(fù)制到FIFO。
3、S3C2440 UART的使用
對(duì)于S3C2440,使用UART之前,首選需要對(duì)2440的UART模塊進(jìn)行初始化,需要設(shè)置波特率、傳輸格式(多少個(gè)數(shù)據(jù)位、是否使用校驗(yàn)位、奇校驗(yàn)或偶校驗(yàn)、多少個(gè)停止位、是否使用流量控制)、選擇所涉及的管腳為UART功能、選擇UART通道的工作模式為中斷模式或DMA模式。設(shè)置好之后,往相關(guān)寄存器寫(xiě)入數(shù)據(jù)即可發(fā)送,讀取相關(guān)寄存器即可接收到數(shù)據(jù),還可以通過(guò)查詢狀態(tài)寄存器或設(shè)置中斷來(lái)獲知數(shù)據(jù)是否發(fā)送完畢、是否接收到數(shù)據(jù)。
我用的開(kāi)發(fā)板是天嵌的TQ2440,該開(kāi)發(fā)板用SP3232EEN擴(kuò)展了一個(gè)RS232串口,電路連接如圖2 所示:
圖2 RS232原理圖
波特率發(fā)生器
每個(gè)UART的波特率發(fā)生器為發(fā)送器和接收器提供串行時(shí)鐘,波特率發(fā)生器的時(shí)鐘源可以選擇S3C2440A的內(nèi)部時(shí)鐘系統(tǒng)或者UEXTCLK。波特率時(shí)鐘是通過(guò)16和由UART波特率分頻寄存器(UBRDIVn)(n=0,1,2)指定的16位分頻系數(shù)來(lái)分頻源時(shí)鐘(PCLK,F(xiàn)CLK/n或者UEXTCLK)產(chǎn)生的,UBRDIVn由下列表達(dá)式確定:
UBRDIVn=(int)(UART時(shí)鐘/(波特率*16))-1
UART時(shí)鐘:PCLK,F(xiàn)CLK/n或者UEXTCLK,例如,如果波特率為115200bps并且UART時(shí)鐘為40MHz,則UBRDIVn為:
UBRDIVn=(int)(40000000/(115200*16))-1=(int)(21.7)-1(取最接近的整數(shù))=22-1=21
介紹發(fā)送和接收操作之前,先介紹幾個(gè)重要的寄存器
UBRDIVn寄存器:設(shè)置波特率,S3C2440 UART的時(shí)鐘源有兩種選擇:PCLK、UEXTCLK、FCLK/n,其中n的值通過(guò)UCON0-UCON2聯(lián)合設(shè)置
ULCONn寄存器:設(shè)置傳輸格式
UCONn寄存器:它用于選擇UART時(shí)鐘源、設(shè)置UART中斷方式
UFCONn寄存器、UFSTATn寄存器,UFCONn寄存器用于設(shè)置是否使用FIFO,設(shè)置各FIFO的觸發(fā)闕值,即發(fā)送FIFO中有多少個(gè)數(shù)據(jù)時(shí)產(chǎn)生中斷、接收FIFO中有多少個(gè)數(shù)據(jù)時(shí)產(chǎn)生中斷。并可以通過(guò)設(shè)置UFCONn寄存器來(lái)復(fù)位各個(gè)FIFO。讀取UFSTATn寄存器可以知道各個(gè)FIFO是否已經(jīng)滿,其中有多少個(gè)數(shù)據(jù)。
UMCONn寄存器、UMSTATn寄存器,這兩類(lèi)寄存器用于流量控制,具體看數(shù)據(jù)手冊(cè)
UTRSTATn寄存器,它用來(lái)表明數(shù)據(jù)是否已經(jīng)發(fā)送完畢、是否已經(jīng)接收到數(shù)據(jù)
UERSTATn寄存器,用來(lái)表示各種錯(cuò)誤是否發(fā)生
UTXHn寄存器,CPU將數(shù)據(jù)寫(xiě)入這個(gè)寄存器,UART即會(huì)將它保存到緩沖區(qū)中,并自動(dòng)發(fā)送出去
URXHn寄存器,當(dāng)UART接收到數(shù)據(jù)時(shí),CPU讀取這個(gè)寄存器,即可獲得數(shù)據(jù)。
下面通過(guò)實(shí)際的代碼來(lái)理解2440的UART
首選是UART的初始化,TQ2440將UART0引了一個(gè)接口出來(lái),就介紹UART0吧
2440的UART引腳是掛接在GPH上的,所以使用UART之前需要先對(duì)GPH的引腳功能進(jìn)行配置。
void uart0_init(void)
{
GPHCON |= 0xaa; // GPH0,GPH1,GPH2,GPH3分別nCTS0,nRTS0,TXD0,RXD0
GPHUP = 0x7ff; //內(nèi)部上拉被禁止
UFCON0 = 0x00; // 不使用FIFO
UMCON0 = 0x00; // 不使用流控
ULCON0 = 0x03; // 8N1(8個(gè)數(shù)據(jù)位,無(wú)校驗(yàn),1個(gè)停止位)
UCON0 = 0x245;
// 查詢方式,UART時(shí)鐘源為PCLK,中斷請(qǐng)求方式為T(mén)x-電平,Rx-脈沖
rUBRDIV0=( (int)(pclk/16./baud+0.5) -1 ); //設(shè)置波特率
}
接下來(lái)幾個(gè)是進(jìn)行數(shù)據(jù)的發(fā)送和接收的函數(shù)
//======此函數(shù)的作用是向UART發(fā)送一個(gè)字符,不用FIFO,直接用UART發(fā)送
void Uart_SendByte(char data)
{
if(data=='\n')
{
while(!(rUTRSTAT0 & 0x2));
取出rUTRSTAT0(UART0發(fā)送/接收寄存器)寄存器中的第2位,含義為T(mén)ransmit buffer是否為空,為1時(shí)表示空。在發(fā)送緩沖器為空時(shí),再發(fā)送
// Delay(1); //because the slow response of hyper_terminal
WrUTXH0('\r'); //將數(shù)據(jù)寫(xiě)入到UART0發(fā)送緩沖器中
}
while(!(rUTRSTAT0 & 0x2)); //Wait until THR is empty.
// Delay(1);
WrUTXH0(data);
}
//========發(fā)送字符串的函數(shù)
void Uart_SendString(char *pt)
{
while(*pt)
Uart_SendByte(*pt++);
}
//C語(yǔ)言的可變參數(shù),為了達(dá)到printf的功能
//例如:Uart_Printf(“my name is %s”a[10]) ;就相當(dāng)于Uart_SendString(“my name is XX”);XX是a[10]的內(nèi)容
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的發(fā)送器為空,就是發(fā)送完畢
void Uart0_TxEmpty()
{
while(!(rUTRSTAT0 & 0x4)); //Wait until Tx shifter is empty.
}
//===從終端上獲取敲入的字符,返回值為char類(lèi)型。RdURXH0有數(shù)據(jù)時(shí),返回URXH的數(shù)據(jù)。當(dāng)URXH沒(méi)有數(shù)據(jù)時(shí),總是等待,直到有數(shù)據(jù)。
char Uart_Getch(void)
{
while(!(rUTRSTAT0 & 0x1)); //接收緩沖器接收到有效數(shù)據(jù)
return RdURXH0(); //從UART0接收緩沖器(URXH0)接收數(shù)據(jù)
}
//===Uart_GetKey 這個(gè)與Uart_Getch 不同的是,當(dāng)URXH沒(méi)有數(shù)據(jù)時(shí)返回0。有數(shù)據(jù)時(shí),返回?cái)?shù)據(jù),這個(gè)函數(shù)可以用來(lái)查看當(dāng)前URXH中的值。
char Uart_GetKey(void)
{
if(rUTRSTAT0 & 0x1) //Receive data ready
return RdURXH0();
else
return 0;
}
//==這個(gè)函數(shù)用于從終端得到一個(gè)字符串,并儲(chǔ)存到string中
void Uart_GetString(char *string)
{
char *string2 = string;
char c;
while((c = Uart_Getch())!='\r')//’\r’是回車(chē)鍵
{
if(c=='\b')//’\b’是backspace按鍵
{
if( (int)string2 < (int)string )
{
Uart_Printf("\b \b");//因?yàn)閎ackspace,所以刪除最后一個(gè)顯示的字符
string--;
}
}
else
{
*string++ = c; //不是回車(chē)和退格鍵,則儲(chǔ)存到string中
Uart_SendByte(c); //每輸入一個(gè)字符,都將它輸出到終端中
}
}
*string='\0';
Uart_SendByte('\n');
}
歡迎光臨 (http://www.zg4o1577.cn/bbs/) |
Powered by Discuz! X3.1 |
主站蜘蛛池模板:
免费小视频在线观看
|
一区二区三区在线观看视频
|
中文字幕日韩一区
|
精品国产乱码久久久
|
亚洲欧美视频一区二区
|
日本 欧美 国产
|
亚洲www|
欧美一级在线免费观看
|
日韩av啪啪网站大全免费观看
|
日韩精品 电影一区 亚洲
|
成人精品一区二区三区中文字幕
|
国产日韩欧美电影
|
国产精品99久久久久久宅男
|
av男人的天堂在线
|
久久午夜电影
|
香蕉二区|
99精品视频一区二区三区
|
精品国产精品三级精品av网址
|
久久网国产
|
伊人久久国产
|
久久免费视频2
|
亚洲欧美综合精品另类天天更新
|
婷婷综合色
|
亚洲成人三区
|
97av在线|
欧美成人一区二免费视频软件
|
亚洲精品成人网
|
日本一区精品
|
一区在线播放
|
久久精品屋
|
狠狠操av
|
国产精品日韩在线
|
www.操.com|
亚洲精彩视频在线观看
|
久久99精品久久久久久秒播九色
|
一区二区三区电影网
|
中文字幕成人网
|
欧美一区2区三区4区公司二百
|
久久性色
|
91婷婷韩国欧美一区二区
|
a级片在线
|