串口DMA方式收发
笔者使用的是STM32F407VET6,共包含6路串口,页尾处程序已将全部串口的DMA收发配置完成,本文仅以串口1为例进行讲解。(查看代码可直接跳至第二节或页尾处下载)
1 STM32F4 DMA 简介
DMA,全称为:Direct Memory Access,即直接存储器访问。DMA 传输方式无需 CPU 直接控制传输,也没有中断处理方式那样保留现场和恢复现场的过程,通过硬件为 RAM 与 I/O 设备开辟一条直接传送数据的通路,能使 CPU 的效率大为提高。
STM32F4 最多有 2 个 DMA 控制器(DMA1 和 DMA2),共 16 个数据流(每个控制器 8 个),每一个 DMA 控制器都用于管理一个或多个外设的存储器访问请求。每个数据流总共可以有多达 8个通道(或称请求)。每个数据流通道都有一个仲裁器,用于处理 DMA 请求间的优先级。
它可以处理一下事务:
- 外设到储存器的传输
- 储存器到外设的传输
- 储存器到储存器的传输
注意:DMA1 控制器 AHB 外设端口与 DMA2 控制器的情况不同,不连接到总线矩阵,因此,仅 DMA2 数据流能够执行存储器到
存储器的传输。
其中,数据流的多通道选择,是通过 DMA_SxCR 寄存器控制的,如图1所示:
图1 通道选择
上图可以看出,DMA_SxCR 控制数据流到底使用哪一个通道,每个数据流有 8 个通道可供选择,但每次只能选择其中一个通道进行 DMA 传输,DMA2 的各数据流通道映射表,如表 1 所示
表1 DMA2数据流映射表
上表就列出了 DMA2 所有可能的选择情况,来总共 64 种组合,比如本章我们要实现串口1的 DMA 发送,即USART1_TX,就必须选择 DMA2 的数据流 7,通道 4,来进行 DMA 传输。这里注意一下,有的外设(比如 USART1_RX)可能有多个通道可以选择,随意选择一个就可以。
重要寄存器简介
(1) DMA 中断状态寄存器
该寄存器总共有 2 个:DMA_LISR 和 DMA_HISR,每个寄存器管理 4 数据流(总共 8 个),DMA_LISR 寄存器用于管理数据流 0~3,而 DMA_HISR 用于管理数据流 4~7。如果开启了 DMA_LISR 中这些位对应的中断,则在达到条件后就会跳到中断服务函数里面去,即使没开启,也可以通过查询这些位来获得当前 DMA 传输的状态。这里常用的是 TCIFx位,即数据流 x 的 DMA 传输完成与否标志。
注意:此寄存器为只读寄存器,所以在这些位被置位之后,只能通过【中断标志清除寄存器】来清除。
(2)DMA 中断标志清除寄存器
该寄存器同样有 2 个:DMA_LIFCR 和 DMA_HIFCR,同样是每个寄存器控制 4 个数据流。该寄存器为只写寄存器,其各位就是用来清除 【中断状态寄存器】的对应位的,通过写 1 清除。
(3) DMA 数据流 x 配置寄存器(DMA_SxCR)
该寄存器控制着 DMA 的很多相关信息,包括数据宽度、外设及存储器的宽度、优先级、增量模式、传输方向、中断允许、使能等都是通过该寄存器来设置的。所以 DMA_ SxCR 是 DMA 传输的核心控制寄存器。
(4)DMA 数据流 x 数据项数寄存器(DMA_SxNDTR)
这个寄存器控制 DMA 数据流 x 的每次传输所要传输的数据量。其设置范围为 0~65535。并且该寄存器的值会随着传输的进行而减少,当该寄存器的值为 0 的时候就代表此次数据传输已经全部发送完成了。所以可以通过这个寄存器的值来知道当前DMA 传输的进度。