基于DMA控制器的UART串行通信设计
2.2 链表项缓存区的设计
建立N个DMAx的链表内容结构体的缓存区DMAx_LINK_LIST_INFOR_INDEX(i)(i=1,2,3,...N-1),称作DMAx_LINK_LIST_INFOR_CACHE(i)(i=1,2,...N-1)。其中DMAx_LINK_LIST_INFOR_CACHE(i)的地址为4字节对齐,必须为最低2位是0的位置。
2.3 空链表项地址队列的设计
建立DMAx的可用空缓存FIFO队列,称作DMAx_LINK_LIST_FREE_TABLE,用于存储N个链表中的空缓存区地址。当执行出队操作时,返回一个非NULL空缓存区地址,若取回值为NULL则说明没有可用缓存区;而执行入队操作时,会将一个非NULL空缓存区的地址加入FIFO队列中,执行读取队列长度操作时,返回队列中可用空缓存地址的数量。
2.4 已占用链表项地址队列的设计
建立DMAx的链表地址FIFO队列,记作DMAx_LINK_LIST_FILL_TABLE,用来放置占用并填充了链表内容的结构体缓存区地址。当执行出队操作时,返回一个非NULL已占用缓存区地址,若取回值为NULL则说明没有可用的已占用缓存区地址;而执行入队操作时,会将一个非NULL已占用缓存区的地址加入FIFO队列中,执行读取队列长度操作时,返回队列中可用的已占用缓存地址数量。
2.5 发送用缓存地址保存队列的设计
建立UARTn TX的地址保存FIFO队列UART_LINK_LIST_STORE_TABLE,用于保存一次DMA发送的时所用到的DMAxLINK_LIST_INFOR_CACHE地址。队列容量可与DMAx_LINK_LIST_FILL_TABLE的容量相同,或根据需求设置成更小。
3 串行通信程实现
3.1 关键寄存器设置
1)使能外设时钟,将PCONP寄存器中的PCGPDAM位置1。此位在复位时为0,即默认DMA被禁止,所以在应用DMA前须先将其使能。
2)使能UnFCR中的第3位。该位为UART的DMA功能使能位,置1时使能DMA,清0后禁用DMA功能;只有在该位使能后,UART的发送和接收过程才能由DMA控制完成。
3)将寄存器DMAReqSel的相应位清零。比如第0位,因为DMA的UART0 TX与定时器0匹配0复用,所以需先选择到UART0 TX上。第0位为0时DMA选择UARTX,为1时DMA选择MAT0.0;其它串口也需做类似选择。
3.2 串行数据发送过程实现
UARTn的DMA数据发送过程如下:
1)轮询检测是否有数据需要UARTn的发送,如果有则从UARTn_BUF_FREE_TABLE队列中取出一个UARTn_BUF缓存,填充欲发送的数据,然后从DMAx_LINK_LIST_FREE_TABLE队列中取出一个DMAx_LINK_LIST_INFOR_CACHE,将UARTn_BUF的地址赋给DMAx_LINK_LIST_INFOR_CACHE的Link List_SrcAddress,并设置其LinkList_DstAddress为UnTHR的地址LinkList_NextListAddress暂为0、LinkList_Control Value为UARTn_BUF中数据大小、源和目的BURST SIZE为0、源和目的传输宽度的1字节、源地址自增、目标地址不自增和Terminal Count中断使能。最后将该DMAx_ LINK_LISTINFOR_CACHE值入队到DMAx_LINK_LIST_FILL_TABLE队列中。流程如图1所示。本文引用地址:https://www.eepw.com.cn/article/160710.htm
评论