实验六 UART.docx
《实验六 UART.docx》由会员分享,可在线阅读,更多相关《实验六 UART.docx(12页珍藏版)》请在冰豆网上搜索。
实验六UART
实验七UART
一、实验目的
1)运行试验参考代码,理解串口通信过程。
2)修改试验代码,实现DNW窗口输出“InputWords:
”并接收输入一段字符串,按下回车后,DNW输出“yourinputwords:
输入的字符串”。
二、实验设备及工具
硬件:
飞凌OK6410开发板、USB转串口线、OTG下载线
软件:
PC机操作系统WIN8.1、DNW、RVDS2.2
三、实验原理
串口,可说是嵌入式开发中重要的开发工具了。
通过串口,我们可以和开发板进行交互,同时也可以打印芯片内部的一些信息。
ARM11的串口使用也是比较简单的。
当然首先需要配置一下。
以上是串口驱动开发的流程。
首先对串口进行初始化,然后实现发送和接收。
以上是串口的结构图。
对于接收和发送,都有一个64字节大小的FIFO。
对于发送来说,如果使用FIFO的话,如果FIFO没有满,那么发送的数据首先发送到FIFO中,然后FIFO中的数据会自动的发送到发送移位寄存器中通过串口发送出去。
接收也是一样的道理。
简单的使用就是不使用FIFO。
数据直接发送到发送移位寄存器中发送。
下面就开始串口程序的设计了,
一、首先是对串口初始化。
1、 设置管脚为串口模式
串口端口和普通IO口是共用的。
这个就要看OK6410的原理图。
从原理图中,接收是GPA0,发送时GPA1。
所以第一步要先去配置管脚功能。
从GPIO章节得到,对于GPA0-1,配置为0010的时候,是串口的功能。
所以,代码就是
2、设置串口工作模式
我们知道,串口是有几种模式的,数据位是几位,有没有奇偶校验位,停止位是几位。
这个就通过ULCONx寄存器控制的。
我们使用的是uart0。
配置的寄存器就是ULCON0。
配置成8位数据模式,没有奇偶校验位,1位停止位,普通的串口模式。
代码就是
3、 设置工作模式
串口是可以工作在三个模式下,一个是中断模式,第二个是DMA方式,第三个就是轮询方式。
这里,不使用DMA,也不使用中断,就配置为轮询模式。
这个配置是通过UCONx寄存器配置。
同样,这个寄存器有4个,对应串口0-3。
这里配置UCON0寄存器。
主要关心以下几位
第一个是选择串口的时钟源。
选择PCLK。
后面两个是配置串口的接收和发送模式,是工作在中断或者轮询,还是工作在DMA模式。
配置为中断或者轮询。
代码就为:
4、 波特率设置
波特率是串口中最重要的设置了,如果这个波特率设置得不对的话,那么就不能正常的接收和发送数据了。
S3C6410的波特率配置通过两个寄存器配置,一个配置整数,一个配置小数。
UART模块有四个波特率分频寄存器:
UBRDIV0、UBRDIV1、UBRDIV2和UBRDIV3,如表6-90所示。
UBRDIVn
中的值决定串行Tx/Rx时钟波特率,如下:
DIV_VAL=UBRDIVn+(UDIVSLOTn中1的量)/16
DIV_VAL=(PCLK/(b/s×16))–1
DIV_VAL=(EXT_UCLK0/(b/s×16))–1
或者
DIV_VAL=(EXT_UCLK1/(b/s×16))–1
除数的范围为1到(216-1),并且UEXTCLK应该比PCLK小。
利用UDIVSLOT,能够得到更准确的波特率。
例如,如果波特率是115200b/sPCLK、EXT_UCLK0或EXT_UCLK1是40MHz,UBRDIVn和UDIVSLOTn是:
DIV_VAL=(40000000/(115200×16))-1
=21.7-1
=20.7
UBRDIVn=20(DIV_VAL的整数部分)
(UDIVSLOTn中1的数量)/16=0.7
这时,(UDIVSLOTn中1的数量)=11
因此,UDIVSLOTn为16’b1110_1110_1110_1010或者16’b0111_0111_0111_0101等。
UDIVSLOTn选择如下表所示:
以上是配置串口波特率的公式。
我们使用的是PCLK。
使用的公式就是
当然这个除下来不一定能整除,就会有小数部分。
所以就需要对小数处理。
numof1’sinUDIVSLOTn/16= 小数部分。
得到numof1’sinUDIVSLOTn值,在查上面的表格,得到真正配置小数寄存器的数据。
举例说明:
之前时钟,将PCLK配置成66M。
波特率采用115200。
得到整数的值是34,小数是0.8。
查表,13对应0xDFDD。
所以,整数的寄存器配置为34。
小数的寄存器配置为0xDFDD。
UBRDIVx对应串口x的波特率设置的整数部分。
UDIVSLOTx对应串口x的波特率设置的小数部分。
代码就是:
以上,就是整个串口的初始化了。
初始化后,我们就可以使用串口发送数据和接收数据了。
二、串口发送数据
有一个寄存器用来保存发送的数据。
当往这个寄存器写数据,硬件会自动的将该数据通过串口发送出去。
在发送之前,是需要检查上一次数据是否发送结束。
如果没有发送结束的话,就需要等待。
这个也是通过一个状态寄存器来知道的。
从这个寄存器,就可以知道,发送数据是否完成以及是否接受到新数据。
对于发送来说,就要检查第二位是否为0。
为0,说明上一次数据是发送结束的。
代码就是:
三、串口接收
这个也是比较简单了,同样,有一个寄存器保存接收的数据,不过和51不一样的是,51的发送和接收都是同一个寄存器SBUF。
但是S3C6410是有两个的。
同样,在读取数据之前,需要检查下,是否有数据接收,有数据接收,才读取数据。
检测之前数据发送说过,检测状态寄存器的第0位。
代码就是
这个地方,在读取中加入了一些处理,为了对接收到的数据进行回显。
每接收到一个数据,判断该数据是否是ox0d(换行符\n),0x0a(\r)。
如果是这两个数据的话,就发送0x0d和0x0a。
否则就将接收的数据发送出去。
剩下就是在main函数中,编写简单的测试代码即可。
先串口初始化,然后无限循环的读取串口接收的数据,判断在将数据回发。
这样,就可以在串口助手中看到,发什么,就显示什么,因为芯片将发送的数据回发了回来。
四、实验步骤
1、参考代码测试
编译工程,生成bin文件。
连接开发板,打开DNW,输入dnw50008000,发生生成的bin文件,DNW中输入go50008000运行。
键盘输入任意字符,DNW显示如下图:
2、按要求修改代码
定义一个字符串,循环接收字符输入,每输入一个字符,在DNW上显示,再进行判断,如果不是回车键,存入字符数组,如果是回车键,则退出循环,输出整个字符串。
运行结果如下图:
五、实验总结
本次试验中没有使用FIFO。
数据直接发送到发送移位寄存器中发送。
所以在主函数在定义了一个字符数组来存储输入的字符串。
这样,已有的串口函数可以直接调用,只需要修改主函数代码就能实现字符串输入。
但是对于串口的输入输出过程还是要熟悉,对于一些重要的寄存器,要理解其功能和设置方法。
波特率是串口中最重要的设置,如果这个波特率设置得不对的话,那么就不能正常的接收和发送数据了。
波特率计算是有公式的,理解了公式每个变量的意义,才能熟练运用。