一、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芯片电压转换后成为串口引脚RS232RXD0。
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 != '