串口驱动设计(基于S3C6410)

时间:2021-04-21 12:20:41

串口通讯

串口充当的角色有两个,一个是数据传输,还有一个就是充当控制台。串口通讯分为同步和异步,我们通常使用的是异步串口。通讯时,双方先约定好数据帧的格式,即波特率,数据位,停止位,奇偶校验位等。我们通常使用的是RS232的9帧串口,其中,最重要的是2,3,5脚。
2:RXD接收数据
3:TXD发送数据
5:GND接地
接下来,我们开始进行串口的初始化。在此使用的开发板是飞凌S3C6410。初始化内容主要分为以下四个方面,引脚设置,帧格式设置,工作模式设置,波特率设置。

引脚设置

串口驱动设计(基于S3C6410)
由核心板原理图上可找到RXD和TXD是通过GPA这个寄存器控制的,所以,在芯片手册中找到GPACON这个寄存器。
串口驱动设计(基于S3C6410)
由芯片手册可得,只要设置GPACON的0到3位和4到7位来分别设置RXD和TXD即可。这里很简单,只要如下设置

 GPACON &= ~0xff; /*先将低八位清零*/ 
GPACON |= 0x22;

设置数据格式

引入一个寄存器ULCON0,线控制寄存器,主要是设置数据格式。
串口驱动设计(基于S3C6410)
ULCON0寄存器低两位主要设置数据位个数,第二位设置停止位个数,校验位暂时不需要使用,其他位使用默认的值。

ULCON0 = 0b11;

设置工作模式

引用UCON0寄存器,只要设置这个寄存器中的0:3位,其中0:1位设置收模式,2:3位设置发模式,在这里都设置为polling mode,即轮询模式,也就是查询等待模式。
串口驱动设计(基于S3C6410)

UCON0 = 0b0101; 

设置波特率

这里引入两个寄存器UBRDIV0和UDIVDLOT0,可以从芯片手册中得到两个寄存器的值,串口的时钟是由PCLK来提供的,在时钟体系那节中明确写出PCLK被设置成66MHZ,波特率一般设置为115200,故UBRDIV0=PCLK/(BAUD*16)-1取整,而UDIVDLOT0则是对小数部分乘上16,取整后查表得出UDIVDLOT0的值,由于PCLK等于66MHZ,BAUD为115200,(66000000/(115200*16))-1=34.8,故UBRDIV0=34,0.8*16=12.8,12查表得UDIVDLOT0为0xDDDD。
串口驱动设计(基于S3C6410)
串口驱动设计(基于S3C6410)
至此,串口初始化程序已经完成,但是如何测试串口正常工作呢,这里需要加两个函数,接收字符和发送字符。

发送数据

引入UTRSTAT寄存器
串口驱动设计(基于S3C6410)
主要检查这个寄存器第1位是否为0,如果为0,表明前一次数据还没有发送完,如果等于1,则可以进行发送数据,在程序中用while循环,将字符送给UTXH0寄存器即可。

void putc(unsigned char ch)
{
while (!(UTRSTAT0 & (1<<2)));
UTXH0 = ch;
}

接收数据

这里还是使用UTRSTAT寄存器,使用第0位,第0位若为0,表明还没有接收到数据,为1表明接收到数据,当接收到数据的时候送到URXH0寄存器中进行返回。

unsigned char getc(void)
{
unsigned char ret;

while (!(UTRSTAT0 & (1<<0)));
// 取数据
ret = URXH0;

if ( (ret == 0x0d) || (ret == 0x0a) ) /*增加回显的功能,0x0d表示回车,0x0a表示换行*/
{
putc(0x0d);
putc(0x0a);
}
else
putc(ret);

return ret;
}

附上整体程序

#define GPACON      (*((volatile unsigned short *)0x7F008000))
#define ULCON0 (*((volatile unsigned long *)0x7F005000))
#define UCON0 (*((volatile unsigned long *)0x7F005004))
#define UTRSTAT0 (*((volatile unsigned long *)0x7F005010))
#define UBRDIV0 (*((volatile unsigned short *)0x7F005028))
#define UTXH0 (*((volatile unsigned char *)0x7F005020))
#define URXH0 (*((volatile unsigned char *)0x7F005024))
#define UDIVSLOT0 (*((volatile unsigned short *)0x7F00502C))

#define PCLK 66500000
#define BAUD 115200

void uart_init()
{
//1.配置引脚功能
GPACON &= ~0xff;
GPACON |= 0x22;

//2.1 设置数据格式
ULCON0 = 0b11;

//2.2 设置工作模式
UCON0 = 0b0101;

//3. 设置波特率
UBRDIV0 =(int)(PCLK/(BAUD*16)-1); //UBRDIV0保存该公式计算后的整数部分
UDIVSLOT0 = 0x0; //UDISLOT0=保存该公式计算后的小数部分*16
}



void putc(unsigned char ch)
{
while (!(UTRSTAT0 & (1<<2)));
UTXH0 = ch;
}



unsigned char getc(void)
{
unsigned char ret;

while (!(UTRSTAT0 & (1<<0)));
// 取数据
ret = URXH0;

if ( (ret == 0x0d) || (ret == 0x0a) )
{
putc(0x0d);
putc(0x0a);
}

else
putc(ret);

return ret;
}