webee210 开发板的串口裸板驱动
2015-12-27 18:47
204 查看
webee210开发板使用的是串口0作为log的输出口,如图所示:1.RXD0和TXD0 分别是GPA0_0以及GPA0_1,首先先使能2个GPIO为串口功能。GPA0CON(0xE020_0000)2.其次看时钟串口的典型的结构图是:可以看到UART部分分为了2个时钟信号,一个是由外部的时钟经过分频得到SCLK_UART,一个是PCLK的时钟,而这个时钟是66M假如前面经历过时钟配置那一节的话,我们已经将基本的几个时钟都配置成为了三星推荐的时钟频率。我们采用PCLK的时钟。UCON0, R/W, Address = 0xE290_00043.常用参数的初始化波特率,数据位,停止位,奇偶校验位的配置,我们选择的是8bit数据位,1bit停止位,无奇偶校验。ULCON0, R/W, Address = 0xE290_00004.数据fifo控制器UFCON0, R/W, Address = 0xE290_0008我们只需要关闭fifo就可以了。其他的采用默认的参数。关于有无fifo的区别可以参考http://blog.csdn.net/u013256018/article/details/50410840这个文章。5.UTXH0, W, Address = 0xE290_0020 发送数据寄存器6.URXH0, R, Address = 0xE290_0024,接收数据寄存器7.波特率配置有两个相关的寄存器UBRDIV0, R/W, Address = 0xE290_0028,UDIVSLOT0, R/W, Address = 0xE290_002C有公式计算:DIV_VAL = UBRDIVn + (num of 1's in UDIVSLOTn)/16DIV_VAL = (PCLK / (bps x 16)) −1或者是DIV_VAL = (SCLK_UART / (bps x 16)) −1,这个取决于选择哪个时钟源作为UART的时钟三星提供了我们一个表格关于UDIVSLOTn中1的个数以及对应写的值三星给了我们一个例子:For example, if the baud-rate is 115200 bps and SCLK_UART is 40 MHz, UBRDIVn and UDIVSLOTn are:DIV_VAL = (40000000 / (115200 x 16)) -1= 21.7 -1= 20.7UBRDIVn = 20 ( integer part of DIV_VAL )(num of 1's in UDIVSLOTn)/16 = 0.7then, (num of 1's in UDIVSLOTn) = 11so, UDIVSLOTn can be 16'b1110_1110_1110_1010 or 16’b0111_0111_0111_0101, etc.整体的串口程序就是这些了。看代码:start.s
.text .global _start _start: ldr sp, =0xD0037D80 @设置栈,以便调用c函数 bl main @调用main函数 halt_loop: bl halt_loopmain.c
#include "led.h" #include "clock.h" #include "uart.h" int main() { unsigned char c; led_init(); //LED初始化 sys_clock_init(); //系统时钟初始化 uart_init(); //串口初始化 while(1) { c = uart0_getbyte(); //等待键盘输入 uart0_sendbyte(c-32); //将a~z小写字母转换为A~Z大写字母 if((c == 'F')||(c == 'f')) //当按下F或者f时,闪灯 { led_flash(); } } return 0; }uart.c
#include"uart.h" void uart_init() { /* 配置引脚 * GPA0CON[1] = UART_0_TXD * GPA0CON[0] = UART_0_RXD */ GPA0CON = (0x2 << 4)|(0x2 << 0); /* * 设置UART0的数据格式为:8个数据位, * 一个停止位,无奇偶校验 */ ULCON0 = (0 << 3)|(0 << 2)|(0x3 << 0); /* * 设置UART0的时钟源为PCLK_PSYS = 66.7MHz,由时钟分频器产生 * 发送、接收均采用查询方式 */ UCON0 = (0 << 10)|(0x1 << 2)|(0x1 << 0); /* 禁止UART0 FIFO!!!!!!!!!!! * 这里如果使能的话实验效果差别相当大, * 读者可以尝试修改为UFCON0 = (1 << 0); * 思考为什么效果会这样? */ UFCON0 = (0 << 0); /* 无流控 */ UMCON0 = (0 << 4); /* * 波特率 = 115200bps * 分频系数 = ( PCLK_PSYS / (Baud * 16)) - 1; * 分频系数 = UBRDIVn寄存器的值 + (UDIVSLOTn寄存器中1的个数) / 16; * For example: * PCLKP =66.7MHz,波特率设为115200 * 分频系数 = ( 66700000 / (115200 * 16)) - 1 = 35.2; * 所以:UBRDIVn寄存器的值 = 35; * 所以UDIVSLOTn寄存器的值的1的个数为2, * 根据S5PV210手册p880可知 UDIVSLOTn= 0x808; */ UBRDIV0 = 0x23; UDIVSLOT0 = 0x808; } void uart0_sendbyte(unsigned char c) { /*直到发送缓存为空,不为空时一直等待*/ while(!(UTRSTAT0 & (1 << 2))); /*向UTXH0 寄存器中写入数据,UART会自动将它发送出去*/ UTXH0 = c; } unsigned char uart0_getbyte() { /*直到发送缓存不为空,为空时一直等待*/ while(!(UTRSTAT0 & (1 << 0))); /*直接读取URXH0 寄存器,即可获得接收到的数据*/ return URXH0; }其实使能和失能FIFO的区别就是一个可以保存多个串口的数据,一个只能保存一个数据。上面的例子假如在使能fifo的时候,我们连续按多次的F(频率很快),但是基本上灯闪烁的次数是F的次数的2倍,但是关闭fifo时,连续F多次,只能闪烁4次,原因是在第一个F后,我们读取了URXH0,进入闪烁。但是很快第二个F来时,硬件赋值给了URXH0,但是此时的led闪烁还没有结束,当继续按第3个F时,此时之前的URXH0还没有被读取,造成第3个数据就丢失了。当使能FIFO时,这些数据先会写到FIFO中,数据不会丢失。
相关文章推荐
- 【C#学习】——接口例子
- hdoj5600N bulbs
- Java Web开发中entityBean的习惯用法
- 数值优化(Numerical Optimization)学习系列-共轭梯度方法(Conjugate Gradient)
- C#使用C/C++编译的动态链接库dll
- Ubuntu Apache 部署 Django
- Android SDK Manager国内下载缓慢的问题
- 数值优化(Numerical Optimization)学习系列-信赖域方法
- java分销资源计划平台框架了解及学习
- xampp 500服务器内部错误,
- 数值优化(Numerical Optimization)学习系列-线搜索方法(LineSearch)
- 数值优化(Numerical Optimization)学习系列-概述
- 2016虚拟现实产业链格局将铺设
- 添加JavaScrip
- HTML5<fieldset>标签
- 函数式编程(functional programming)学习总结
- 福建省赛-- Common Tangents(数学几何)
- 关于for循环中i=0与i=arr.length容易被忽视的bug
- Library not loaded: @rpath/libswiftCore.dylib
- 福建省赛-- Common Tangents(数学几何)