s5pv210——串口(UART)通信实战

以下内容源于朱有鹏嵌入式课程的学习,如有侵权,请告知删除。

参考博客http://www.cnblogs.com/biaohc/p/6351253.html

 

一、主要代码总览

void main(void)
{
	uart_init();
	
	while(1)
	{
		uart_putc('a');
		delay();
	}
}
#define GPA0CON		0xE0200000
#define UCON0 		0xE2900004
#define ULCON0 		0xE2900000
#define UMCON0 		0xE290000C
#define UFCON0 		0xE2900008
#define UBRDIV0 	0xE2900028
#define UDIVSLOT0	0xE290002C
#define UTRSTAT0	0xE2900010
#define UTXH0		0xE2900020	
#define URXH0		0xE2900024	

#define rGPA0CON	(*(volatile unsigned int *)GPA0CON)
#define rUCON0		(*(volatile unsigned int *)UCON0)
#define rULCON0		(*(volatile unsigned int *)ULCON0)
#define rUMCON0		(*(volatile unsigned int *)UMCON0)
#define rUFCON0		(*(volatile unsigned int *)UFCON0)
#define rUBRDIV0	(*(volatile unsigned int *)UBRDIV0)
#define rUDIVSLOT0	(*(volatile unsigned int *)UDIVSLOT0)
#define rUTRSTAT0		(*(volatile unsigned int *)UTRSTAT0)
#define rUTXH0		(*(volatile unsigned int *)UTXH0)
#define rURXH0		(*(volatile unsigned int *)URXH0)

// 串口初始化程序
void uart_init(void)
{
	// 初始化Tx Rx对应的GPIO引脚
	rGPA0CON &= ~(0xff<<0);			// 把寄存器的bit0~7全部清零
	rGPA0CON |= 0x00000022;			// 0b0010, Rx Tx
	
	// 几个关键寄存器的设置
	rULCON0 = 0x3;//0校验位、8数据位、1停止位
	rUCON0 = 0x5;//发送和接收都是polling mode
	rUMCON0 = 0;//禁止modem、afc
	rUFCON0 = 0;//禁止FIFO模式
	
	// 波特率设置	DIV_VAL = (PCLK / (bps x 16))-1
	// PCLK_PSYS用66MHz算		余数0.8
	//rUBRDIV0 = 34;	
	//rUDIVSLOT0 = 0xdfdd;
	
	// PCLK_PSYS用66.7MHz算		余数0.18
	// DIV_VAL = (66700000/(115200*16)-1) = 35.18
	rUBRDIV0 = 35;
	// (rUDIVSLOT中的1的个数)/16=上一步计算的余数=0.18
	// (rUDIVSLOT中的1的个数 = 16*0.18= 2.88 = 3
	rUDIVSLOT0 = 0x0888;		// 3个1,查官方推荐表得到这个数字
}


// 串口发送程序,发送一个字节
void uart_putc(char c)
{                  	
	// 串口发送一个字符,其实就是把一个字节丢到发送缓冲区中去
	// 因为串口控制器发送1个字节的速度远远低于CPU的速度,所以CPU发送1个字节前必须
	// 确认串口控制器当前缓冲区是空的(意思就是串口已经发完了上一个字节)
	// 如果缓冲区非空则位为0,此时应该循环,直到位为1
	while (!(rUTRSTAT0 & (1<<1)));//缓冲区为空时(即状态寄存器的第2bit为1),说明可以发送该字节到缓冲区了
	rUTXH0 = c;
}

// 串口接收程序,轮询方式,接收一个字节
char uart_getc(void)
{
	while (!(rUTRSTAT0 & (1<<0)));
	return (rURXH0 & 0xff);//为什么要与,bit0~bit3????????
}

 

二、流程分析

 

1、整个串口通信相关程序包含2部分

  • uart_init负责初始化串口;
  • uart_putc负责发送一个字节;

2、串口的初始化

(1)初始化串口的Tx和Rx引脚所对应的GPIO。

 

  • GPA0CON(0xE0200000)的 bit[3:0] = 0b0010,bit[7:4] = 0b0010,即把引脚设置为UART_?(这里为0)的作用状态。

 

s5pv210——串口(UART)通信实战_第1张图片

(2)初始化关键寄存器:ULCON0、UCON0、UMCON0、UFCON0、UBRDIV0、UDIVSLOT0;

A、ULCONn寄存器

  • 红外模式:0:普通模式、1:红外模式;
  • 奇偶校验模式:0:无、1:奇数、2:偶数;
  • 终止位:0:1位,1:2位;
  • 字长:5-8bit。

 

s5pv210——串口(UART)通信实战_第2张图片

B、UCONn寄存器

  • 时钟选择:0:PCLK_PSYS,1:SCLK_UART,我们设置为0;
  • 发送模式:轮询/中断;
  • 接收模式:轮询/中断;

 

s5pv210——串口(UART)通信实战_第3张图片

s5pv210——串口(UART)通信实战_第4张图片

s5pv210——串口(UART)通信实战_第5张图片

C、UMCONn寄存器:禁止modem、afc

s5pv210——串口(UART)通信实战_第6张图片

D、UFCONn寄存器:禁止FIFO模式

s5pv210——串口(UART)通信实战_第7张图片

s5pv210——串口(UART)通信实战_第8张图片

E、UTRSTATn寄存器,是状态寄存器

  • Transmitter empty: 移位器和发送缓冲寄存器是否有可用数据发送,0:非空,1:空;
  • Transmitter buffer empty: 发送缓冲寄存器,0:非空,1:空;
  • Recieve buffer empty: 接收缓冲寄存器,0:非空,1:空。

s5pv210——串口(UART)通信实战_第9张图片

 

F、UBRDIV0和UDIVSLOT0和波特率设置有关

s5pv210——串口(UART)通信实战_第10张图片

s5pv210——串口(UART)通信实战_第11张图片

s5pv210——串口(UART)通信实战_第12张图片

波特率设置方法:DIV_VAL = (PCLK / (bps x 16)) −1。

如66.7MHz/(115200*16) = 36.187,

则UBRDIV n中的值就是36-1=35,

0.187*16=2.992 ,则UDIVSLOTn中1的个数为3个,则UDIVSLOTn寄存器的值根据上表,应该写入0x0888。

 

G、UTXHn寄存器、URXHn寄存器

s5pv210——串口(UART)通信实战_第13张图片

 

你可能感兴趣的:(ARM裸机)