DMA控制器结构:通道、请求、优先级、传输模式

说到DMA控制器,我最早接触的时候也觉得它挺神秘的。说白了,它就是一块专门负责搬数据的小硬件。它不参与运算,也不会被CPU的中断打断。它的任务就一个——按照你设定好的规则,把数据从A搬到B。

要想用好它,你得先搞懂它的内部结构。嗯,我们来拆开看看。

核心观点:DMA控制器是CPU的“数据搬运工”。它有三个核心要素——通道、请求和传输模式。你把这三点理清了,乒乓DMA的配置也就水到渠成了。

1. 通道(Channel)—— 搬运工专属车道

DMA控制器内部有多个通道。每个通道都可以独立工作,互不干扰。我记得我第一次画DMA的流程图时,把通道画成了好几条并行的传送带。每个通道有自己的源地址、目的地址、数据长度和控制寄存器。

这就像工厂里的多条流水线。你想想看,一条流水线被占了,另一条还能继续跑。我曾经在一个多通道项目中,直接用8个通道同时采集8路ADC,CPU完全空闲出来,跑UI都不卡。

  • 通道独立性:每个通道可以配置不同的源和目标。比如通道0从ADC搬数据到内存,通道1从内存搬到串口。
  • 通道优先级:通道之间有优先级排序。高优先级的通道会先获得总线控制权。
  • 通道数量:常见的有4通道、8通道、16通道等。我用过最多的是32通道的DMA控制器,那是某个高端MCU。

小提示:实际项目中,通道号从0开始编号。比如STM32的DMA1有7个通道,从0到6。别搞混了。

2. 请求(Request)—— 通知搬运工开工的信号

DMA自己不会主动搬数据。它得等一个“请求”信号。这个信号来自外设,比如ADC转换完成、串口收到数据、定时器溢出。

为什么需要请求?很简单,DMA不知道数据什么时候就绪。外设准备好了,就拉高请求线。DMA检测到请求,就开始一次传输。完成后再等下一个请求。

我个人习惯把请求分成两类:

请求类型 触发源 特点 典型应用
硬件请求 外设(ADC、USART、TIM等) 自动、实时性高 连续采样、数据流传输
软件请求 CPU写寄存器触发 手动、受控 内存拷贝、初始化数据搬移
外部引脚请求 外部中断线 灵活、响应快 外部事件触发批量传输

你想想看,如果每次都要CPU去检查外设是否就绪,那DMA还有什么意义?所以,请求机制就是DMA的“耳朵”。它负责听外设的招呼。

避坑指南:我曾经在一个项目中,定时器的DMA请求配置错了触发边沿。结果数据对不齐,整整排查了两天。记住:上升沿触发和电平触发的区别很大。

3. 优先级(Priority)—— 抢总线的规则

当多个通道同时有请求,DMA控制器必须决定谁先用总线。这就是优先级干的事。

优先级分两层:

  • 固定优先级:通道号越小,优先级越高。通道0永远优先于通道1。这个模式简单,但不够灵活。
  • 轮询优先级:每次传输后,刚刚完成传输的通道优先级降到最低。其他通道依次提升。这个模式公平。

我个人建议,除非你非常确定数据流的时序,否则先用轮询模式。我在调试一个多通道音频采集系统时,就遇到过固定优先级导致低频通道饿死的情况。换成轮询后,一切正常。

重要提醒:优先级不是越高越好。高优先级通道如果一直占用总线,其他通道的数据可能溢出。我曾经因为一个DMA通道优先级设得过高,导致另一路串口数据丢失。

4. 传输模式(Transfer Mode)—— 数据搬运的具体方式

传输模式决定了DMA怎么搬、搬几次、搬完后做什么。选对了模式,乒乓DMA才能跑起来。

最常见的几种模式:

模式 行为 适用场景
单次传输 每次请求搬一个数据单元 低速外设、内存集散
块传输 一次请求搬完一整块 批量数据搬移
循环模式 搬完自动从头开始 连续采样、音频流
乒乓模式 两个缓冲区交替使用 无丢点连续采样
链表模式 搬运完一个配置后自动跳到下一个 复杂数据流、多段传输

嗯,这里要注意循环模式和乒乓模式的区别。循环模式只有一个缓冲区,满了就从头覆盖。乒乓模式有两个缓冲区,一个满了通知CPU来处理,另一个继续接收新数据。两者不丢数据。

技巧:传输模式可以组合。比如“块传输 + 循环模式”可以实现固定大小的循环采集,这是做示波器常用的配置。

5. 一张图看懂DMA控制器结构

下面这张图展示了DMA控制器的核心结构:通道、请求、优先级和传输模式之间的关系。我画这张图的时候,特意把“乒乓缓冲区”画成两个独立的大方块,因为它在连续采样中太关键了。

DMA控制器结构图 DMA控制器核心结构 ADC请求 USART请求 TIM请求 优先级仲裁 固定优先级 / 轮询优先级 DMA通道 0 源: 0x4001 2000 → 目的: 0x2000 0400 DMA通道 1 源: 0x4000 4400 → 目的: 0x2000 0800 传输模式配置 单次 / 块 / 循环 / 乒乓 / 链表 缓冲区A 正在填充 缓冲区B CPU可处理 传输完成 → 触发中断 → 通知CPU 注意 通道独立、优先级仲裁 传输模式决定行为

这张图很直观。你得先配置好通道的源和目的地址,然后设定请求方式。请求进来之后,经过优先级仲裁,决定哪个通道先拿到总线控制权。最后,传输模式决定了这次搬运是一次性的、循环的,还是乒乓的。

总结一下:DMA控制器的四个要素——通道是车道,请求是通知,优先级是规则,传输模式是动作。你把这四个东西配置对了,后面的乒乓DMA就能顺滑运行。

嗯,我个人习惯先把通道的源地址和目的地址确认好。这两个地址写错了,后面的配置都是白搭。接下来,我们会用这些知识,一步步搭起乒乓DMA的框架。