1 DMA简介
DMA(Direct Memory Access)直接存储器存取
可以直接访问STM32的存储器的,包括运行SRAM、程序存储器Flash和寄存器等等
DMA可以提供外设寄存器和存储器或者存储器和存储器之间的高速数据传输,无须CPU干预,节省了CPU的资源
12个独立可配置的通道: DMA1(7个通道), DMA2(5个通道)
每个通道都支持软件触发和特定的硬件触发
存储器到存储器转运,需要软件触发,一股脑的转运
外设到存储器的转运,需要硬件触发,触发一次转运一次。
STM32F103C8T6 DMA资源:DMA1(7个通道)
1.1 存储器映像
类型 | 起始地址 | 存储器 | 用途 |
ROM | 0x0800 0000 | 程序存储器Flash(主闪存) | 存储C语言编译后的程序代码 (下载程序的位置) |
0x1FFF F000 | 系统存储器 | 存储BootLoader,用于串口下载 | |
0x1FFF F800 | 选项字节 | 存储一些独立于程序代码的配置参数 | |
RAM | 0x2000 0000 | 运行内存SRAM | 存储运行过程中的临时变量 |
0x4000 0000 | 外设寄存器 | 存储各个外设的配置参数 | |
0xE000 0000 | 内核外设寄存器 | 存储内核各个外设的配置参数 |
ROM:只读存储器,非易失性、掉电不丢失的存储器;
RAM:随机存储器,易失性,掉电丢失的存储器。
1.2 DMA框图
可以看作是CPU+存储器两个东西
Flash是主闪存,SRAM是运行内存。各个外设也可以看出存储器。
寄存器是连接软件和硬件的桥梁,软件读写寄存器相当于控制硬件的执行。
使用DMA转运归类为一类问题:从某个地址取值,再放到另一个地址。
利用总线访问,分为主动和被动。
DMA要有访问的主动权。
产生冲突时,由仲裁器根据通道的优先级决定先后顺序。
DMA既是总线矩阵的主动单元,可以读写各种寄存器,也是AHB上的被动单元。
Flash一般不能写入,需要配置才可以写入。
1.3 DMA的基本结构
左边是外设寄存器站点,右边是存储器站点,包括Flash和SRAM(存储器一般特指Flash和SRAM)。DMA的转运可以是从外设到存储器,也可以是从存储器到外设,有一个方向的参数可以控制;还有一种转运方式存储器到存储器。Flash到SRAM/SRAM到SRAM。
数据宽度的作用是指定一次转运要按多大的数据宽度来进行。
传输寄存器用来指定总共转运几次的,自减计数器。
重装寄存器:当传输寄存器减到0后,是否要自动恢复到最初的值。(单次/循环)
触发源有软件触发和硬件触发,由M2M(Memory to Memory)决定,软件触发的逻辑是:以最快的速度,连续不断的触发DMA,争取早点把传输计数器清零,完成这一轮的转换。软件触发和循环模式不能同时使用。(存储器到存储器的转运)
硬件触发源可以选择ADC、串口、定时器等(一般与外设转运有关)
DMA转运的条件:
(1)开关控制,DMA_Cmd必须使能;
(2)传输计数器必须大于0;
(3)必须要有触发源。
(4)以此循环,开启下一次,但是必须先关闭DMA,再给传输计数器传值。
1.4 DMA请求
DMA触发部分
每个通道都有一个数据选择器,选择硬件触发或者软件触发,EN=0数据选择器不工作;EN=1数据选择器工作。当M2M位=1时选择软件触发,M2M=0时选择硬件触发。
每个通道的触发源都是不一样的,即硬件触发要看通道,软件触发则是随意的。
通道1的硬件触发是ADC1、TIM2的通道3和TIM4的通道1,选择哪个触发源呢?根据外设是否开启的DMA输出来决定的,比如ADC1有个库函数,ADC_DMACmd。三个都开始是或门,一般开启一个。
7个触发源进入到仲裁器,进行优先级判断,最终产生内部的DMA1请求。(默认通道号越小,通道优先级越高,也可以配置)
1.5 数据宽度与对齐
如果转运的时候,数据宽度都一样,那就是正常的一个个转运;如果数据宽度不一样,则按这个表处理。
目标的数据宽度>源端数据宽度,在目标数据前面多出的地方补0;
目标的数据宽度<源端数据宽度,读B1B0,只写入B0;读B3B2,只写入B2,把多出的高位舍弃
1.6 数据转运+DMA
任务是:将SRAM里面的数组DataA搬运到另一个数组DataB中。
外设地址是DataA数组的首地址;存储器地址是DataB数组的首地址;
数据宽度,两个都是uint8_t;
两个站点的地址都自增;
方向参数:外设站点转运到存储器站点了。
传输计数器:7
自动重装暂时不需要;
使用软件触发(存储器到存储器)
复制转运DataA的数据不会消失。
1.7 ADC扫描模式+DMA
左边是ADC扫描模式的执行流程,触发一次7个通道依次进行AD转换,转换结果都放在ADC_DR数据寄存器里,需要做的是在每个单独的通道转换完成后,进行一次DMA数据转运,并且目的地址自增,所以DMA的配置是:外设地址写入ADC_DR这个寄存器的地址,存储器的地址可以在SRAM中定义一个数组ADValue,然后把ADValue的地址当作寄存器的地址;之后数据宽度是uint16_t。外设地址不自增,存储器地址自增;传输方向是外设站点到存储器站点;传输计数器是7;计数器是否重装根据ADC的配置,ADC单次扫描则传输计数器不重装;ADC循环扫描,则传输计数器自动重装;最后是触发选择,这里ADC_DR的值是在ADC单个通道转换完成之后才有效的,所以DMA转运的时机需要和ADC单个通道转换完成同步,所以DMA的触发选择ADC硬件触发。
ADC单个通道完成过不产生中断,但是会产生DMA请求,去触发DMA转运。
手册