九.ARM裸机学习之串口通信详解2(S5PV210串行通信编程详解)

1、整个程序流程分析
(1)整个串口通信相关程序包含2部分:uart_init负责初始化串口,uart_putc负责发送一个字节,uart_gec负责接收一个字节。
2、串口控制器初始化关键步骤
(1)初始化串口的Tx和Rx引脚所对应的GPIO(查原理图可知Rx和Rx分别对应GPA0_1和GPA0_0)
(2)GPA0CON(0xE0200000),bit[3:0] = 0b0010 bit[7:4] = 0b0010
(3)初始化这几个关键寄存器UCON0 ULCON0 UMCON0 UFCON0 UBRDIV0 UDIVSLOT0
3、主要的几个寄存器
(1)ULCON0 = 0x3 // 0校验位、8数据位、1停止位
(2)UCON = 0x5 // 发送和接收都是polling mode
(3)UMCON0 = 0x0 // 禁止modem、afc
(4)UFCON0 = 0x0 // 禁止FIFO模式
(5)UBRDIV0和UDIVSLOT0和波特率有关,要根据公式去算的
4、在C源文件中定义访问寄存器的宏
定义好了访问寄存器的宏之后,将来写代码时直接使用即可。
5、串口Tx、Rx对应的GPIO的初始化
给GPA0CON的相应bit位赋值为相应值,用C语言位操作来完成。
6、UCON、ULCON、UMCON、UFCON等主要控制寄存器
依据上节中分析的值进行依次设置即可。
7、波特率的计算和设置
(1)第一步,用PCLK_PSYS和目标波特率去计算DIV_VAL: DIV_VAL = (PCLK / (bps x 16))-1
(2)第二步,UBRDIV0寄存器中写入DIV_VAL的整数部分
(3)第三步,用小数部分*16得到1个个数,查表得uBDIVSLOT0寄存器的设置值
1.7.8.4、串口发送和接收函数的编写
(1)写发送函数,主要发送前要用while循环等待发送缓冲区为空才能发送。
发送接收状态寄存器:UTRSTAT0
uart.c:
/*
   包含串口初始化程序,串口发送程序,串口接收程序
*/

#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<<1);//把寄存器的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)));
	rUTXH0=c;
	
	
}

//串口接收程序,发送一个字节
char uart_getc(void)
{
	while (!(rUTRSTAT0 & (1<<0)));
	return (rURXH0 & 0x0f);
	
}

Makefile:
uart.bin: start.o led.o clock.o uart.o main.o
	arm-linux-ld -Ttext 0x0 -o uart.elf $^
	arm-linux-objcopy -O binary uart.elf uart.bin
	arm-linux-objdump -D uart.elf > uart_elf.dis
	gcc mkv210_image.c -o mkx210
	./mkx210 uart.bin 210.bin
	
%.o : %.S
	arm-linux-gcc -o $@ $< -c -nostdlib

%.o : %.c
	arm-linux-gcc -o $@ $< -c -nostdlib

clean:
	rm *.o *.elf *.bin *.dis mkx210 -f



  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值