Subject:FL2440无操作系统应用程序编写测试002——UART
Date: 7-Nov-2011
1.UART介绍
UART:Universal Asynchronous Receiver/Transmitter,一种通用串行数据总线,用于异步通信。该总线双向通信,可以实现全双工传输和接收。在嵌入式设计中,UART用来与PC进行通信,包括与监控调试器和其它器件,如EEPROM通信。计算机内部采用并行数据,不能直接把数据发到Modem,必须经过UART整理才能进行异步传输,其过程为:CPU先把准备写入串行设备的数据放到UART的寄存器(临时内存块)中,再通过FIFO(First Input First Output,先入先出队列)传送到串行设备,若是没有FIFO,信息将变得杂乱无章,不可能传送到Modem。
UART首先将接收到的并行数据转换成串行数据来传输。消息帧从一个低位起始位开始,后面是5~8个数据位,一个可用的奇偶位和一个或几个高位停止位。接收器发现开始位时它就知道数据准备发送,并尝试与发送器时钟频率同步。如果选择了奇偶,UART就在数据位后面加上奇偶位。奇偶位可用来帮助错误校验。在接收过程中,UART从消息帧中去掉起始位和结束位,对进来的字节进行奇偶校验,并将数据字节从串行转换成并行。UART也产生额外的信号来指示发送和接收的状态。例如,如果产生一个奇偶错误,UART就置位奇偶标志。
详细参考:http://baike.baidu.com/view/245027.htm
2.硬件原理图(FL2440有二个三线的232电平串口(串口0及1))
3.控制框图
4.UART0寄存器设置
void UART0_Port_Init(U32 baudrate){
BYTE i = 0;
//UART0传输协议:Normal,无奇偶校验,1停止位,8数据位
rULCON0 = 0x3;
//UART0 Modem Control
rUMCON0 = 0x0;
//UART0 Control:时钟信号源->PCLK,传送/接收模式:轮询
rUCON0 = 0x245; // Control register
//UART0 FIFO Control
rUFCON0 = 0x0; //UART channel 0 FIFO control register, FIFO disable
//UART0 Baud Rate Generation
rUBRDIV0=( (U32)(PCLK/16./baudrate+0.5) -1 ); //Baud rate divisior register 0
for(i=0;i<100;i++);
}
5.代码分析 UART.c
#include "2440addr.h"
#include "def.h"
#include "option.h"
#include <stdarg.h>
#include <stdio.h>
//寄存器设置
void UART0_Port_Init(U32 baudrate){
BYTE i = 0;
rULCON0 = 0x3; //Line control register : Normal,No parity,1 stop,8 bits
rUMCON0 = 0x0; //UART chaneel 0 MODEM control register, AFC disable
rUCON0 = 0x245; // Control register
rUFCON0 = 0x0; //UART channel 0 FIFO control register, FIFO disable
rUBRDIV0=( (U32)(PCLK/16./baudrate+0.5) -1 ); //Baud rate divisior register 0
for(i=0;i<100;i++);
}
//等待接收缓冲器准备好
static void UART0_RxReady(void){
while(!(rUTRSTAT0 & 0x1)); //Wait until rx is ready
}
//等待发送缓冲器为空(可发送下一字符)
static void UART0_TxEmpty(void){
while(!(rUTRSTAT0 & 0x4)); //Wait until tx shifter is empty.
}
//读取字符,如果未接收到字符则等待
static BYTE UART0_GetChar(void){
UART0_RxReady();
return RdURXH0(); // (*(volatile unsigned char *)0x50000024)
}
//读取按键,如果未接收到按键则返回NULL
BYTE UART0_GetKey(void){
if(rUTRSTAT0 & 0x1){
return RdURXH0();
}
else{
return NULL;
}
}
//发送字符
void UART0_SendChar(BYTE data){
if(data=='\n'){
UART0_TxEmpty();
WrUTXH0('\r'); //(*(volatile unsigned char *)0x50000020)=(unsigned char)(ch)
}
UART0_TxEmpty();
WrUTXH0(data);
}
//发送字符串
static void UART0_SendStr(BYTE *pt){
while(*pt){
UART0_SendChar(*pt++);
}
}
//UART0_Printf
void UART0_Printf(BYTE *fmt,...){
va_list ap;
char str[256];
va_start(ap,fmt);
vsprintf(str,fmt,ap);
UART0_SendStr(str);
va_end(ap);
}
6.测试程序及结果
#include "UART.h"
int Main(void)
{
UART0_Port_Init(115200);
UART0_Printf("Hello FL2440!\n");
while(1){
;
}
return 0;
}