一、UART原理說明
通用異步收發(fā)器簡稱UART,用來傳輸串行數(shù)據(jù)。
發(fā)送數(shù)據(jù)時,CPU將并行數(shù)據(jù)寫入UART,UART按照一定的格式在一根電線上串行發(fā)出。
接收數(shù)據(jù)時,CPU檢測另一根電線上的信號,講串行收集放在緩沖區(qū)中,CPU即可讀取UART獲得這些數(shù)據(jù)。
UART之間通過全雙工方式傳輸數(shù)據(jù),最簡單只有三根線TxD(發(fā)送數(shù)據(jù)),RxD(接收數(shù)據(jù)),GnD(雙方參考電平),連線如下圖所示。
(PS:單工、半雙工、全雙工
單工數(shù)據(jù)傳輸只支持?jǐn)?shù)據(jù)在一個方向上傳輸;
半雙工數(shù)據(jù)傳輸允許數(shù)據(jù)在兩個方向上傳輸,但是,在某一時刻,只允許數(shù)據(jù)在一個方向上傳輸,它實(shí)際上是一種切換方向的單工通信;
全雙工數(shù)據(jù)通信允許數(shù)據(jù)同時在兩個方向上傳輸,因此,全雙工通信是兩個單工通信方式的結(jié)合,它要求發(fā)送設(shè)備和接收設(shè)備都有獨(dú)立的接收和發(fā)送能力)
硬件連接圖如下:
UART使用標(biāo)準(zhǔn)的TTL/CMOS邏輯電平(0~5V 、0~3V、 0~2.5V 或 0~1.8V)來表示數(shù)據(jù) ,高電平表示1,低電平表示0。
為了增強(qiáng)數(shù)據(jù)的抗干擾能力、提高傳輸長度,通常將TTL/CMOS邏輯電平轉(zhuǎn)換為RS-232邏輯電平(3~12V表示0,-3~-12V表示1)。
其中, MAX3232為電平轉(zhuǎn)換芯片, 利用雙電荷泵在3.0V至5.5V電源供電時能夠?qū)崿F(xiàn)真正的RS-232性能,將ARM處理器芯片輸出的
電壓轉(zhuǎn)換為符合RS232規(guī)范的串口電壓。 即TXD0引腳經(jīng)MAX3232芯片電壓轉(zhuǎn)換后成為串口引腳RS232TXD0, RXD0引腳經(jīng)
MAX3232芯片電壓轉(zhuǎn)換后成為串口引腳RS232RXD0。
TXD 和RXD以”位“為最小傳輸數(shù)據(jù),一幀數(shù)據(jù)由不可分割的若干位組成,它包含開始位、數(shù)據(jù)位、校驗(yàn)位(可選)和停止位。
二、UART的使用
發(fā)送數(shù)據(jù)之前,UART之間要約定好數(shù)據(jù)的傳輸速度(每位所占的時間,即波特率),數(shù)據(jù)的傳輸格式(有多少數(shù)據(jù)位、是否使用校驗(yàn)位、
是奇校驗(yàn)還是偶校驗(yàn)、有幾位停止位、是否使用流量控制)。
對于S3C2410和S3C2440,還有選擇所涉及管腳為UART功能,選擇UART通道的工作模式為中斷或者DMA模式。設(shè)置好之后,往某個寄存器寫入數(shù)據(jù)即可發(fā)送,讀取某個寄存器即可得到接收到的數(shù)據(jù)。可以通過查詢狀態(tài)寄存器或者設(shè)置中斷來獲知數(shù)據(jù)是否已經(jīng)發(fā)送完畢。是否已經(jīng)收到數(shù)據(jù)。
所用的寄存器如下:
1、設(shè)置涉及管腳為UART功能
2、UBRDIVn寄存器:設(shè)置波特率
3、ULCONn寄存器:設(shè)置傳輸格式
4、UCON寄存器:設(shè)置時鐘源、中斷方式等
5、UFCONn寄存器、UFSTATn寄存器:FIFO設(shè)置
6、UMCONn寄存器、UMSTATn寄存器:流量控制
7、UTRSTATn寄存器:數(shù)據(jù)是否發(fā)送完畢、是否收到數(shù)據(jù)
8、UERSTATn寄存器:錯誤是否發(fā)生
9、UTXHn寄存器:數(shù)據(jù)寫入,然后自動放入緩存區(qū),然后發(fā)送。
10、URXHn寄存器:收到數(shù)據(jù)時,讀該寄存器即可得到數(shù)據(jù)。
PS:詳細(xì)的寄存器信息去芯片手冊查找。
三、UART操作實(shí)例
目的:
在PC機(jī)上通過鍵盤敲入任意字符,ARM將接受到的字符通過串口發(fā)出并在PC端的secureCRT上顯示。
開發(fā)板通過串口輸出字符串。
代碼詳解:
本實(shí)例串口參數(shù)設(shè)置如下:
使用串口0,三線連接,波特率115200,PCLK為50MHZ,一位起始位,八位數(shù)據(jù)位,沒有校驗(yàn)位,一位停止位,不使用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賦值設(shè)為TXD0和RXD0
UBRDIV0=0x1A; //設(shè)置波特率為115200
ULCON0=0x03;//設(shè)置8數(shù)據(jù)位,1停止位,無校驗(yàn)位UCON0=0x05;//設(shè)置為普通輪詢}
2、發(fā)送字符函數(shù)
本實(shí)例不使用FIFO,發(fā)送字符前需要先判斷上一個字符是否已經(jīng)被發(fā)送出去。如果沒有,則不斷查詢UTRSTAT0寄存器的位[2],當(dāng)他為1時表示已經(jīng)發(fā)送完畢。這時可向UTXH0寄存器中寫入要發(fā)送的字符。
void uart_txd(char c) //發(fā)送字符
{
while(! (UTRSTAT0&TXD0READY)); //等待,直到發(fā)送緩沖區(qū)中的數(shù)據(jù)已經(jīng)全部發(fā)出去
UTXH0=c; //寫入欲發(fā)送的字符,UART自動發(fā)送
}
3、發(fā)送字符串函數(shù)
void uart_txd(char *c) //發(fā)送字符串
{
for (; *c != '