Bootstrap

stm32入门教程--DMA 超详细!!!

目录

简介

工作模式

1、数据转运+DMA

2、ADC扫描模式+DMA


简介

工作模式

1、数据转运+DMA

  这个例子的任务是将SRAM的数组DataA,转运到另一个数组DataB中,这个基本结构里的各个参数应该如何配置呢?

 首先是外设站点和存储器站点的起始地址、数据宽度、地址是否自增这三个参数,

在这个任务中,外设地址显然应该填DataA数组的首地址,存储器地址给DataB的地址,然后数据宽度,两个数组的类型都是uint8_t,,所以数据宽度都是按8位的字节传输

 我们想要的效果是DataA[0]转运到Data[0],DataA[1]转运到DataB[1],两个数组一一对应,所以转运完DataA[0]和DataB[0]之后,两个站点的地址都应该自增,都移动到下一个数据的位置,继续转运DataA[1]和DataB[1]这样来进行,如果左右都不自增,那就一直是DataA[0]转到DataB[0]其他数据不变。

 下一个数据是方向参数,显然就是外设站点转运到存储器站点了,如果想把DataB转运到DataA,可以把方向参数换过来,这样就是反向转运了

  然后就是传输计数器和是否要自动重装,这里显然幺转运7次,所以传输计数器给7,自动重装暂时不需要,之后触发选择部分 ,这里我们要选择软件触发 ,因为这里是存储器到存储器的数据转运 ,是不需要等待硬件时机的,尽快转运完成就行了 ,最后调用DMA_Cmd,给DMA使能,这样数据就会从DataA转运到DataB了 ,转运7次之后,传输计数器自减到0,DMA停止,转运完成 ,这里的数据转运是一种复制转运,转运完成后DataA的数据并不会消失,这个过程相当于把DataA的数据复制到了DataB的位置 这就是第一个存储器到存储器的数据转运 。

2、ADC扫描模式+DMA

  左边是ADC扫描的全部流程,这里有7个通道,触发一次之后,七个通道依次进行AD转换然后转换结果都放到ADC_DR数据寄存器里面 ,那我们要做的就是,在每个单独的通道转换完成之后,进行一次DMA数据转运,并且目的地址进行自增,这样数据就不会被覆盖,所以这里DMA的配置就是外设地址,写入ADC_DR这个寄存器的地址,寄存器的地址,可以在SRAM中定义的一个数组ADvalue然后把ADvalue的地址当作存储器的地址 ,之后数据宽度 ,因为ADC_DR和SRAM数组 ,我们要的都是uint16_t的数据,所以数据宽度都是16位的半字节传输 ;

地址是否自增,从这个图里,显然是外设地址不自增,存储地址自增,传输方向是外设站点到存储器站点 ,传输计数器,这里通道有七个,所以计数7次;

计数器是否自动重装这里可以看ADC的配置,ADC如果是单次扫描,那DMA的传输计数器可以不自动重装,转换一轮就停止,如果ADC是连续扫描,那DMA就可以使用自动重装 ,在ADC启动下一轮转换的时候,DMA也启动下一轮转运,ADC和DMA同步工作

最后是触发选择,这里ADC_DR的值是在ADC但各通道转换完成后才会有效,所以DMA转运的时机,需要和ADC单个通道转换完成同步,所以DMA的触发要选择ADC的硬件触发。

这里硬件触发要说明一下,ADC扫描模式,在每个单独的通道转换完成后,没有任何标志位,也不会触发中断,所以我们程序不太好判断,某一个通道转换完成的时机是什么时候,索然单个通道转换完成后,不产生任何标志位和中断,但是他应该会产生DMA请求去触发DMA转运。

一般来说,DMA最常见的用途就是配合ADC的扫描模式,因为ADC扫描模式有个数据覆盖的特征,或者说这个数据覆盖的问题是ADC固有的缺陷,这个缺陷使ADC和DMA成了最常见的伙伴,ADC对DMA的续修是非常强烈的 ,像其他一些外设,使用DMA是可以提高效率,是锦上添花的操作。

;