UART(Universal Asynchronous Receiver/Transmitter,,通用異步接收/發(fā)送裝置)用于異步通信,,可以實(shí)現(xiàn)全雙工發(fā)送和接收。s3c2440提供了三個(gè)UART端口,,它們都可以通過查詢,、中斷和DMA方式傳輸數(shù)據(jù),。下面通過超級終端發(fā)送字符到2440,2440返回該字符的例子來簡要介紹一下s3c2440中UART的用法:
用到的寄存器:
GPHCON :端口配置引腳寄存器
GPHUP:使能上拉禁止寄存器
ULCON0:線路控制寄存器
UCON0:通道控制寄存器
UTRSTAT0:發(fā)送/接收狀態(tài)寄存器
UBRDIV0:波特率分頻寄存器
UTXTH0:通道0發(fā)送緩沖寄存器
URXTH0:通道0接收緩沖寄存器
編程流程如下: 1,UART的初始化:包括串口的選擇,,IO口的初始化,,UART的UFCONn,
UMCONn,,ULCONn,,UCONn及波特率的初始化
其中波特率的具體計(jì)算公式為:時(shí)鐘源頻率÷(波特率×16)-1。
如圖:
具體相關(guān)寄存器的配置如下:
- rGPHCONrGPHCON = rGPHCON & (~(0xffff)) ;
- rGPHCONrGPHCON = rGPHCON | (0xaaa0) ;//除GPH0,GPH1以外的腳都是第二功能,,urt0的9個(gè)腳
- rGPHUP = 0x0; // 使用內(nèi)部上拉電阻,。
-
- rUFCON0=0x00; //不使用FIFO
- rUMCON0=0x00; //不使用自動(dòng)流控制
- rULCON0=0x03; //不采用紅外線傳輸模式,無奇偶校驗(yàn)位,,1個(gè)停止位,,8個(gè)數(shù)據(jù)位
- rUCON0=0x245; //發(fā)送中斷為電平方式,接收中斷為邊沿方式,,禁止超時(shí)中斷,,允許產(chǎn)生錯(cuò)誤狀態(tài)中斷,禁止回送模式,,禁止中止
- //信號,,傳輸模式為中斷請求模式,接收模式也為中斷請求模式,。
- rUBRDIV0=( (int)(PCLK/16./baud+0.5) -1 );//?為什么要加0.5,?
2,要發(fā)送數(shù)據(jù)時(shí),,等待直到發(fā)送緩沖區(qū)UTRSTAT0[1]為空.再把數(shù)據(jù)放入發(fā)送緩存器UTXHn中,。
要發(fā)送的數(shù)據(jù),首先被寫入FIFO,,然后拷貝到發(fā)送移位寄存器,,接著它從數(shù)據(jù)輸出端(TxDn)依次被移位輸出
- while(!(rUTRSTAT0 & 0x2)); //等待,直到發(fā)送緩沖區(qū)為空
- Delay(100);
- WrUTXH0(ch); //串口0發(fā)送字符
3,, 要接收數(shù)據(jù)時(shí),,檢查串口狀態(tài)寄存器0,是否有數(shù)據(jù)到來,,然后啟動(dòng)接收,,接收到的數(shù)據(jù)是放到接收緩存器URXHn中。
UART的接收數(shù)據(jù):被接收的數(shù)據(jù)也同樣從數(shù)據(jù)接口RxDn移位輸入到移位寄存器,,然后拷貝到FIFO中
- while(!(rUTRSTAT0 & 0x1)); //檢查串口狀態(tài)寄存器0,,是否有數(shù)據(jù)到來,啟動(dòng)接收過程
- return RdURXH0(); //URXH0串口接收緩存寄存器0
uart.c
實(shí)現(xiàn)查詢發(fā)式串口的收發(fā)功能,,接收來自串口的字符,,并將接收到的字符發(fā)送到超級終端:
- static int UartNum=0; //串口選擇的標(biāo)志位,可以省略,,只是方便多個(gè)串口選擇
- //===============================================================
- //對Uart進(jìn)行初始化,以所需要的波特率為輸入?yún)?shù)
- void myUart_Init(int whichuart, int baud)
- {
- if(whichuart==0) //判斷是否選擇串口0,假如選擇串口1,,則應(yīng)該初始化串口1的寄存器
- {
- UartNum=0; //串口選擇的標(biāo)志位
-
- rGPHCONrGPHCON = rGPHCON & (~(0xffff)) ;
- rGPHCONrGPHCON = rGPHCON | (0xaaa0) ;//除GPH0,GPH1以外的腳都是第二功能,,urt0的9個(gè)腳
- rGPHUP = 0x0; // 使用內(nèi)部上拉電阻。
-
- rUFCON0=0x00; //不使用FIFO
- rUMCON0=0x00; //不使用自動(dòng)流控制
- rULCON0=0x03; //不采用紅外線傳輸模式,,無奇偶校驗(yàn)位,,1個(gè)停止位,8個(gè)數(shù)據(jù)位
- rUCON0=0x245; //發(fā)送中斷為電平方式,,接收中斷為邊沿方式,,禁止超時(shí)中斷,允許產(chǎn)生錯(cuò)誤狀態(tài)中斷,,禁止回送模式,禁止中止
- //信號,,傳輸模式為中斷請求模式,,接收模式也為中斷請求模式。
- rUBRDIV0=( (int)(PCLK/16./baud+0.5) -1 );//?為什么要加0.5,?
- Delay(10);
- }
-
- }
-
- /*******************************************************************/
- void myUart_SendByte(char ch)
- {
- if (UartNum ==0) //判斷是否選擇串口0,,在這里也可以不用這句,
- //只是方便多個(gè)串口選擇時(shí)用
- {
- if(ch=='\n') //判斷是否是換行字符,,如果是換行字符,,發(fā)送一個(gè)回車符
- {
- while(!(rUTRSTAT0 & 0x2)); //等待,直到發(fā)送緩沖區(qū)為空
- //Delay(10); //超級中斷的響應(yīng)速度較慢
- WrUTXH0('\r'); //發(fā)送回車符
- }
- while(!(rUTRSTAT0 & 0x2)); //等待,,直到發(fā)送緩沖區(qū)為空
- Delay(100);
- WrUTXH0(ch); //串口0發(fā)送字符
- }
-
- }
-
- /********************************************************************/
- void Uart_Send (char *str)
- {
- myUart_Init(0,115200);
- while (*str)
- myUart_SendByte(*str++);
- }
- /********************************************************************/
- char myUart_ReceiveByte(void) //接收字符函數(shù)
- {
- if(UartNum==0) //選擇串口0
- {
- while(!(rUTRSTAT0 & 0x1)); //檢查串口狀態(tài)寄存器0,,是否有數(shù)據(jù)到來,啟動(dòng)接收過程
- return RdURXH0(); //URXH0串口接收緩存寄存器0
- }
- return 0;
- }
-
- /********************************************************************/
- void Uart_receive(char *string) //接收函數(shù)
- {
- char *stringstring2 = string;
- char c;
- myUart_Init(0,115200); //串口的選擇與波特率的選擇
- while((c = myUart_ReceiveByte())!='\n') //循環(huán)判斷接收字符函數(shù)返回的字符是不是換行字符\r是換行符?\n?
- {
- if(c=='\b')//\b回退符
- {
- if( (int)string2 < (int)string )
- {
- Uart_Printf("\b \b");
- string--;
- }
- }
- else
- {
- *string++ = c;
- myUart_SendByte(c);
- }
- }
- *string='\0'; //接收完畢后執(zhí)行空格
- myUart_SendByte('\n'); //如果接收完畢后,,補(bǔ)充一個(gè)回車
- }
測試用主函數(shù):
- int Main(void)
- {
- char *str;
- char *string;
- ChangeClockDivider(3,1); //1:3:6
- ChangeMPllValue(127,2,1); //405MHZ
- Port_Init();
- Isr_Init();
-
- Uart_Send("Please Input a string:\n"); //超級終端提示輸入一串字符
- Uart_receive(string); //2440接收字符
- *str=*string; //發(fā)送的跟接收的字符相等
- Delay(500);
- Uart_Send(str); //2440發(fā)送字符顯示到超級終端上
- while(1);
- }
效果圖:
完整工程文件可在這里下載,。
|