STM32 控制器 DMA:嵌入式开发的超强 “数据搬运工”
wx:嵌入式工程师成长日记
https://mp.weixin.qq.com/s/L0zX86LzFjhyui2vm7rv1A?token=1728731884&lang=zh_CN
一、介绍
在 STM32 微控制器的应用开发中,直接存储器访问(DMA)技术扮演着至关重要的角色。它能够显著提升系统的数据传输效率,减轻 CPU 的负担,让 CPU 有更多精力处理复杂的算法和控制任务,从而优化整个嵌入式系统的性能。无论是在高速数据采集、实时通信还是多媒体处理等诸多领域,深入理解和合理运用 STM32 的 DMA 功能都十分关键。
二、DMA 基本原理
DMA 的核心思想是在无需 CPU 持续干预的情况下,实现存储器与外设之间或存储器不同区域之间的数据直接传输。它依靠专门的 DMA 控制器来协调传输过程。当一个 DMA 传输请求被触发,例如 ADC(模数转换器)完成一次转换后需要将数据传输到内存,DMA 控制器接管总线控制权,依据预先设置好的传输参数,如源地址、目标地址、传输数据长度、传输方向等,自动地将数据从源端搬运到目标端。
在 STM32 中,DMA 控制器通常支持多种传输模式。1.最基本的是单次传输模式,即完成一次数据传输后就停止,等待下一次启动指令;2.还有循环传输模式,特别适用于需要持续采集数据的场景,如音频采集,数据传输到缓冲区末尾后又自动回到起始地址重新传输,形成循环,保证数据的连续性。3.突发传输模式,能在一个总线周期内传输多个连续的数据,以提高传输效率。
三、STM32 DMA 的特点
(1)多通道设计
STM32 系列芯片一般配备多个 DMA 通道,不同通道可以独立配置并同时工作,这意味着可以并行处理多个外设的数据传输需求。例如,一个通道负责 UART 串口接收数据并传输到内存缓存区,另一个通道可以同步处理 SPI 接口与外部 Flash 之间的数据读写,极大地增强了系统的并发处理能力。
(2)灵活的传输配置
用户能够根据实际应用灵活设定传输的源和目标地址,可以是片内存储器(如 SRAM)、片外存储器(通过 FSMC 接口连接的外部 RAM 等)、外设的数据寄存器(像 TIM 定时器的捕获比较寄存器、ADC 的数据寄存器)。而且,传输的数据宽度支持字节、半字、字等多种形式,适配不同外设的数据格式。
(3)中断支持
每完成一次 DMA 传输、传输过半或发生错误等关键节点,DMA 控制器都能产生中断信号通知 CPU。这使得 CPU 可以及时知晓传输状态,进行后续的数据处理或错误纠正操作。例如,当一批网络数据包通过 DMA 传输完成后,触发中断,CPU 在中断服务程序中对数据包进行解包、校验等处理。
四、STM32 DMA 的配置步骤
1.开启 DMA 时钟
首先要在 RCC(复位和时钟控制)模块中使能对应的 DMA 时钟,因为 DMA 控制器作为硬件模块,需要时钟驱动才能正常工作。不同 STM32 型号,时钟使能的寄存器位有所不同,通常在 RCC_AHBENR(高级高性能总线时钟使能寄存器)或类似寄存器中设置相关位开启 DMA 时钟。
2.配置 DMA 通道参数
选定要使用的 DMA 通道后,需设置源地址、目标地址、传输数据长度、传输方向(如从外设到存储器、存储器到外设等)、传输模式(单次、循环等)以及数据宽度。这些参数通过一系列 DMA 控制寄存器来配置,例如DMA_CPARx(通道x外设地址寄存器)设置源外设地址,DMA_CMARx(通道x存储器地址寄存器)设置目标存储器地址,DMA_CNDTRx(通道 x 传输数据数量寄存器)设置要传输的数据个数。
3.配置 DMA 中断(可选)
如果需要在传输关键节点获取通知,要在 NVIC(嵌套向量中断控制器)中配置 DMA 中断优先级,并使能相应的 DMA 中断通道。同时,在 DMA 控制寄存器中开启对应的中断使能位,如传输完成中断、传输过半中断等,以便在中断发生时能及时响应并执行自定义的中断服务程序。
4.启动 DMA 传输
完成上述配置后,通过设置DMA 控制寄存器中的启动位(如 DMA_CCRx 寄存器的 EN 位)来激活 DMA 传输,此后 DMA 控制器就按照设定参数开始自动搬运数据。
五、DMA配置的寄存器
控制寄存器
传输方向设置:用于指定数据传输的方向,是从外设到内存(读操作)还是从内存到外设(写操作)。如在某些 DMA 控制器中,通过设置控制寄存器的特定位来确定,0 表示从外设到内存,1 表示从内存到外设。
传输模式选择:可选择连续传输、单次传输、循环传输等模式。连续传输适合大量数据的不间断传输,单次传输则适用于每次只需要传输少量数据的情况,循环传输常用于周期性的数据采集或输出等场景。
中断使能设置:可以开启或关闭在 DMA 传输完成、传输错误等事件发生时产生中断请求的功能。
地址寄存器
源地址寄存器:存放数据传输的源地址,即数据的起始位置。若从外设读取数据到内存,该寄存器存储外设数据缓冲区的首地址;若是从内存写入数据到外设,就存储内存中数据的首地址。
目标地址寄存器:用于指定数据传输的目标地址,即数据要存储或写入的位置。对于从外设到内存的传输,它是内存中用于存储数据的缓冲区首地址;从内存到外设的传输时,是外设接收数据的缓冲区首地址。
地址增量 / 减量设置:可设置源地址和目标地址在每次传输后是递增、递减还是保持不变,以适应不同的数据存储和传输需求。
数据长度寄存器
传输数据长度设置:用来指定本次 DMA 传输的数据量,单位可以是字节、字或双字等。通过设置该寄存器,DMA 控制器能准确知道需要传输多少数据,从而在传输达到指定长度时停止传输。
数据宽度设置:可配置每次传输的数据宽度,如 8 位、16 位、32 位等。这决定了 DMA 控制器每次从源地址读取或向目标地址写入的数据位数,要与外设和内存的数据格式相匹配。
优先级寄存器
通道优先级设置:当多个 DMA 通道同时请求传输时,可通过设置优先级来决定哪个通道先进行传输,确保重要的数据传输能够优先得到处理。
仲裁模式选择:可选择固定优先级仲裁或循环优先级仲裁等模式,以适应不同的应用场景和数据传输需求。
此外,在一些复杂的 DMA 控制器中,还可能有用于配置突发传输、校验模式、FIFO 深度等功能的寄存器。
作者:JaneZJW