新闻中心

EEPW首页>嵌入式系统>设计应用> ARM中基于DMA的高效UART通讯及其应用

ARM中基于DMA的高效UART通讯及其应用

作者: 时间:2012-04-16 来源:网络 收藏

4、和中断相结合的软件设计

在以S3C44B0X为核心组成的移动机器人中,采用3路PWM定时器驱动3个直流电机,通用的GPIO口和A/D口连接外部的红外和超声以及激光传感器,使用0完成与上位机(PC)的数据交换,这些数据是单向的(从上位机发送给S3c44b0x),主要是上位机传给机器人控制器的各种命令信息,但是命令信息的发送时间上是不具有规律性的,即间隔时间不定。为了充分的利用CPU,减少数据丢失的风险,我们利用模式来完成数据的接收。软件部分主要是针对具体的,对控制器以及作适当的初始化。UART的初始化比较简单,主要是数据格式、波特率等的设置,这些与其他控制器相同,只要设置相关的寄存器即可。注意UART设置成不使用自动流控制,不使用红外线传输模式,关键要注意UART0设置成DMA模式而不是中断模式,并且要使能FIFO缓冲区(根据需要,使用16字节的接收缓冲区),这样在接收缓冲区满时,会产生DMA请求而不是中断请求。限于篇幅,具体的寄存器定义以及串行口的初始化不做详悉介绍,可以参考文献[1][2]。

DMA控制器的初始化也比较简单,主要是相关寄存器的设置。与BDMA0相关的在本系统中用到的寄存器以及相关定义见表1,具体寄存器的名称定义以及物理地址见参考文献[1][2]。

表1 S3c44b0x的BDMA相关寄存器的定义
4.jpg

在初始化时要正确设置目标(缓冲区的)首地址、数据传输的方向、源寄存器的首地址、地址指针是否递增以及递增方向、DMA计数器等等。相关代码以及注释如下:
#define RAM_ADDRESS 0xc200000 //定义接收数据的缓冲区,根据硬件而定。在我们的系统中扩展的SDRAM 存储空间从0x0C00000~0x0C7fffff,占用S3c44b0x的bank 6。
#define size 16 //定义DMA的计数器,根据需要设定,可以选择的选项是4、8、2和16
char *Buf;
Buf=(unsigned char*) RAM_ADDRESS; //指针指向起始地址
BDISRC0=(1128)+(int)(rURxH0); /*以字节为单位传送;因为DMA操作时是将UART的寄存器中的数据读出放置到设定的缓冲区,所以源寄存器的地址应该是固定到;UART的接收保存寄存器rURxH0,同时位[29:28]应该设置成 0b11。*/
BDIDES0=(1030)+(0128)+ Buf); /*传输方向模式设定为从内部设备(UART口)到外部存储器(SDRAM),目标存储器(SDRAM)使用地址递增的方向,将数据顺次放置到缓冲区中*/
BDICNT0=(1030)+(126)+(322)+(121)+(0 lt;20)+size;/*设置UART0使用BDMA0通道,在DMA计数到0时自动重载和自动启动,计数结束产生中断,每次DMA操作移动 16字节数据到设定地缓冲区*/
BDICNT0 |= (120);//使能DMA
BDCON0 = 0x02;//允许外部DMA请求

数据接收:这一部分工作由初始化好后的DMA控制器依靠硬件来完成。接收数据不定时,初始化UART0的接收缓冲区为16字节,当接收缓冲区满时,会产生DMA请求,然后在DMA控制器的控制下,将UART的接收FIFO中的16字节的数据转移到指定的缓冲区中(SRAM),当数据转移完毕(DMA 计数到0)后,要做两件事情:一是自动重载和自动启动,即自动重新设置好目标(缓冲区)首地址和源地址(UART接收寄存器)以及DMA计数器,准备好下次DMA请求;另外产生DMA中断。DMA中断服务程序要做的工作很简单,只要对全局标志RECEIVE_FLAG置位,通知主程序有新的命令需要处理。这样主程序可以直接处理RAM中的数据,而不需要花费时间去读取UART的接收缓冲区。

数据处理:当主程序通过查询全局标志RECEIVE_FLAG,如果为1,则知道有新的命令,可以直接读取命令缓冲区,同时对RECEIVE_FLAG清零。然后按照一定的算法对接收的数据做出解析,这部分内容不做重点讨论。



评论


相关推荐

技术专区

关闭