裸板之UART驱动
2014-04-07 15:06
120 查看
1、什么是UART?
UART就是通用异步收发器。这个异步怎么体现呢?因为它没有时钟。
UART有 3条线:TX、RX、GND。
这里没有时钟线,那怎么知道什么时候发送,接收数据呢?
比如我们要发送字母'A',它的16进制是0x41, 2进制为 0100,0001. 那怎么发送呢?
平时发送引脚为高电平,那么串口怎么通知PC端要发送数据了呢?
要发送时,把发送引脚拉低,并维持一断时间,多久呢,维持一位的时间。这位叫做起始位。
然后发送8位数据0100,0001(从高开始发送,即先发0),发送完后维持一位的高电平,这个就叫做停止位。
发送方:开始位--数据--停止位。
一开始为高电平,要发送时拉为低电平,通知要发送了,即开始位。
接收方:检测到低电平,知道要发送数据了。
这就是串口的协议。
每一位占多长时间(波特率);开始位、数据位、校验位、停止位各多少。
发送:把要发送的数据写到缓冲区(操作寄存器),硬件自动的一位一位发送。
接收:把数据一位一位存在缓冲区中。
2、进入代码分析
1)程序先从启动代码start.S开始运行,这个和以前的差不多,就不放上来了。
2)启动化,进入main()函数运行。
3)初始化串口
那我们就要将这个gpio设置成 串口功能,GPACON设置成 0010 为串口功能。
2》 UFCON0
这个是FIFO 控制寄存器,什么是FIFO呢?
FIFO就是这个64字节的缓冲区,发数据时可以一次性发64字节的数据全部放到这个缓冲区中,然后硬件会一位一位的取走。因为串口的发送是很慢的,如果不用这个缓冲区只能一位一位的发,等取走后才能发下一位。 UFSTAT0 是缓冲区的状态,0:5 表示有多少位数据,第6位表示满或不满。 (UFSTAT0
& 0x7f) == 0 就表缓冲区中示没有数据。
3)波特率设置
假设我们的系统时钟 PCLK=66.5MHZ,要得到的波特率baudrate=115200.怎么得到?
DIV_VAL = (PCLK / (bps x 16 ) ) −1 (公式1)
代进去算一下: DIV_VAL =(66.5*10^6/(115200*16))-1=35.008
DIV_VAL = UBRDIVn + (num of 1’s in UDIVSLOTn)/16 (公式2)
UBRDIVn =35 后面部分为小数, UDIVSLOTn算得为12.
UART就是通用异步收发器。这个异步怎么体现呢?因为它没有时钟。
UART有 3条线:TX、RX、GND。
这里没有时钟线,那怎么知道什么时候发送,接收数据呢?
比如我们要发送字母'A',它的16进制是0x41, 2进制为 0100,0001. 那怎么发送呢?
平时发送引脚为高电平,那么串口怎么通知PC端要发送数据了呢?
要发送时,把发送引脚拉低,并维持一断时间,多久呢,维持一位的时间。这位叫做起始位。
然后发送8位数据0100,0001(从高开始发送,即先发0),发送完后维持一位的高电平,这个就叫做停止位。
发送方:开始位--数据--停止位。
一开始为高电平,要发送时拉为低电平,通知要发送了,即开始位。
接收方:检测到低电平,知道要发送数据了。
这就是串口的协议。
每一位占多长时间(波特率);开始位、数据位、校验位、停止位各多少。
发送:把要发送的数据写到缓冲区(操作寄存器),硬件自动的一位一位发送。
接收:把数据一位一位存在缓冲区中。
2、进入代码分析
1)程序先从启动代码start.S开始运行,这个和以前的差不多,就不放上来了。
2)启动化,进入main()函数运行。
#include "uart.h" int main() { char c; init_uart(); /* 波特率,数据位,停止位... */ while (1) { c = getchar(); putchar(c+1); } return 0; }main 函数主要实现调用串口初始化函数,然后等待串口输入一个字符,加1后输出。 看一下初始化串口怎么做?
3)初始化串口
#define GPACON (*((volatile unsigned long *)0x7F008000)) #define ULCON0 (*((volatile unsigned long *)0x7F005000)) #define UCON0 (*((volatile unsigned long *)0x7F005004)) #define UFCON0 (*((volatile unsigned long *)0x7F005008)) #define UMCON0 (*((volatile unsigned long *)0x7F00500C)) #define UFSTAT0 (*((volatile unsigned long *)0x7F005018)) #define UTXH0 (*((volatile unsigned char *)0x7F005020)) /*这里是char型,只能存一个字符*/ #define URXH0 (*((volatile unsigned char *)0x7F005024)) #define UBRDIV0 (*((volatile unsigned short *)0x7F005028)) #define UDIVSLOT0 (*((volatile unsigned short *)0x7F00502C)) void init_uart(void) { /* 设置GPA0,GPA1作为RxD0, TxD0 */ GPACON &= ~0xff; GPACON |= 0x22; ULCON0 = 0x3; /* 8个数据位,8n1 */ UCON0 = 0x5; /* 使能UART, 时钟源PCLK */ UFCON0 = 0x1; /* FIFO enable */ UMCON0 = 0; /* 无流控 */ /* 设置波特率 */ /* DIV_VAL = (PCLK / (bps x 16 ) ) - 1 * bps = 115200 * PCLK = 66500000 Hz * DIV_VAL = 66500000 / (115200 x 16) - 1 = 35.08 * x/16 = 0.08 * x = 1 * */ UBRDIV0 = 35; /* 实际波特率 = 115451 */ UDIVSLOT0 = 0x1; } char getchar(void) { /* 判断有无数据 */ /* 有数据的状态: * 1. UFCON0 & (1<<6) == 1 * 或 * 2. UFCON0 & (1<<6) == 0, &&, (UFCON0 & 0x3f) > 0 * 无数据: UFCON0 & (1<<6) == 0, && (UFCON0 & 0x3f) == 0 */ while ((UFSTAT0 & 0x7f) == 0); return URXH0; /*直接把这个接收寄存器的值取出来就可以,得到一个接收到的字符*/ } void putchar(char c) { /* 判断状态 */ while (UFSTAT0 & (1<<14)); /* 如果TX FIFO满,等待 */ UTXH0 = c; /*直接把要发送的字符放到这个发送寄存器就可以*/ }1》 从原理图上得知,RXD0接GPA0,TXD0接GPA1。
那我们就要将这个gpio设置成 串口功能,GPACON设置成 0010 为串口功能。
2》 UFCON0
这个是FIFO 控制寄存器,什么是FIFO呢?
FIFO就是这个64字节的缓冲区,发数据时可以一次性发64字节的数据全部放到这个缓冲区中,然后硬件会一位一位的取走。因为串口的发送是很慢的,如果不用这个缓冲区只能一位一位的发,等取走后才能发下一位。 UFSTAT0 是缓冲区的状态,0:5 表示有多少位数据,第6位表示满或不满。 (UFSTAT0
& 0x7f) == 0 就表缓冲区中示没有数据。
3)波特率设置
假设我们的系统时钟 PCLK=66.5MHZ,要得到的波特率baudrate=115200.怎么得到?
DIV_VAL = (PCLK / (bps x 16 ) ) −1 (公式1)
代进去算一下: DIV_VAL =(66.5*10^6/(115200*16))-1=35.008
DIV_VAL = UBRDIVn + (num of 1’s in UDIVSLOTn)/16 (公式2)
UBRDIVn =35 后面部分为小数, UDIVSLOTn算得为12.
相关文章推荐
- UART协议与其基于控制器的裸板驱动(非常简单)
- s3c6410的UART设备驱动(5)
- UART驱动分析
- STM32F4XX串口高效驱动篇1-UART
- Linux TTY驱动--Uart_driver底层【转】
- 学习笔记 --- LINUX UART串口驱动框架分析
- uboot下的UART驱动
- Linux kernel 之 uart 驱动解析
- linux驱动之S3C2440 Uart
- ARM-Linux S5PV210 UART驱动(5)----串口的open操作(tty_open、uart_open)
- 小结UART驱动过程
- S3C2416 Linux2.6.21 驱动移植--添加UART3 及波特率设置bug消除
- S3C2416 Linux2.6.21 驱动移植--添加UART3 及波特率设置bug消除
- pcDuino第一个裸板程序uart0
- linux设备驱动之UART驱动结构
- tty初探—uart驱动框架分析
- UART设备驱动
- S3C2440 UART串口驱动
- [1]ARM-Linux S5PV210 UART驱动
- s3c6410的UART设备驱动(1)