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

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:

#define    GPA0CON    ( *((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_VAL    35

#define     UART_UDIVSLOT_VAL    0x1

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栈、系统时钟等

工程源代码请查看附件

时间: 2024-10-12 05:09:39

嵌入式Linux裸机开发(七)——UART串口通信的相关文章

嵌入式Linux裸机开发(十三)——I2C通信

嵌入式Linux裸机开发(十三)--I2C通信 一.IIC协议 1.IIC总线简介 I2C(Inter-Integrated Circuit)总线是一种由PHILIPS公司开发的两线式串行总线,用于连接微控制器及其外围设备.I2C总线是一种串行数据总线,只有二根信号线,一根是双向的数据线SDA,另一根是时钟线SCL.在 I2C总线上传送的一个数据字节由八位组成.总线对每次传送的字节数没有限制,但每个字节后必须跟一位应答位. IIC总线是一种串行总线,用于连接微控制器及其外围设备,具有以下特点:

嵌入式Linux裸机开发(九)——S5PV210定时器

嵌入式Linux裸机开发(九)--S5PV210定时器 S5PV210内部一共有四类定时器. 一.PWM定时器 1.PWM定时简介 S5PV210内部共有5个32bit的PWM定时器.PWM定时器可以生成内部中断.PWM定时器0.1.2.3具有PWM功能,可以驱动外部I/O信号.PWM定时器4是一个无外部引脚的内部定时器.PWM 定时器使用 PCLK_PSYS 作为时钟源. 每个定时器有一个由定时器时钟驱动的32位递减计数器.递减计数器的初始值是由TCNTBn自动装载而获得的.如果递减计数器减到

嵌入式Linux裸机开发(十五)——LCD

嵌入式Linux裸机开发(十五)--LCD 一.LCD简介 LCD(Liquid Crystal Display)是液晶显示器简称.LCD的构造是在两片平行的玻璃基板当中放置液晶盒,下基板玻璃上设置TFT(薄膜晶体管),上基板玻璃上设置彩色滤光片,通过TFT上的信号与电压改变来控制液晶分子的转动方向,从而达到控制每个像素点偏振光出射与否而达到显示目的. 1.LCD类型 按照背光源的不同,LCD可以分为CCFL和LED两种. A.CCFL 指用CCFL(冷阴极荧光灯管)作为背光光源的液晶显示器(L

Win10 IoT C#开发 4 - UART 串口通信

原文:Win10 IoT C#开发 4 - UART 串口通信 Windows 10 IoT Core 是微软针对物联网市场的一个重要产品,既可以开发设备UI与用户交互式操作,又可以控制GPIO等接口,使得原来嵌入式繁琐的开发变得简单.通过Remote Debug功能可以进行断点追踪调试.C#语言本身也有很好的用户基础,相信Win10 IoT 不远的将来会火起来.上个月帮朋友解决了关于Win10 IoT 的一些技术问题,当前也有很多公司在尝试采用Win10 IoT进行开发,可能也会遇到这些问题,

嵌入式Linux裸机开发(八)——S5PV210中断处理流程

嵌入式Linux裸机开发(八)--S5PV210中断处理流程 中断是一个过程,是CPU在执行当前程序的过程中因硬件或软件的原因插入了另一段程序运行的过程.因硬件原因引起的中断过程的出现是不可预测的,即随机的,而软中断是事先安排的.引起中断的信号源称之为中断源.根据中断源的来源将中断分为外部中断和内部中断.中断源来自SoC内部(内部外设)的中断称为内部中断.中断源来自SoC外部,通过中断对应的GPIO引脚产生的中断称为外部中断.中断有四种状态: Inactive(不激活):没有被激活或挂起的中断 

嵌入式Linux裸机开发(十四)——ADC

嵌入式Linux裸机开发(十四)--ADC 一.AD转换简介 AD转换就是模数转换,就是把模拟信号转换成数字信号.A/D转换器是用来通过一定的电路将模拟量转变为数字量.模拟量可以是电压.电流等电信号,也可以是压力.温度.湿度.位移.声音等非电信号.在A/D转换前,输入到A/D转换器的输入信号必须经各种传感器把各种物理量转换成电压信号.A/D转换后,输出的数字信号可以有8位.10位.12位.14位和16位等. 二.ADC控制器 ADC控制器时钟: 时钟源为PCLK_PSYS,经过一次分频后得到AD

嵌入式Linux裸机开发(六)——S5PV210时钟系统

嵌入式Linux裸机开发(六)--S5PV210时钟系统 一.时钟系统简介 外设工作需要一定频率的时钟,这些时钟都由系统时钟提供.系统时钟一般由外部低频24MHZ晶体振荡器通过锁相环电路PLL倍频产生.通过外部的低频晶体振荡器产生系统时钟不仅可以减少干扰还可以降低成本.外设的工作频率越高,功耗越高,越不稳定.通过关闭外设的时钟可以关闭外设. 二.时钟域 S5PV210 中包含 3 大类时钟 domain, 分别是主系统时钟 domain (简称 MSYS).显示相关的时钟 domain (DSY

嵌入式Linux裸机开发(十二)——iNand简介

嵌入式Linux裸机开发(十二)--iNand简介 一.iNand简介 iNand是SanDisk公司研发的存储芯片,可以看成SD卡或MMC卡芯片化. iNand是SanDisk公司符合eMMC协议的芯片系列名称,内部采用MLC存储颗粒.iNand接口电路设计复杂,功能完善,提供eMMC接口协议,与SoC的eMMC控制器配对通信. 相对MLC NandFlash,iNAND有以下优点: 1.提高性能 A.减少SOC的工作量,节约SOC资源. 如果使用MLC做存储,SOC要参与FLASH的坏块管理

嵌入式Linux裸机开发(十)——SD卡启动

嵌入式Linux裸机开发(十)--SD卡启动 存储设备分类: 磁存储设备:软盘.硬盘.光盘.CD.磁带 Flash:NandFlash.NorFlash 缺点:时序复杂,无坏块处理机制,接口不统一 NandFlash:MLC(可靠性差,容量大).SLC(可靠性高.容量小) 扩展卡式Flash:SD卡.MMC卡.MicroSD(TF卡) 内部为NnadFlash存储颗粒,外部封装了接口,接口标准统一.通用. 缺点:频繁使用导致卡槽接触不可靠 iNand.MoviNand.eSSD: 内部为Nand