STM32 DMA的原理:寄存器配置数据搬运的完整链路解析
扫描二维码
随时随地手机看文章
以STM32F103为例,当使用USART1以115200bps速率连续接收数据时,若采用传统轮询方式,每接收1字节需至少5条指令(读DR、写内存、增址、判数、跳转),在72MHz主频下耗时约200ns。表面看CPU仍有大量空闲时间,但当需要同时处理多个高速外设,如双路ADC同步采样、UART日志输出、SPI Flash写入时,CPU在多个数据搬运任务间频繁切换,上下文保护/恢复开销急剧上升,实时性保障彻底瓦解。而DMA(Direct Memory Access,直接存储器访问)技术的出现,彻底改变了这一局面,它允许外设与存储器之间直接进行数据传输,无需CPU干预,从而释放CPU资源,提高系统整体效率。
DMA技术本质:从CPU卸载数据搬运任务
DMA的核心思想是将“数据搬运”这一确定性、重复性极强的任务,从CPU软件控制中剥离,交由专用硬件控制器独立执行。DMA控制器本质上是一个状态机+地址生成器+计数器+总线仲裁器的组合体。它不依赖CPU指令流,而是通过硬件逻辑直接接管AHB/APB总线,在内存与外设之间建立直通通道。当配置完成后,DMA仅需响应外设发出的硬件请求信号(如USART_RXNE、ADC_EOC),即可自动完成地址递增、数据传输、计数减一、标志置位等全部动作。整个过程中CPU完全无需参与数据搬运,可专注执行控制算法、协议解析、人机交互等高价值任务。
以STM32F107为例,当USART1接收缓冲区满时,DMA控制器可直接从USART1_DR寄存器读取数据,并按预设步长写入SRAM指定区域,整个过程CPU仅需在传输完成时收到一次通知,而非每字节中断一次。这种硬件级卸载使CPU得以专注算法处理、协议解析或用户交互等高价值任务,系统整体吞吐量与确定性显著提升。据实测数据显示,在STM32F103平台上,使用DMA进行USART数据接收时,CPU占用率从传统中断方式的35%降低至5%以下,数据吞吐量提升3倍以上。
STM32 DMA控制器架构:双控制器十二通道的资源组织
STM32系列MCU通常集成双DMA控制器,以STM32F103为例,其包含DMA1(7通道)和DMA2(5通道)。这种设计并非简单的冗余堆砌,而是针对不同总线矩阵(AHB/APB)的外设访问特性进行的精细化分工。DMA1主要服务于APB1总线外设,如USART2、I2C1、TIM2等,这些外设通常运行在较低频率(如36MHz),承载着对实时性要求相对宽松的通信与模拟外设;DMA2则侧重APB2总线外设,如USART1、TIM1、ADC1等,以及部分AHB外设(如FSMC),这些外设通常运行在系统主频(如72MHz),连接着对带宽和响应速度要求更高的核心外设。
每个DMA通道都是完全独立的,拥有自己的一套寄存器组,包括传输数量寄存器(CNDTRx)、外设地址寄存器(CPARx)、存储器地址寄存器(CMARx)和控制寄存器(CCRx)。这种独立性是实现多任务并发数据搬运的前提。例如,在一个工业控制系统中,可以同时配置DMA1_Channel1负责ADC采样数据的搬运,DMA1_Channel5负责USART1的数据发送,DMA2_Channel1负责SPI Flash的读取,三者物理上同时运行,互不抢占,从而显著提高系统的实时性和数据吞吐能力。
寄存器配置:数据搬运链路的精确控制
DMA的强大功能依赖于对寄存器的精确配置,这些寄存器共同定义了数据搬运的完整链路。
地址管理:源与目标的精准定位
CPARx和CMARx寄存器分别存储外设数据寄存器的物理地址和用户数据缓冲区的起始地址。对于USART1接收,CPARx必须被设置为&USART1->DR(如0x40013804),因为这是外设产生数据的地方;而CMARx则应指向预先在SRAM中开辟的接收缓冲区,如&rx_buffer[0]。地址增量模式由CCRx寄存器中的MINC(存储器增量)和PINC(外设增量)位控制。在USART接收场景中,通常启用MINC(存储器地址自动递增),以便DMA每次传输后自动更新目标地址,实现连续填充缓冲区;而PINC则禁用(外设地址保持不变),因为外设数据寄存器(如USART1_DR)为固定地址,每次读写均操作同一物理位置。
数据宽度与传输数量:匹配外设特性
MSIZE(存储器数据大小)和PSIZE(外设数据大小)位域定义了数据传输的粒度,支持8位(Byte)、16位(Half-Word)、32位(Word)三种模式。参数选择必须严格匹配外设数据寄存器的实际宽度。例如,USART_DR寄存器在8位数据格式下为8位宽,若错误配置为32位传输,DMA将尝试读取4字节,导致后续3字节被错误解释为无效数据;反之,ADC规则通道数据寄存器(ADC_DR)为16位宽,配置为8位将造成高位数据丢失。传输数量由CNDTRx寄存器定义,其值范围为1至65535。在传输过程中,该寄存器的值会随着每一次数据项的成功搬运而自动递减,当其值减至0时,标志着本次传输的完成,并可触发相应的中断标志。
传输模式与优先级:适应不同应用场景
DIR位选择传输方向,包括外设到存储器(Peripheral to Memory)、存储器到外设(Memory to Peripheral)、存储器到存储器(Memory to Memory)三种模式。其中,“存储器到存储器”模式为特殊场景设计,其启动不依赖外设请求信号,而是由软件置位EN位直接触发,常用于RAM数据块拷贝、Flash编程前的数据预处理等场景。CIRC位启用循环模式,使CNDTRx在减至0后自动重载初始值,形成无限循环传输,典型应用包括ADC连续扫描,可避免采样丢失。优先级配置分为软件可编程优先级(High/Medium/Low/Very Low)和硬件默认优先级(通道号越小,优先级越高),工程师可根据系统实时性需求进行精细化调控,例如将ADC采样通道设为最高优先级以保障数据不丢失。
实战案例:USART接收的DMA配置
以STM32F103的USART1接收为例,完整的DMA配置流程如下:
时钟使能:开启DMA1和USART1的时钟。
DMA通道配置:
设置CPARx为&USART1->DR,指定外设数据源。
设置CMARx为接收缓冲区地址,如&rx_buffer[0]。
配置CCRx寄存器:启用MINC(存储器地址递增),禁用PINC(外设地址不变),设置MSIZE和PSIZE为8位(根据实际需求调整),选择传输方向为外设到存储器,启用传输完成中断(TCIE)。
初始化CNDTRx为缓冲区大小,如100。
USART配置:启用USART接收DMA请求(DMAR位)。
启动DMA通道:置位CCRx中的EN位,使能通道。
配置完成后,当USART1接收到数据时,DMA控制器会自动将数据从USART1_DR寄存器搬运到接收缓冲区,无需CPU干预。当CNDTRx减至0时,触发传输完成中断,通知CPU处理接收到的数据。
结语
DMA技术通过硬件化数据搬运任务,显著提升了STM32系统的数据吞吐能力和实时性。其核心在于对寄存器的精确配置,包括地址管理、数据宽度、传输数量、传输模式和优先级等关键参数。通过深入理解DMA的工作原理和寄存器配置方法,开发者可以充分利用DMA的优势,设计出高效、可靠的嵌入式系统,满足各种复杂应用场景的需求。





