1、S5PV210 串口通信详解1
1、S5PV210串口通信原理框图
peripheral BUS (外设总线) 与SOC连接
APB:给 peripheral BUS 提供时钟的总线
AHB
如何发送?
Transmit Buffer Register
Transmit Shifter 发送移位器
总线角度来讲,串口控制器是接在APB总线上的。对我们编程有影响的是:将来计算串口控制器的源时钟是以APB总线来计算的。
2、 Transmit 由发送缓冲区和发送移位器构成的,我们要发送信息时,首先要进行信息编码成二进制流。然后将一帧数据写入发送缓冲区,发送
移位器自动从发送缓冲区中读取一帧数据,然后自动移位。将其发送到TX通信线。
3、receiver由接收缓冲区和接收移位器构成。原理与发送相似。
4、串口有一个波特率发生器,作用还是产生串口发送和接收的时钟。波特率发生器的节拍来源:其实就是个时钟分频器,它的工作需要源时钟,在内部进行分频
得到目标时钟,再用目标时钟产生波特率(硬件自动)。
3、自动流控
流控线:发送数据流的控制
发的快收得慢的地方需要流控,确保数据收发非常准确,不会漏掉东西。
2、S5PV210 串口通信详解2
本来串口功能就是上部分讲过的,后来技术发展给串口叠加呢一些高级功能
1、FIFO模式及其作用
典型的串口设计,发送和接收缓冲区只有1字节,每次发送/接收只能处理1帧数据。这样在简单处理中没什么问题。
先进先出的一种数据结构,这里大的缓冲区叫FIFO 是因为这个缓冲区的工作方式类似于FIFO这种结构。
2、DMA模式及其作用
FIFO模式是一种轻量级的解决方案,DMA模式适合大量数据迸发的发送和接收时。
DMA本来是DSP中的一种技术
3、IrDA模式及其用法
1、IrDA其实就是红外,红外就是红外通信(电视机、空调遥控器就是红外通信的)。
红外编码原理:在一个时间段内判断红外线的有无表示 0和1
2、红外通信原理是发送方固定时间间隔向接收方发送红外信号(表示1和0),接收方每个固定时间间隔判断有无红外信号来接收0和1
3、分析可知,红外通信和串口通信非常像,因此x210的串口通信实现了红外发送和接收。
4、210某个串口支持IrDA模式,开启红外模式后,我们只徐亚向串口写数据,这些数据就会以红外光的方式发射出去,然后接收方接收这些数据即可解码得到我们的发送信息。
3、S5PV210 串口通信详解3
1、串口通信和中断的关系
发送方可以使用中断,也可以不使用中断。使用中断的工作情景是:发送方先设置 中断并绑定一个中断处理程序。然后发送方丢一帧数据给transmitter,transmitter发送海飞一段时间来发送这一帧数据。这段时间内发送方CPU可以去做别的事情。
不使用中断的工作情景是:发送方事先禁止TXD中断,这是CPU处于等待状态。
CPU如何知道transmitter发送完成? 原来有个状态寄存器,状态寄存器中有一个位:发送缓冲区空标志。发送完成后就会给标志位置位。
2、因为串口通信是异步的,异步的意思是发送方占主导权,也就是说发送方随时想法就能发
3、串口通信时钟设计
串口通信需要一个固定的波特率。
4、串口通信中时钟的设置 主要看寄存器的设置
7、串口通信实战编程
1、整个流程分析
新建文件main.c uart.c
bl main
void main()
{
uart_init();
uart_putc();
}
// 串口控制器的初始化
1、初始化串口的TX和RX引脚所对应的GPIO,引脚复用。
RX和TX分别 对应GPA0_0,GPA0_1
GPA0CON(0xE0200000), bit[3:0] = 0010 bit[7:4] = 0010
初始化关键寄存器 UCON0 ULCON0 UMCON0 UFCON0 UBRDIV0 UDIVSLOT0
ULCONn ULCON0, R/W, Address = 0xE290_0000
ULCONn = 0x03 // 0校验位 8数据位 1停止位
UCON0, R/W, Address = 0xE290_0004
Loop-back Mode 回环模式测试 内部自己发送自己接收
UCON0 = 0x05 // 发送和接收都是polling mode 轮询模式
UMCON0 UMCON0, R/W, Address = 0xE290_000C 禁止mode AFC
UFCON0 UFCON0, R/W, Address = 0xE290_0008 FIFO相关
UFCON0 = 0x0 // 禁止FIFO模式
UBRDIV0 UDIVSLOT0 和波特率有关,需要根据公式计算
#define GPA0CON 0xE0200000
#define UCON0 0xE290_0004
#define ULCON0 0xE290_0000
#define UMCON0 0xE290_000C
#define UFCON0 0xE290_0008
#define UBRDIV0 0xE290_0028
#define UDIVSLOT0 0xE290_002C
#define UTRSTAT0 0xE290_0010
#define UTXH0 0xE290_0020
#define URXH0 0xE290_0024
// 定义访问寄存器的宏
#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和TX
rGPA0CON &= ~(0xff<<0); //把bit0-7全部清零
rGPA0CON |= 0x00000022; //对应0b0010
rULCON0 = 0x03;
rUCON0 = 0x05;
rUMCON0 = 0;
rUFCON0 = 0;
// 波特率的设置 DIV_VAL = (PCLK / (bps x 16)) −1
// PCLK_PSYS用66MHz计算 余数0.8
//rUBRDIV0 = 34;
//rUDIVSLOT0 = 0xDFDD;
// PCLK_PSYS用66.7MHz计算 余数0.8
rUBRDIV0 = 36;
rUDIVSLOT0 = 0x0888;
}
void uart_putc(char c)
{
// 串口发送一个字符,其实就是把一个字节丢到发送缓冲区中
// 如果缓冲区非空则位为0,此时应该循环,直到位为1。
while(!(rUTRSTAT0 & (1<<2)));
rUTXH0 = c;
// 因为串口发送数据的速度,远远低于CPU发送速度,所以CPU
// 发送一个字节前,必须确保状态寄存器为空。
// 读状态寄存器,确认发送完成。UTRSTAT0, R, Address = 0xE290_0010
}
//串口接收程序
void uart_getc(void)
{
}
2、串口初始化部分 uart_init
8、uart stdio 的移植1
1、什么是stdio
标准输入输出:操作系统定义默认的输入输出通道
标准输入: 键盘
标准输出: 屏幕
嵌入式系统为什么要使用标准输入输出?
printf函数和scanf函数可以和底层输出/输入函数绑定。然后这两个函数就可以
和stdio绑定起来,也就是说我们直接调用printf函数输出,内容就会被标准输入输出。
我们这里使用的标准输入 输出 是 :串口
2、printf函数的工作原理
printf函数工作时实际调用了2个关键函数:一个是VSprintf函数(主要功能是格式化打印信息)
另一个就是真正的输出函数putc(操控标准输出的硬件,将信息发送出去)。
3、移植printf函数的三种思路
一般有三个途径获取printf的实现源码:最原本的来源就是ilinux内核中的printk。
8、uart stdio 的移植2
objs 用于定义变量
$ 引用变量
export 导出变量到全局,其实就是给子文件下的makefile 使用
C预处理器的flag,flag就是编译器可选的选项
INCDIR := shell pwd
-nostdlib -nostdinc -I$(INCDIR)/include(用于指定头文件目录)
CFLAGS := -Wall -O2 -fno-builtin
9、uart stdio 的移植3
1、在移植后的uart stdio 项目佛张添加link.lds链接脚本。指定链接地址
2、C语言的可变参数
va_start(args, fmt);
va_end(args, fmt);
fmt 字符串
printf("a = %d, b = %s.\n", a, p);
3、GCC可变参数及va_arg介绍
1、printf函数中首先使用了C语言可变参数va_start/va_arg/va_end;
2、补充练习
3、<> 标识系统自带头文件 ""自定义头文件
vsprintf - 左对齐 + 右对齐
10、串口实验烧录问题总结
1、USB下载的问题
USB下载时在win7 x64下,下载前面的小代码没问题,下载串口通信的小代码也没有问题,下载
stdio的移植就有问题了。有时候下载不懂,有时候下载但是不运行,有时候又正常下载运行。
2、SD卡烧录镜像
1、在linux 下烧录
2、在windows下烧录
注意以管理员方式运行
3、启动方式的设置
4、链接脚本的影响
5、bin文件大于16k怎么办?
通过USB下载,最多能下载96kB的bin,如果大于96KB,肯定SRAM放不下会出错。如果用SD卡启动,那么mkv210_image.c决定了bin文件最大不超过16KB.
在USB下载时,可以先下载一个210_USB.bin.
s5pv210串口通信笔记
最新推荐文章于 2021-03-05 17:08:35 发布