嵌入式 linux 串口,嵌入式Linux裸机开发(七)——UART串口通信

嵌入式Linux裸机开发(七)——UART串口通信

一、UART串口通信简介通用异步收发器简称UART,即UNIVERSAL ASYNCHRONOUS RECEIVER AND TRANSMITTER, 它用来传输串行数据。发送数据时, CPU 将并行数据写入UART,UAR按照一定的格式在一根电线上串 行发出;接收数据时, UART检测另一根电线的信号,将串行收集在缓冲区中, CPU 即可读取 UART 获得这些数据。 在 S5PV210中, UART提供了 4 对独立的异步串口I/O端口,有4个独立的通道,每个通道可以工作于DMA模式或者中断模式。其中,通道0有 256byte 的的发送FIFO和 256byte 的接收FIFO,通道1有64byte 的的发送FIFO和64byte的接收FIFO,而通道 2和3只有16byte 的的发送FIFO。UART使用标准的TTL/CMCOS 逻辑电平来表示数据,为了增强数据抗干扰能力和提高传输长度,通常将TTL/CMOS逻辑电平转换为 RS-232 逻辑电平。

二、S5PV210串口通信接口

1、S5PV210 UART接口S5PV210的UART结构图如下:3f288ee285423cc6e29fa526842ca321.pngUART串口控制器包含发送器和接收器两部分,发送器负责SoC向外部发送信息,接收器负责从外部接收信息到SoC。发送器由发送缓冲区和发送移位器构成,将发送信息进行ascii编码,将一帧数据写到发送缓冲区,发送移位器将会自动从发送缓冲区中取出一帧数据,自动移位,发送到TX。接收器由接收缓冲区和接收移位器构成,有信息需要接收时,接收移位器将收到的二进制数保存到接收缓冲区,收到一帧数据后发送一个中断给CPU,通知CPU读取接收缓冲区的数据。串口控制器的波特率发生器用于产生串口发送、接收的时钟频率,源时钟是APB总线时钟。

2、电路原理图查阅查阅smart210底板电路原理图UART部分:S5PV210本身总共有4个串口,UART0和UART3已经经过RS232电平转换,分别对应于COM0和COM3,通过附带的交叉串口线和PC互相通讯。3f288ee285423cc6e29fa526842ca321.png3、查阅核心板电路图查阅核心板电路原理图UART相关部分,查找UART对应的GPIO引脚3f288ee285423cc6e29fa526842ca321.pngUART COM0接口对应的GPIO引脚为GPA0

4、相关寄存器GPA0CON(0xE0200000):GPIO引脚控制寄存器 设置为0x22,打开COM0收发ULCON0(0xE290_0000):奇偶校验位、数据位、停止位UCON0(0xE290_0004):时钟源选择,模式选择UFCON0(0xE2900008):FIFO模式UMCON0(0xE290000C):流控制UTXH0(0xE2900020):发送寄存器URXH0(0xE2900024):接收寄存器UBRDIV0(0xE2900028):波特率设置UDIVSLOT0(0xE290002C):波特率设置波特率设置:DIV_VAL = (PCLK / (bps x 16))1或DIV_VAL = (SCLK_UART / (bps x 16)) 1UBRDIV0的值取DIV_VAL整数部分UDIVSLOT0的值通过DIV_VAL的小数部分乘以16得到的整数部分,通过查表得到:3f288ee285423cc6e29fa526842ca321.png

