(9)串口通信详情

11 篇文章 0 订阅

一、背景
1、介绍
通用异步收发器简称 UART,即 UNIVERSAL ASYNCHRONOUS RECEIVER AND TRANSMITTER,它用来传输串行数据。发送数据时,CPU 将并行数据写入 UART,UART 按照一定的格式在一根电线上串
行发出;接收数据时,UART 检测另一根电线的信号,将串行收集在缓冲区中,CPU 即可读取 UART获得这些数据。 在 S5PV210 中,UART 提供了 4 对独立的异步串口 I/O 端口,有 4 个独立的通道,每个通道可以工作于 DMA 模式或者中断模式。 其中, 通道 0 有 256byte 的的发送 FIFO 和 256byte 的接收FIFO,通道 1 有 64byte 的的发送 FIFO 和 64byte 的接收 FIFO, 而通道 2 和 3 只有 16byte 的的发送 FIFO和 16byte 的接收 FIFO。
uart结构图:
在这里插入图片描述

2、主要寄存器
GPA0CON 0xE020_0000
GPA1CON 0xE020_0020
UFCON0 0xE290_0008
UMCON0 0xE290_000C
ULCON0 0xE290_0000
UCON0 0xE290_0004
UBRDIV0 0xE290_0028
UDIVSLOT0 0xE290_002C
UTRSTAT0 0xE290_0010
UTXH0 0xE290_0020
URXH0 0xE290_0024

二、代码
1、start.s

/*
 *		代码:初始化uart输出输入一个字符
 *		日期:2020.7.13
 *		作者:glass love
 *
 */
 
 
.globl _start
_start:

/**********************关看门狗*******************************/
//通过查阅数据手册知道控制看门狗开关的寄存器是:
//Watchdog Timer Control Register (WTCON, R/W, Address =0xE2700000 ) 
//WTCON寄存器的bit[0]位是启用或禁用复位信号的看门狗定时器输出位
//1为启用,0为禁止
//因此只需要往WTCON中写入0x0即可
	ldr r0, =0x00000000
	ldr r1, =0xE2700000
	str r0, [r1]
	

	
/***********************设置栈****************************/
//IROM 里的固定代码设置的 sp 就等于 0xD003_7D80,
//所以我们设置栈一般就指向0xD003_7D80,以调用c函数
	ldr sp, =0xD0037D80
	
/**********************初始化时钟***********************/	
	bl clock_init
	
/*********初始化uart并输出输入一个字符************/
	bl main
	

//汇编死循环	
	b .

2、uart.c

#define rGPA0CON 		( *((volatile unsigned long *)0xE0200000) )		
#define rGPA1CON 		( *((volatile unsigned long *)0xE0200020) )

// UART相关寄存器
#define rULCON0 		( *((volatile unsigned long *)0xE2900000) )		
#define rUCON0 			( *((volatile unsigned long *)0xE2900004) )
#define rUFCON0 		( *((volatile unsigned long *)0xE2900008) )
#define rUMCON0 		( *((volatile unsigned long *)0xE290000C) )
#define rUTRSTAT0 		( *((volatile unsigned long *)0xE2900010) )
#define rUERSTAT0 		( *((volatile unsigned long *)0xE2900014) )
#define rUFSTAT0 		( *((volatile unsigned long *)0xE2900018) )
#define rUMSTAT0 		( *((volatile unsigned long *)0xE290001C) )
#define rUTXH0 			( *((volatile unsigned long *)0xE2900020) )
#define rURXH0 			( *((volatile unsigned long *)0xE2900024) )
#define rUBRDIV0 		( *((volatile unsigned long *)0xE2900028) )
#define rUDIVSLOT0 		( *((volatile unsigned long *)0xE290002C) )
#define rUINTP 			( *((volatile unsigned long *)0xE2900030) )
#define rUINTSP 		( *((volatile unsigned long *)0xE2900034) )
#define rUINTM 			( *((volatile unsigned long *)0xE2900038) )


#define			UART_UBRDIV_VAL		0x23
#define			UART_UDIVSLOT_VAL	0x0888

void uart_init(void)
{
	//初始化GPIO引脚,配置RX和TX功能
	rGPA0CON = 0x22222222;
	rGPA1CON = 0x2222;
	
	//设置数据格式
	//禁用FIFO
	rUFCON0 = 0x0;
	
	//禁用流控
	rUMCON0 = 0x0;
	
	// 数据位:8, 无校验, 停止位: 1
	rULCON0 = 0x3;
		
	//时钟:PCLK,禁止中断
	rUCON0 = 0x5;
	//设置波特率
	rUBRDIV0 = UART_UBRDIV_VAL;
	rUDIVSLOT0 = UART_UDIVSLOT_VAL;
	
}

void putch(char c)
{
	// 如果TX满,等待
	while (!(rUTRSTAT0 & (1<<2)));
	// 写数据
	rUTXH0 = c; 
	
	
}

char getch(void)
{
	// 如果RX 空,等待
	while (!(rUTRSTAT0 & (1<<0)));
	// 取数据
	return rURXH0;

	
}

3、main.c

void uart_init(void);

void main(void)
{
	//UART初始化
	uart_init();
	
	while(1)
	{
		char c;
		//接收一个字符
		c = getch();
		
		//发送一个字符
		putch(c+1);
		
	}
}

4、Makefile

uart_init: start.o clock.o uart.o main.o
	arm-linux-ld -Ttext 0x20000000 -o uart_init.elf $^                 
	arm-linux-objcopy -O binary uart_init.elf uart_init.bin			  
	arm-linux-objdump -D uart_init.elf > uart_init_elf.dis   		  
	gcc mkv210_image.c -o mk210              		  
	./mk210 uart_init.bin 210.bin 						  
	
%.o : %.S
	arm-linux-gcc -o $@ $< -c -nostdlib

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

clear:
	rm *.o *.elf *.bin *.dis mk210 -f

5、clock.S
clock.S较上一节没有改变。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值