S5PV210开发 -- 串口驱动开发
来源:互联网 发布:微赞是什么样的软件 编辑:程序博客网 时间:2024/05/17 01:15
上篇文章讲的 UART,更多的是硬件相关的知识。接下来进入正题了,串口驱动开发。
一、阅读原理图
我们用的是 UART2 串口,则接收管脚 XuRXD2 复用 GPA1_0,发送管脚 XuTXD2 复用 GPA1_1
二、S5PV210 UART
(1)通用异步接收器和发送器的概述 (p-853)
S5PV210中的通用异步接收器和发送器(UART)提供四个独立的异步和串行输入/输出(I / O)端口。所有端口都以基于中断或基于DMA的方式运行模式。 UART产生一个中断或DMA请求来传送数据到CPU和UART。UART支持高达3Mbps的比特率。每个UART通道包含两个FIFO来接收和传输数据:
ch0中的256个字节,ch1中的64个字节以及ch2和ch3中的16个字节。
UART包括可编程波特率,红外(IR)发送器/接收器,一个或两个停止位插入,5位,6位,7位或8位数据宽度和奇偶校验。每个UART包含一个波特率发生器,一个发送器,一个接收器和一个控制单元,如图1-1所示。
波特率发生器使用PCLK或SCLK_UART。发送器和接收器包含FIFO和数据移。要发送的数据被写入Tx FIFO,并被复制到发送移位器。数据是由发送数据引脚(TxDn)移出。接收到的数据从接收数据引脚(RxDn)移位,从移位器复制到Rx FIFO。
(2)通用异步接收器和发送器的关键特性
基于DMA或基于中断的操作的RxD0,TxD0,RxD1,TxD1,RxD2,TxD2,RxD3和TxD3带有IrDA 1.0的UART Ch 0,1,2和3
具有256字节FIFO的UART Ch 0,具有64字节FIFO的Ch 1,具有16字节FIFO的Ch2和3
用于自动流量控制的UART Ch 0,1和2与nRTS0,nCTS0,nRTS1,nCTS1,nCTS2和nRTS2
支持握手发送/接收。
(3)UART描述
以下各节将介绍UART操作,如数据传输,数据接收,中断生成,波特率生成,环回模式,红外模式和自动流量控制。《1》数据发送
传输的数据帧是可编程的。 它由一个起始位,五到八个数据位,一个可选的奇偶校验组成位和由行控制寄存器(ULCONn)指定的一到两个停止位。 变送器也可以产生一个强制串行输出为逻辑0状态一个帧传输时间的中断条件。 这个块传送当前发送字之后的中断信号被完全发送。 中断信号后传输时,发送器不断向Tx FIFO发送数据(Tx保持寄存器,如果是非FIFO模式)《2》数据接收
与数据发送类似,用于接收的数据帧也是可编程的。 它由一个5位的起始位组成8个数据位,一个可选的奇偶校验位以及线路控制寄存器(ULCONn)中的一到两个停止位。 收件人检测溢出错误,奇偶校验错误,帧错误和中断情况,每个错误标志都会设置一个错误标志。溢出错误(Overrun error)表示新数据在旧数据读取之前覆盖旧数据。
奇偶校验错误(Parity error)表示接收器检测到意外的奇偶校验条件。
帧错误(Frame error)表示接收到的数据没有有效的停止位。
中断条件(Break condition)表示RxDn输入保持逻辑0状态,以进行多个帧传输时间。
如果在3个字的时间内没有收到任何数据,则会发生接收超时情况(此时间间隔符合设置字长度位),FIFO模式下Rx FIFO不为空。
后面内容有点多... 就不一一翻译了。想了解更多,自己看。
三、UART 相关配置
(1)配置串口管脚
上面提到了,S5PV210 中的通用异步接收器和发送器(UART)提供四个独立的异步和串行输入/输出(I / O)端口。根据原理图可以看出,我们用的是 UART2 串口,则接收管脚 XuRXD2 复用 GPA1_0,发送管脚 XuTXD2 复用 GPA1_1
查看GPA1寄存器(p-135)
端口组GPA1控制寄存器有六个控制寄存器,分别是GPA1CON,GPA1DAT,GPA1PUD,GPA1DRV,GPA1CONPDN和端口组GPA1控制寄存器中的GPA1PUDPDN。
《1》GPA1CON 寄存器 (配置寄存器) 将其配置成UART2收/发模式
GPA1CON, R/W, Address = 0xE020_0020
GPA1CON[1] [7:4] 0100 = UART_AUDIO_TXD
GPA1CON[0] [3:0] 0100 = UART_AUDIO_RXD
设置:
GPA1CON 地址为 0xE020_0020,然后要将 GPA1CON[7:0] 进行位操作,使其变为0010 0010,即UART2收发模式。
位操作方法,参看:C语言再学习 -- 位操作
GPA1CON &= ~(0xff<<0); //清空bit 0-7
GPA1CON |= 0x22; //设置 0010 0010 接受 发送
《2》GPA1PUD 寄存器(上下拉电阻控制寄存器 )
GPA1PUD, R/W, Address = 0xE020_0028
GPA1PUD[n] [2n+1:2n] 00 = Pull-up/ down disabled
设置:
GPA1PUD 地址为 0xE020_0028,我们不需要上下拉,因此:
GPA1PUD [1:0] 00 = Pull-up/ down disabled
GPA1PUD [3:2] 00 = Pull-up/ down disabled
位操作方法:
GPA1PUD &= ~(0x0f<<0);//0000 禁止上拉下拉
(2)配置串口寄存器
在 p-864 有一个 REGISTER MAP,可以看一下。太长了只粘贴一部分。
S5PV10 UART 相关寄存器有如下几个,下面我们会一一讲解的:
《1》UART 行控制器 ULCONn
位操作方法:
《2》UART 模式控制寄存器 UCONn
位操作方法:
需要知道的小知识点:
在收发模式里有中断、轮询、DMA这些有什么区别呢?
参看:后续补充!!
再者,时钟源选择里有 PCLK、SCLK_UART 这又是什么呢?
参看:后续补充!!
《3》UART FIFO 控制寄存器UFCONn
禁止 FIFO,即FIFO 控制寄存器 UFCON2 = 0x00;
《4》UART 收/发 状态寄存器 UTRSTATn
《5》UART 发送缓冲寄存器(保持寄存器和FIFO寄存器)UTXHn
发送移位器:发送缓冲寄存器中的数据并不是直接传送到输出管脚TXD2(GPA1_1),还必须先送到发送移位器(Transmit shifter),然后再由Transmit shifter通过移位操作,将数据一位一位的发送到TXD2管脚上。
《6》UART接收缓冲寄存器(保持寄存器和FIFO寄存器)URXHn
URXHn包含接收数据的8位数据。
接收移位器:从接收管脚RXD2上接收来的数据并不是直接放到接收缓冲寄存器,而是先一位一位的放到接收移位器中,当收满一个字节后,再放到接收缓冲寄存器中。
《7》UART 通道波特率分频寄存器 UBRDIVn
《8》UART通道分割插槽寄存器 UDIVSLOTn
数据传输率
发送时钟和接收时钟
UART模块中有四个UART波特率除数寄存器,分别是UBRDIV0,UBRDIV1,UBRDIV2和UBRDIV3。
存储在波特率除数寄存器(UBRDIVn)中的值:
或者
SLCK_UART:DIV_VAL = (SCLK_UART / (bps x 16))
外部时钟源 SCLK_UART
使用 UDIVSLOT,可以更准确地生成波特率。
例如,如果波特率是 115200 bps,SCLK_UART 是 40 MHz,则 UBRDIVn 和 UDIVSLOTn 是:
= 21.7 -1
= 20.7
(UDIVSLOTn中1的个数)/ 16 = 0.7 (21.7 小数点后为 0.7)
那么(UDIVSLOTn中的1的个数)= 11 (取整数部分)
所以,UDIVSLOTn 可以是16'b 1110_1110_1110_1010或 16'b 0111_0111_0111_0101 等
PCLK:DIV_VAL1) = (PCLK / (bps x 16) )
=============================================
其中 PCLK 的值是怎么得到的呢?
查看芯片手册 CLOCK DOMAINS (p-353)
S5PV210由三个时钟域组成,即主系统(MSYS),显示系统(DSYS)和外设系统(PSYS),如图3-1所示。
•MSYS域包括Cortex A8处理器,DRAM内存控制器(DMC0和DMC1),3D内部SRAM(IRAM和IROM),INTC和配置接口(SPERI)。 Cortex A8仅支持同步模式,因此它必须与200MHz AXI总线同步运行。
•DSYS域包含显示相关模块,包括FIMC,FIMD,JPEG和多媒体IP(所有其他模块)在X,L和T块中提到的IP),如图3-1所示。
•PSYS域用于安全性,I / O外围设备和低功耗音频播放。
•每个总线系统分别工作在200 MHz(最大),166 MHz和133 MHz。 有异步总线桥(BRG)在两个不同的域之间。
在这里,得出 PCLK_PSYS 为 66 MHz。
=============================================
如果波特率是 115200 bps,PCLK 是 66 MHz,则 UBRDIV2 和 UDIVSLOT2 是:
= 35.8 -1
= 34
(UDIVSLOTn中1的个数)/ 16 = 0.8 (35.8 小数点后为 0.8)
那么(UDIVSLOTn中的1的个数)= 13 (四舍五入)
(3)总结
《1》GPA1CON 寄存器 (配置寄存器) 将其配置成UART2收/发模式
GPA1CON 地址为 0xE020_0020GPA1CON &= ~(0xff<<0); //清空bit 0-7
GPA1CON |= 0x22; //设置 0010 0010 接受 发送
《2》GPA1PUD 寄存器(上下拉电阻控制寄存器 )
《3》UART 行控制器 ULCONn (数据位宽度为 8bit,停止位 1位,无校验位,正常模式)
《4》UART 模式控制寄存器 UCONn(接收/发送模式选择轮询,正常发送暂停信号,回环模式为正常,时钟源选择 PCLK)
《5》UART FIFO 控制寄存器UFCONn(禁止 FIFO)
《6》UART 收/发 状态寄存器 UTRSTATn(接收缓冲区数据准备好,缓冲区为空;发送缓冲区寄存器为空)
《7》UART 发送缓冲寄存器(保持寄存器和FIFO寄存器)UTXHn
UTXH2 地址为 0xE290_0820《8》UART接收缓冲寄存器(保持寄存器和FIFO寄存器)URXHn
URXH2 地址为 0xE290_0824
char d;
d = URXH2 & 0xFF;
《9》UART 通道波特率分频寄存器 UBRDIVn(设置波特率为 115200)
UBRDIV2 地址为 0xE290_0828
UBRDIV2 = 34;
《10》UART通道分割插槽寄存器 UDIVSLOTn
UDIVSLOT2 地址为 0xE290_082C
UDIVSLOT2 = 0xDFDD;
四、编写驱动程序
此处用到关键字 volatile,参看:C语言再学习 -- 关键字volatile
#ifndef __UART_H__#define __UART_H__#define GPA1CON*((volatile unsigned int *)0xE0200020)#define GPA1PUD*((volatile unsigned int *)0xE0200028)#define ULCON2*((volatile unsigned int *)0xE2900800)#define UCON2*((volatile unsigned int *)0xE2900804)#define UFCON2*((volatile unsigned int *)0xE2900808)#define UTRSTAT2*((volatile unsigned int *)0xE2900810)#define UTXH2*((volatile unsigned int *)0xE2900820)#define URXH2*((volatile unsigned int *)0xE2900824)#define UBRDIV2*((volatile unsigned int *)0xE2900828)#define UDIVSLOT2*((volatile unsigned int *)0xE290082C)#define PCLK66000000//66MHzextern void uart0_init(void);extern void uart_test(void);extern void uart_putc(char );extern void uart_puts(char *);extern char uart_getc(void);extern void uart_gets(char *, int);#endif(2)uart.c
#include "uart.h"void uart2_init(void){/*配置GPA1_0 GPA1_1管脚为uart功能*/ //配置串口管脚GPA1CON &= ~(0xff<<0);GPA1CON |= 0x22; //禁止两个管脚内部上拉下拉电阻GPA1PUD &= ~(0x0f<<0);//配置串口寄存器/*8N1 115200 轮询*/ULCON2= 0x03;UCON2 = 0x05;UFCON2= 0x00;UBRDIV2 = PCLK/(115200*16) - 1;/*reference P879*/UDIVSLOT2= 0xDFDD;}void uart_putc(char c){/*判断UTXH2中是否为空 * UTRSTAT2 bit2 1,空 0,非空 */while(!(UTRSTAT2 & 0x02)) ;UTXH2 = c;if(c == '\n'){uart_putc('\r');}}void uart_puts(char *s){while(*s){uart_putc(*s);s++;}}void uart_test(void){/*输出数据到PC*/uart_puts("\n helloworld! \n");}char uart_getc(void){ /* * UTRSTAT2 bit0 1,代表接收到数据 * 0,没有接收到数据 * */ while(!(UTRSTAT2 & 0x01)); return (char)(URXH2&0xff);}void uart_gets(char *buf, int max){ int i = 0; char tmp = 0; while(i < (max-1)) { tmp = uart_getc(); /*回显*/ uart_putc(tmp); buf[i] = tmp; if(tmp == '\r') { break; } i++; } /*"abc\r" "abc\0"*/ buf[i] = '\0';}(3)main.c
#include "uart.h"#define CMD_MAX_LEN 32char cmd[CMD_MAX_LEN];int main(){/*8n1 115200 轮询模式*/uart2_init();while(1){ /*发送命令提示符*/ uart_puts("\narmshell##"); /*接收PC机端的输入*/ uart_gets(cmd, CMD_MAX_LEN); /*执行用户命令*/}return 0;}(4)Makefile
NAME=uartBIN=$(NAME).binOBJ=main.o uart.oELF=$(NAME).elfCFLAGS=-nostdlibLDFLAGS=-nostdlib -nostartfiles$(BIN):$(ELF)arm-none-linux-gnueabi-objcopy -O binary $(ELF) $(BIN)$(ELF):$(OBJ)arm-none-linux-gnueabi-ld$(LDFLAGS) -T uart.lds $(OBJ) -o $(ELF)%.o:%.carm-none-linux-gnueabi-gcc $(CFLAGS) -c $< -o $@clean:rm -f $(OBJ) $(ELF) $(BIN)(5)uart.lds
ENTRY(main)SECTIONS{. = 0xc0008000;.text :{main.o(.text)*(.text)}.data :{*(.data)}.bss :{*(.bss)}}
五、编译下载到开发板并执行
六、问题分析
RS232协议并未规定最大传输速率,而是规定“速率低于20kb/s时,传输距离可以到15m”。随着距离减小,这个速率可以提高。RS232中一个波特包括一个bit。所以波特率与比特率相等。而随着现在电子科技发展,芯片驱动接受能力增强。这个速率也在提高,现在PC机都到921600了。不要为“最大传输速率”的定义纠结。
而不会遭受永久性的损害。每一行应该有一个最小负载3kΩ,最大负载7kΩ,通常是接收器电路的一部分。
逻辑0由5V和15V之间的驱动电压和逻辑1表示在-5V和-15V之间。在接收端,电压在3V和15V之间代表0和在-3V和-15V之间的电压代表1。电压在±3V之间是不确定的,位于过渡区域。这有效地给了接收器的最小2 V噪声容限。
这被限制在120kbit / s左右。一些软件程序运行在传输速率为116 kbit / s。此外,在更长的线路长度,最大线路驱动器的驱动电流成为影响数据速率的主要特征,取代了30-V /μs的压摆率。随着线路长度的增加,负载电容也增加,需要更多的电流保持不变过渡时间。
到目前为止,已经讨论了负载电容方面的线路长度。 为了实际目的,我们不能考虑把这个负载电容的值变成真实的线路长度。 该标准规定最大线路电容为2500 pF。该对于20pF的接收机,输入电容将2480pF作为最大线路
电容。
接下来,必须考虑使用的电缆类型。 标准232电缆由多家厂商提供有互电容的每米大约100 pF,但必须增加杂散电容。 流浪电容变化很大,取决于线是否是屏蔽。对于屏蔽电缆,杂散电容通常是互电容的两倍。如图5所示,对于屏蔽电缆,最大线路长度为20米;对于非屏蔽电缆,它是40多米。
- S5PV210开发 -- 串口驱动开发
- S5PV210开发 -- 驱动开发相关硬件简介
- 串口驱动开发学习
- 硬件开发----串口驱动
- s5pv210开发板linux摄像头v4l2驱动
- s5pv210开发板linux ac97 alsa驱动
- s5pv210开发板linux mtd驱动 Nandflash
- s5pv210开发板linux mmc 驱动架构
- s5pv210开发板linux wifi驱动路径
- S5PV210开发板 介绍camera 驱动 (4)
- S5PV210开发系列七_Nand驱动实现
- S5PV210 裸机开发驱动之LED灯
- s5pv210开发板 led驱动学习笔记
- 基于S5PV210板驱动开发之按键驱动
- linux UART串口驱动开发
- linux驱动开发:串口协议
- NRF52832开发:普通串口驱动
- x210ii DM9000驱动调试成功-基于x210ii/s5pv210开发板
- iOS-各种动画特效
- js实现查询 添加 排序功能
- 普通程序员如何入门深度学习?
- SystemInfo获取设备系统参数
- 安卓handler消息机制源码解析
- S5PV210开发 -- 串口驱动开发
- C++运算符重载(6) 重载转换操作符
- HTML5 data-* 自定义属性
- Request操作类
- Wireshark抓包示范:TCP三次握手建立连接和四次握手断开连接
- IPFS 入门笔记
- iOS图片的填充方式UIImageView(contentMode)有什么不同
- 代数发展简史
- HTTP与HTTPS的区别