三、UART串口通信代码实践uart.c:#defineGPA0CON( *((volatile unsigned long *)0xE0200000) )#define    ULCON0( *((volatile unsigned long *)0xE2900000)#define    UCON0( *((volatile unsigned long *)0xE2900004) )#define    UFCON0( *((volatile unsigned long *)0xE2900008) )#define    UMCON0( *((volatile unsigned long *)0xE290000C) )#define    UTRSTAT0( *((volatile unsigned long *)0xE2900010) )#define    UERSTAT0( *((volatile unsigned long *)0xE2900014) )#define    UFSTAT0( *((volatile unsigned long *)0xE2900018) )#define     UMSTAT0( *((volatile unsigned long *)0xE290001C) )#define     UTXH0( *((volatile unsigned long *)0xE2900020) )#define     URXH0( *((volatile unsigned long *)0xE2900024) )#define     UBRDIV0( *((volatile unsigned long *)0xE2900028) )#define     UDIVSLOT0( *((volatile unsigned long *)0xE290002C) )#define     UINTP0( *((volatile unsigned long *)0xE2900030) )#define     UINTSP0( *((volatile unsigned long *)0xE2900034) )#define     UINTM0( *((volatile unsigned long *)0xE2900038) )#define     UART_UBRDIV_VAL35#define     UART_UDIVSLOT_VAL0x1void uart_init(void);void uart_putc(char c);char uart_getc(void);void uart_sendc();void uart_init(void){// 1 配置引脚用于RX/TX功能的GPIO寄存器GPA0CON = 0x22;// 2 设置数据格式等// 数据位:8,无校验,停止位: 1ULCON0 = 0x3;// 时钟:PCLK,禁止中断,轮询UART发送、接收UCON0  = 0x5;// 禁止fifoUFCON0 = 0x0;// 无流控UMCON0 = 0x0;

// 3 设置波特率115200UBRDIV0 = UART_UBRDIV_VAL;UDIVSLOT0 = UART_UDIVSLOT_VAL;

}// 接收一个字符char uart_getc(void){// 如果URXH0空,等待while (!(UTRSTAT0 & (1<<0)));// 取数据return URXH0;}// 发送一个字符void uart_putc(char c){// 如果UTXH0满,等待while (!(UTRSTAT0 & (1<<1)));// 写数据UTXH0 = c;}void uart_sendc(void){uart_init();while(1){uart_putc('a');}}

四、printf移植将printf函数与串口COM0绑定,输出到COM0。printf函数内部调用vsprintf实现对字符串格式化,调用putc函数操作硬件设备从串口输出。移植流程:1、修改工程Makefile头文件需要添加下面的内容OBJS += lib/lib.a//增加目标文件CPPFLAGS += -nostdlib -nostdinc//不使用标准库,不包含标准库头文件目录CFLAGS += -Wall -O2 -fno-builtin -I$(CURDIR)/include//包含当前inlcudeexport CROSS_COMPILER CC CPPFLAGS CFLAGS LDFLAGS//导出变量lib/lib.a:make -C ./lib//编译lib目录2、在使用printf的文件uart.c中添加头文件#include“stdio.h”3、编写putc、getc函数printf内部通过调用putc函数实现输出到标准输出,因此需要编写同名的putc函数,重定向到串口COM0输出。// 发送一个字符void putc(unsigned char c){// 如果UTXH0满,等待while (!(UTRSTAT0 & (1<<1)));// 写数据UTXH0 = c;}// 接收一个字符unsigned char getc(void){// 如果URXH0空,等待while (!(UTRSTAT0 & (1<<0)));// 取数据return URXH0;}4、初始化串口COM0void uart_init(void){// 1 配置引脚用于RX/TX功能的GPIO寄存器GPA0CON = 0x22;// 2 设置数据格式等// 数据位:8,无校验,停止位: 1ULCON0 = 0x3;// 时钟:PCLK,禁止中断,轮询UART发送、接收UCON0  = 0x5;// 禁止fifoUFCON0 = 0x0;// 无流控UMCON0 = 0x0;

// 3 设置波特率UBRDIV0 = UART_UBRDIV_VAL;UDIVSLOT0 = UART_UDIVSLOT_VAL;

}5、编写测试函数void uart_printf(void){char *str = "hello world";int a = 0;int b = 0;int year = 2016;int month = 5;int day = 2;

uart_init();printf("%s

",str);printf("Today is %d-%d-%d

",year,month,day);while (1){printf("please enter two number:

");scanf("%d %d", &a, &b);printf("

");printf("the sum is: %d

", a+b);}}6、start.S.global _start_start:bl uart_printf.endBL0(iROM)阶段已经关闭了看门狗、打开了icache、设置好了SVC栈、系统时钟等工程源代码请查看附件

本文出自 “生命不息,奋斗不止” 博客,请务必保留此出处http://9291927.blog.51cto.com/9281927/1787067

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值