二十一、DMA原理介绍
1. DMA基础知识
1.1 数据传输方式
一般情况下实现存储器和外设之间的数据传输,有三种常用的方法:轮询法(polling),中断法(interrupt)以及DMA。
轮询法(polling): 在主循环中,CPU不断检查外设的相关标志位,来判断其是否需要进行数据的传输,如果需要,则CPU将数据在外设和内存之间搬运,实现数据传输。当数据传输服务请求频繁或者传输的数据量很大时,会影响其他任务的实时性。
中断法(interrupt): 当外设需要传输数据时,会触发中断,CPU会暂停正在处理的任务,转而去执行中断服务函数,接着处理外设的数据传输任务。CPU无需反复检查外设的标志位,中断机制会指示CPU何时去处理外设数据,但是依然需要CPU去完成数据搬运和传输过程。当外设数据传输服务不频繁且数据量不大时,中断法也是不错的选择。当中断连续不断且频繁发生时,中断法变得不再高效,因为在恢复主流程的执行和中断相应的上下文切换会占用大量的CPU时间。
DMA: DMA控制器是单片机中的硬件单元,它在存储器和外设之间有专用的通道,允许外设和存储器之间高效传输数据,且传输过程无需CPU参与。
综上可见DMA是一种高效的数据传输方式。
1.2 什么是DMA
直接存储器访问(DMA)是一种高效的数据传输方式,它允许外设或内存直接与存储器进行数据交换,而无需CPU的介入。这样可以显著提高数据处理的效率,减轻CPU的负担。
1.3 CW32 DMA介绍
CW32x030 支持直接内存访问(DMA),无需 CPU 干预,即可实现外设和存储器之间、外设和外设之间、存储器和存储器之间的高速数据传输。DMA 控制器内部的优先级仲裁器,可实现 DMA 和 CPU 对外设总线控制权的裁,以及多 DMA 通道之间的调度执行。
每个通道都有专门的硬件DMA请求逻辑,同时可以由软件触发每个通道;传输的长度、传输的源地址和目标地址都可以通过软件单独设置。
关于DMA的主要特性在用户手册的第124页,如图所示(部分截图)。
1.4 DMA的传输模式
DMA 支持 4 种传输模式:软件触发 BLOCK 传输模式,软件触发 BULK 传输模式,硬件触发 BLOCK 传输模式,硬件触发 BULK 传输模式。
- 软件触发 BLOCK 传输模式
- DMA 通道每传输完成 1 个数据块,DMA 插入一个传输间隙,仲裁器在该传输间隙内进行传输优先级仲裁。如果在该传输间隙内,有 CPU 或更高优先级的 DMA 请求要访问当前 DMA 通道所占用的 AHB 设备,仲裁器会释放当前 DMA 通道对该设备的控制权,让 CPU 或者更高优先级的 DMA 通道优先访问;当 CPU 或更高优先级的 DMA通道释放设备访问权后,本 DMA 通道未完成的数据传输将继续进行。
- 软件触发 BULK 传输模式
- 软件触发 BULK 传输模式没有传输间隙,在 DMA_CNTy.CNT 个数据块传输完成之前,该 DMA 通道将一直占用外设,CPU 或更高优先级的 DMA 通道只能等待该 DMA 传输完成后才能访问该外设。
- 硬件触发 BLOCK 传输模式
- 同软件 BLOCK 传输模式一样,硬件 BLOCK 传输模式每传输完成 1 个数据块,DMA 插入一个传输间隙,允许CPU 或更高优先级的 DMA 通道传输请求抢占外设控制权。
- 硬件触发 BULK 传输模式
- 硬件触发 BULK 传输模式没有传输间隙,在 DMA_CNTy.CNT 个数据块传输完成之前,DMA 将一直占据外设访问权,CPU 或更高优先级的 DMA 通道只能等待该操作完成后才能访问该外设。
1.5 DMA中断
DMA 通道在传输过程可产生 2 个中断标志:传输错误中断标志和传输完成中断标志。
1.6 地址生成算法
DMA控制器允许在外设和内存之间进行高效的数据传输,而无需CPU的介入。DMA传输过程中的地址生成是根据预设的配置自动进行的,这包括源地址、目标地址以及它们的增量设置。
1.6.1 源地址和目标地址
- 源地址(Source Address):这是数据传输开始的地址。根据传输的类型,它可以是内存地址或外设寄存器的地址。
- 目标地址(Destination Address):这是数据传输结束的地址,同样可以是内存地址或外设寄存器的地址。
1.6.2 地址增量设置
在DMA传输过程中,每次数据传输后,源地址和目标地址可以根据配置自动增加或保持不变。这主要通过以下两个设置控制:
- 源地址增量(Source Address Increment):在每次数据传输后,如果启用了源地址增量,源地址将根据设置的增量大小(通常是数据宽度,如8位、16位或32位)自动增加。如果未启用,源地址将保持不变,这在从单一外设寄存器连续读取数据时很有用。
- 目标地址增量(Destination Address Increment):与源地址增量类似,目标地址在每次数据传输后也可以根据设置的增量大小自动增加,或者保持不变。
1.6.3 地址生成算法
基于上述设置,DMA的地址生成算法可以概括为:
初始化:在DMA传输开始前,源地址和目标地址被初始化为预设的起始地址。
数据传输:每次传输一个数据单元(根据配置的数据宽度,可以是8位、16位或32位)。
地址更新:
- 如果启用了源地址增量,源地址将根据数据宽度自动增加。
- 如果启用了目标地址增量,目标地址将根据数据宽度自动增加。
重复步骤2和3,直到完成预设数量的数据传输。
1.7 循环模式
循环模式是STM32F103C8T6等STM32系列微控制器的DMA(直接存储器访问)功能中的一个重要特性,它特别适用于需要连续数据传输的场景,如ADC连续采样、定时器产生的周期性事件等。在循环模式下,DMA传输完成一轮设定的数据量后,会自动重新开始,无需CPU介入重新配置DMA,从而实现了数据的连续传输。
- CIRC位:在DMA通道的控制寄存器(DMA_CCRx)中,有一个名为CIRC(循环模式)的位。当这个位被设置(即CIRC=1)时,循环模式被激活。
- 自动重置:在循环模式下,当DMA完成一次预设数量的数据传输后,不会停止工作。相反,它会自动将数据计数器重置为初始配置的值,然后继续进行下一轮的数据传输。
- 连续传输:这意味着DMA会不断地循环传输数据,直到CIRC位被清除(即CIRC=0),或者DMA被显式停止。这对于需要连续监测或更新的应用场景非常有用,如连续读取ADC值或向某个外设不断发送数据。
1.8 中断
每个DMA通道都可以在DMA传输过半、传输完成和传输错误时产生中断。为应用的灵活性考虑,通过设置寄存器的不同位来打开这些中断。
发生异常事件时,正在进行的DMA传输不会被停止,仍将继续传输。发生错误事件时,正在进行的DMA传输会被停止。
2. 实验原理
DMA支持很多个外设,这里就以串口DMA接收进行介绍。
一般进行串口接收也有以下几种方式:
- 通过轮询接收数据
- 通过中断接收数据
- 通过DMA接收数据
一般使用情况可能是中断方式用的比较多,但是使用中断在数据量不大的时候使用效率是高的,但数据量一旦很大,这个效率就很低了。数据量很大的传输推荐使用DMA进行传输。
2.1 ADC+DMA实现思路
我们配置ADC单通道单次采样,设定转换完成触发DMA。当adc完成转换(这里会触发中断重新启动下一次ADC转换),DMA将数据搬运到指定的buff里面。搬运完成之后DMA也会触发中断会重新使能DMA。一环嵌一环这样就能够循环的读取ADC数据了。