基于S5PV210的串口通信的实战
---参考朱有鹏ARM裸机课程
1、串口的程序的流程的分析过程
整个串口通信相关的程序包括2个部分:uart_init负责初始化串口
uart_putc负责发送一个字节的数据。
整个过程中我们需要编写的函数有三个函数:
(1)串口的初始化函数
uart_init(); //为什么我们需要编写这样的一个函数,因为每一个IO口基本都有引脚的复用的功能
(2)串口的发送程序,发送一个字节;
uart_putc(char x);
(3)串口的接收函数,轮询方式,接收一个字节。
char uart_getc();
2、串口控制器初始化关键步奏:
(1)初始化串口的Tx和Rx引脚对应的GPIO(引脚是复用的引脚)
查原理图可知:
GPA0_0 Rx
GPA0_1 Tx
GPA0CON() 0xE0200000 位的0-3 = 0010, 同理可得:bit4-7为0010
2、初始化关键寄存器
UCON0 / ULCON0
UMCON0 UFCON0
UBRDIV0
UDIVSLOT0
ULCON0 = 0x03 //无校验位,8位数据位
UCON0 = 0x05 //发送和接收都是polling mode
UMCON0 = 0x0 //禁止modem、afc
UFCON0 = 0x0 //禁止FIFO模式
(2)UBRDIV0和UDIVSLOT0和波特率有关,要根据公式去计算。
我们运用了PCLK_MSYS的时钟信号,在上面的时钟系统已经配置过了。
主要是66.7MHZ
DIV_VAL = (PCLK/(bps * 16)) - 1
= 66700000/115200 /16 -1 = 35.18 ==35
UDIVSLOT = 16 * 0.18 = 2.88 = 3
0x0888
3、如何编写发送函数
我们的CPU的速度要远远的比我们串口的速度要快。
所以可能CPU已经发送了10个数据,串口还没有反应过来。
所以我们需要的是:
我们需要判断,在我们前一帧已经发送完成之后,CPU才发送数据过来。
所以这里就需要使用到我们发送是否为空的标志符,
如果发送缓冲区有数据的情况下面,我们就不再发送数据过去。
以下是uart的驱动程序:
void uart_init(void)
{
//初始化Tx和Rx对应的IO口为串口的发送的方式,根据原理图来理解
rGPA0CON &= ~(0xff << 0); //把寄存器的bit0~7全部清零
rGPA0CON |= 0x00000022; //把Rx和T恤设置为UART的串口方式
//设置几个关键寄存器的设置
rULCON0 = 0x03;
rUCON0 = 0x5;
rUMCON0 = 0x0; //模式控制的
rUFCON0 = 0x0; //设置为FIFO的模式
//波特率的设置:
//DIV_VAL = (PCLK / (bps * 16) - 1)
//PCLK_PSYS用66MHZ算。 余数0.8
rUBRDIV0 = 35;
rUDIVSLOT0 = 0x0888; //3个1,这是查到官方推荐表得到的这个数字。
}
//串口发送程序,发送一个字节:
void uart_putc(char c)
{
//因为串口发送一个字节,其实就是把一个字节丢到发送缓冲区中去
//因为串口控制器发送一个字节的速度远远的低于CPU的速度
//所以CPU发送一个字节前必须确认串口控制器当前的缓冲区是不是空的
//如果缓冲区非空则位为0,此时应该循环,直到位为1
while(!(rUTRSTAT0 & (0x02)));
rUTXH0 = c;
}
//串口接收程序,轮询方式,接收一个字节
char uart_getc(void)
{
while(!(rUTRSTAT0 & (0x01)));
return (rURXH0 & 0x0f);
}