07 DMA
Direct Memory Access controller 直接内存访问控制器
up的视频讲解: https://space.bilibili.com/1455872040
1 ⭐️DMA 简介

DMA(Direct Memory Access controller)的全称是 直接内存访问控制器
对于外设中的数据 如果要存到内存中 往往都是通过将对应标志位置位 向CPU发出信号 然后 CPU再将对应寄存器进行读取 读取完之后 再将数据存到RAM里面
而通过DMA CPU就只需要简单地对它进行配置 就可以将这样重复性的搬运工作交给它去处理
2 DMA工作原理
2.1 工作流程

如果CPU直接对数据进行搬运
- 那么首先需要通过APB总线
- 再通过AHB总线矩阵将数据读取到CPU内部的寄存器中
- 最后 再通过总线矩阵写到内存RAM中这就完成了一次搬运

如果通过DMA来搬运的话
- 首先需要对DMA进行配置 那么CPU就会 通过AHB总线矩阵对DMA的AHB slave端口进行写入
- 配置好了之后 DMA就会作为AHB总线上的 主设备 去 读取外设寄存器中的数据
- 读取完成后 再将数据 拷贝到对应的内存空间里面
所以通过DMA 外设中的数据就可以不经过CPU直接给到内存 它叫做 直接内存访问控制器的原因
2.2 工作方式

从外设到内存只是其中一种情况 我们来排列组合一下
- 外设到内存
- 比如说ADC采集 串口接收就可以通过DMA来搬运到内存
- 内存到外设
- 比如说 DAC输出 串口发送 就可以通过DMA将数据搬运到这些外设
- 外设到外设
- 是否能直接搬运取决于地址访问、请求节拍和目标外设接收条件,不能只按型号新旧判断。
- 本课程采用外设→RAM→外设分两步处理,便于分别控制采集与输出速度;不要把ADC请求直接当作IIC DAC的更新请求。
- 内存到内存
- 从flash搬运到ram适用于 要从flash中搬运比较多的常量数据的时候
- 从ram到ram也就是 从ram的一个区域搬运到另一个区域

讲到这里你可能会发现 DMA虽然有类似CPU的搬运功能 但它远没有CPU那么灵活
-
比如说 F103C8t6的DMA 它一共有7个通道
-
DMA请求源到通道的映射由硬件规定,一个通道可能被多个外设请求共用;方向、内存地址与传输长度仍需软件配置。共用通道的外设不能在同一时刻独立使用该通道。
-
每一个通道对应连接不同外设的DMA请求线

CPU对DMA的配置:
- 可以看到 CPU通过DMA的 AHB Slave接口
- 分别配置了 通道的参数
- 以及这个 Arbiter仲裁器 也就是配置通道的优先级
3 DMA通道配置
3.1 通道参数配置

对于 通道的参数配置 有 源地址 目标地址 以及 要传输的 数据个数 而具体怎么传 就需要配置 模式 位宽 以及 是否自增
-
正常模式就是将指定个数的数据搬运完之后就停止了 而循环模式则会重新开始又传输一遍
-
位宽可配置为 这三种 一字节也就是8位 半个字也就是16位 一个字也就是32位
-
是否自增 一般用于搬运到内存的时候 开启自增就会按照位宽 一位一位接下去
这里需要区分请求映射与地址:例如ADC1使用DMA1 Channel1,但外设地址、内存起始地址和数据长度仍要配置。ADC数据寄存器地址固定,目标RAM数组可以由软件选择;配置通道前要先关闭通道。
3.2 通道优先级配置

再来看到 通道优先级的配置 DMA一共有 四个优先级
- Very High 非常高
- High 高
- Medium 中
- Low 低
同一时刻 优先级高的先搬运 如果优先级相同的话就按通道编号的顺序来
而优先级的判决 就由刚刚看到的arbiter仲裁器来判决
- 不同的DMA请求线 连接不同的通道
- 然后再连接到 这个仲裁器
- 同一时刻只能有一个内部DMA请求
4 DMA缓冲技术


单缓冲
- DMA在 搬运完指定个数的数据之后
- 就可以触发 传输完成中断
- 然后CPU就可以直接对 RAM中的数据进行处理
双缓冲
- 设立两个缓冲区
- 在CPU在处理 上面的缓冲区的时候 就让DMA 搬运下面的缓冲区
- 当CPU处理 下面的缓冲区的时候 就让DMA 搬运上面的缓冲区
通过这样的方式就可以减少CPU的等待时间 做到不间断地处理
本课程STM32F103C8T6的DMA通道只有一个内存地址寄存器
- 所以说要实现双缓冲的效果 需要通过软件重新配置的方式
- 或者使用循环模式的半传输完成中断和传输完成中断实现两个半缓冲交替处理
✅用ADC搬运验证DMA
ADC1使用DMA1 Channel1,外设地址对应ADC数据寄存器,内存地址对应uint16_t数组;外设不自增,内存自增,宽度Half Word。HAL接口长度是传输项数,不是数组字节数。
Normal模式填满后结束,Circular模式填满后回到数组开头。CPU读取期间DMA仍可能改写循环缓冲,所以“有完成标志”不等于“数据永远不会再变”。
本课程C8T6的单通道只有一个内存地址寄存器,使用半满/全满中断可构成软件乒乓缓冲,详见连续采样。下一节先用Normal模式采完整一帧,逐步完成FFT。