嵌入式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结构图如下:

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

2、电路原理图查阅

查阅smart210底板电路原理图UART部分:

S5PV210本身总共有4个串口,UART0和UART3已经经过RS232电平转换,分别对应于COM0和COM3,通过附带的交叉串口线和PC互相通讯。

3、查阅核心板电路图

查阅核心板电路原理图UART相关部分,查找UART对应的GPIO引脚

UART 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)) 1

UBRDIV0的值取DIV_VAL整数部分

UDIVSLOT0的值通过DIV_VAL的小数部分乘以16得到的整数部分,通过查表得到:

三、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_VAL0x1

void 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,无校验,停止位: 1

ULCON0 = 0x3;

// 时钟:PCLK,禁止中断,轮询UART发送、接收

UCON0  = 0x5;

// 禁止fifo

UFCON0 = 0x0;

// 无流控

UMCON0 = 0x0;

// 3 设置波特率115200

UBRDIV0 = 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//包含当前inlcude

export 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、初始化串口COM0

void uart_init(void)

{

// 1 配置引脚用于RX/TX功能的GPIO寄存器

GPA0CON = 0x22;

// 2 设置数据格式等

// 数据位:8,无校验,停止位: 1

ULCON0 = 0x3;

// 时钟:PCLK,禁止中断,轮询UART发送、接收

UCON0  = 0x5;

// 禁止fifo

UFCON0 = 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\n",str);

printf("Today is %d-%d-%d\n",year,month,day);

while (1)

{

printf("please enter two number: \n");

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

printf("\n");

printf("the sum is: %d\n", a+b);

}

}

6、start.S

.global _start

_start:

bl uart_printf

.end

BL0(iROM)阶段已经关闭了看门狗、打开了icache、设置好了SVC栈、系统时钟等

工程源代码请查看附件

linux编译运行uart,嵌入式Linux裸机开发(七)——UART串口通信相关推荐

  1. 嵌入式linux编译环境搭建,嵌入式Linux开发环境搭建

    整理下嵌入式Linux开发环境搭建过程笔记. 一.制作u-boot.bin文件: tar xjf u-boot-1.1.6.tar.bz2 cd u-boot-1.1.6 patch -p1 < ...

  2. 嵌入式linux的运行过程,嵌入式linux的启动流程--详解

    开门见山: 1.嵌入式linux启动第一步----Boot Loader Boot Loader在这里我就不细说了,详细分析起来的话有很多内容,网上也有很多讲解很详细的文章.这段小程序中我们可以初始化 ...

  3. 嵌入式linux编译环境搭建,嵌入式Linux之旅——环境搭建篇之交叉编译工具的安装...

    在正式开始学习裸机程序的编写之前,我们还需要安装一下交叉编译工具.何为交叉编译工具?其实就是在x86的ubuntu主机上编译程序,并且可以运行在arm环境的编译工具.而gcc是本地编译工具,这个在我们 ...

  4. linux编译运行build.sh,linux下libwebsockets编译及实例

    最近想自己搭建一个webscoket协议的服务器,打算用libwebsockts这个库. 下载代码编译. 编写一个shell脚本 #!/bin/sh # wget http://git.warmcat ...

  5. linux内核培训广州,嵌入式Linux驱动开发高级培训班-华清远见嵌入式培训中心

    课程目标 本课程以案例教学为主,系统地介绍Linux下有关FrameBuffer.MMC卡.USB设备的驱动程序开发.参加本课程学习的学员,因为具备了Linux设备驱动开发基础,所以本课程针对性较强, ...

  6. linux 直流电机驱动设计,嵌入式Linux直流电机驱动.PPT

    嵌入式Linux直流电机驱动.PPT 嵌入式Linux直流电机驱动实验 开发平台中直流电机驱动的实现 S3C2410芯片自带定时器,所以控制部分省去了三角波产生电路.脉冲调制电路和PWM信号延迟及信号 ...

  7. 嵌入式linux的发展历程,嵌入式Linux论文(历史发展分类及应用)

    嵌入式Linux 一.嵌入式Linux简介 1.1 嵌入式Linux历史 随着社会的发展,信息化技术的成熟和数字化产品的普及,让以计算机技术.芯片技术和软件技术为核心的嵌入式系统再度成为当前研究和应用 ...

  8. 安卓开发板之串口通信,通过modbus Rtu协议控制下位机

    安卓开发板之串口通信,通过modbus Rtu协议控制下位机 1.环境准备 2.编写串口操作核心类 3.编写测试类 前言:因为公司最近有个人脸识别门禁的项目,这个项目主要业务是实现远程人脸注册,管理员 ...

  9. 嵌入式STM32入门之STM32基础串口通信

    STM32基础串口通信 一.前言 二.串口协议 (1)浅谈设备通信方式 (2)具体串口协议 (3)STM32的串口通信 (4)RS-232通信协议 (5)USB To TTL(CH340) 5.1 C ...

最新文章

  1. 'yii\base\InvalidRouteException' with message 'Unable to resolve the request site/error.'
  2. MSP430学习笔记
  3. 使用外部表关联MySQL数据到Oracle
  4. 日常运维管理技巧十七(Nethogs进程流量监控工具)(转载)
  5. 把字符串里的整数倒叙一个一个打印出来
  6. 链表题目汇总(python3)
  7. Java学习之SpringBoot整合SSM Demo
  8. flask html 路径,【Python】Flask 怎样获取当前页面的相对路径
  9. 详解JavaScript数组过滤相同元素的5种方法
  10. 冈萨雷斯图像处理Matlab函数汇总
  11. PPP协议基础与工作流程
  12. gitignore文件的几种写法,Git忽略文件规则的配置方法
  13. [译]直观理解信息论
  14. 【视频直播篇七】Aliplayer的使用
  15. U盘无法格式化解决方法
  16. Android MeasureSpec理解
  17. 【VTM10.0】量化之RDOQ技术
  18. 常见前端九十道面试题及答案-韩烨
  19. 深入解析 Apache BookKeeper 系列:第四篇—背压
  20. CSS教程--CSS字体

热门文章

  1. 如何优雅的抢红包 老司机给你传授秘技
  2. Nerwo(原npss 奶瓶)邀请链接
  3. C语言学习(五)——指针
  4. 编写了个videobuf-contig.c以获得物理上连续的大的内存(DMA)
  5. 科创人·用友网络刘剑锋:企业服务云生态尚处建设阶段,大团队管理核心是凝聚共识
  6. (转载)Knuth-Morris-Pratt算法(简称KMP)学习
  7. 传统的获客渠道方式对比包获客,你更认可哪一种?
  8. 微信小程序之城市切换
  9. mod_jk 内部结构
  10. chrome浏览器安装插件,提示程序包无效,解决方案