S3C2410 通用非同步收發UART 串列埠通訊
一、UART原理說明
通用非同步收發器簡稱UART,用來傳輸序列資料。
傳送資料時,CPU將並行資料寫入UART,UART按照一定的格式在一根電線上序列發出。
接收資料時,CPU檢測另一根電線上的訊號,講序列收集放在緩衝區中,CPU即可讀取UART獲得這些資料。
UART之間通過全雙工方式傳輸資料,最簡單隻有三根線TxD(傳送資料),RxD(接收資料),GnD(雙方參考電平),連線如下圖所示。
(PS:單工、半雙工、全雙工
單工資料傳輸只支援資料在一個方向上傳輸;
半雙工資料傳輸允許資料在兩個方向上傳輸,但是,在某一時刻,只允許資料在一個方向上傳輸,它實際上是一種切換方向的單工通訊;
全雙工資料通訊允許資料同時在兩個方向上傳輸,因此,全雙工通訊是兩個單工通訊方式的結合,它要求傳送裝置和接收裝置都有獨立的接收和傳送能力)
硬體連線圖如下:
UART使用標準的TTL/CMOS邏輯電平(0~5V 、0~3V、 0~2.5V 或 0~1.8V)來表示資料 ,高電平表示1,低電平表示0。
為了增強資料的抗干擾能力、提高傳輸長度,通常將TTL/CMOS邏輯電平轉換為RS-232邏輯電平(3~12V表示0,-3~-12V表示1)。
其中, MAX3232為電平轉換晶片, 利用雙電荷泵在3.0V至5.5V電源供電時能夠實現真正的RS-232效能,將ARM處理器晶片輸出的
電壓轉換為符合RS232規範的串列埠電壓。 即TXD0引腳經MAX3232晶片電壓轉換後成為串列埠引腳RS232TXD0, RXD0引腳經
MAX3232晶片電壓轉換後成為串列埠引
TXD 和RXD以”位“為最小傳輸資料,一幀資料由不可分割的若干位組成,它包含開始位、資料位、校驗位(可選)和停止位。
二、UART的使用
傳送資料之前,UART之間要約定好資料的傳輸速度(每位所佔的時間,即波特率),資料的傳輸格式(有多少資料位、是否使用校驗位、
是奇校驗還是偶校驗、有幾位停止位、是否使用流量控制)。
對於S3C2410和S3C2440,還有選擇所涉及管腳為UART功能,選擇UART通道的工作模式為中斷或者DMA模式。設定好之後,往某個暫存器寫入資料即可傳送,讀取某個暫存器即可得到接收到的資料。可以通過查詢狀態暫存器或者設定中斷來獲知資料是否已經發送完畢。是否已經收到資料。
所用的暫存器如下:
1、設定涉及管腳為UART功能
2、UBRDIVn暫存器:設定波特率
3、ULCONn暫存器:設定傳輸格式
4、UCON暫存器:設定時鐘源、中斷方式等
5、UFCONn暫存器、UFSTATn暫存器:FIFO設定
6、UMCONn暫存器、UMSTATn暫存器:流量控制
7、UTRSTATn暫存器:資料是否傳送完畢、是否收到資料
8、UERSTATn暫存器:錯誤是否發生
9、UTXHn暫存器:資料寫入,然後自動放入快取區,然後傳送。
10、URXHn暫存器:收到資料時,讀該暫存器即可得到資料。
PS:詳細的暫存器資訊去晶片手冊查詢。
三、UART操作例項
目的:
在PC機上通過鍵盤敲入任意字元,ARM將接受到的字元通過串列埠發出並在PC端的secureCRT上顯示。
開發板通過串列埠輸出字串。
程式碼詳解:
本例項串列埠引數設定如下:
使用串列埠0,三線連線,波特率115200,PCLK為50MHZ,一位起始位,八位資料位,沒有校驗位,一位停止位,不使用FIFO快取,普通輪詢模式,不使用中斷。
1、UART初始化
#define GPHCON *(volatile unsigned int *)0x56000070
#define ULCON0 *(volatile unsigned int *)0x50000000
#define UCON0 *(volatile unsigned int *)0x50000004
#define UTRSTAT0 *(volatile unsigned int *)0x50000010
#define UTXH0 *(volatile unsigned int *)0x50000020
#define URXH0 *(volatile unsigned int *)0x50000024
#define UBRDIV0 *(volatile unsigned int *)0x50000028
#define TXD0READY (1<<2)
#define RXD0READY 1
#define GPH_URAT 10<<4
#define GPH_MSK 15<<4
void uart_init(void)
{
GPHCON=(~GPH_MSK)&GPHCON; //GPH2 3位清零
GPHCON=GPH_URAT|GPHCON; //GPH2 3賦值設為TXD0和RXD0
UBRDIV0=0x1A; //設定波特率為115200
ULCON0=0x03;//設定8資料位,1停止位,無校驗位UCON0=0x05;//設定為普通輪詢}
2、傳送字元函式本例項不使用FIFO,傳送字元前需要先判斷上一個字元是否已經被髮送出去。如果沒有,則不斷查詢UTRSTAT0暫存器的位[2],當他為1時表示已經發送完畢。這時可向UTXH0暫存器中寫入要傳送的字元。
void uart_txd(char c) //傳送字元
{
while(! (UTRSTAT0&TXD0READY)); //等待,直到傳送緩衝區中的資料已經全部發出去
UTXH0=c; //寫入欲傳送的字元,UART自動傳送
}
3、傳送字串函式
void uart_txd(char *c) //傳送字串
{
for (; *c != '\0'; c++)
{
while(!(UTRSTAT0 & TXD0READY)); //不斷查詢,直到可以傳送資料
UTXH0 = *c ; //傳送資料
}
}
4、接收字元函式
讀取資料之前,要先查詢UTRSTAT0暫存器的[1]位,當為1的時候,表示接收快取區中有資料。於是,即可讀取URXH0得到資料。
char uart_rxd(void)//接收字元
{
while(! (UTRSTAT0&RXD0READY)); //等待,直到接收快取區中有資料來到
return URXH0; //直接讀取URXH0,即可獲得資料
}
5、主函式
int main(void)
{
uart_init(); //初始化(波特率115200,8N1)
/* S3C2440可以,但2410亂碼
**
char ch[]="===========\n\rhello word!\n\r===========\n\r"; // /n為換行 /r為跳到行首
char c;
int j;
for(j=0;j<39;j++) //顯示字串
{
uart_txd(ch[j]);
}
**
*/
uart_txd("===========\n\rhello word!\n\r===========\n\r"); //顯示字串
while(1) //串列埠接收資料後,再發送到PC secureCRT
{
c=uart_rxd();
uart_txd(c);
}
return 0;
}