首先通过上节ADC的模数转换,学习到在进行扫描模式时,需要DMA进行数据转运,本节将学习这个内容。
首先进行实验,如下所示:
DMA
可以看出首先输入数组A,之后将数据转运到数组B,再通过数据自增将数组A增加,再转运到数组B,变化为一秒延时。
接下来学习理论知识:
其中存储器到存储器的转运为软件触发,外设到存储器为硬件触发。
每个通道都支持软件触发,硬件触发需要特定的通道才能触发,
之后是存储器的地址,以下是只读存储器ROM和随机存储器RAM的地址
DMA总线用于访问各个存储器;DMA中主要有独立的通道进行数据转运;仲裁器进行判断谁先,防止冲突;AHB从设备进行设置DMA参数;DMA请求就是硬件触发源,譬如:ADC转换完、串口接收数据等发送请求来调度DMA进行数据转运。
之后是DMA的整体结构,首先输入一个方向参数,数据转运主要有3种:外设到存储器、存储器到外设、存储器到存储器(Flash到SRAM或者SRAM到SRAM)为这个时放在外设寄存器位置的就可以是FLASH或SRAM,不是一定要寄存器的地址。之后对于数据宽度外设中分为字节uint8_t,半字uint16_t为ADC一次转运数据大小,字uint32_t;地址是否自增表示在一次转运后存储地址是否需要移动到下一个位置从而转运剩下数据(如P++)ADC的扫描模式需要DMA进行不断的转运,此时外设不需要地址自增,存储器处需要。
传输计数器是一个自减器,当需要转运5次数据时,初始值是5,每转运一次就减1,直到为0.然后如果使用自动重装器,就表明当传输计数器为0后重新回到初始值5再次进行转运,譬如ADC的扫描模式+连续模式就需要这样。
之后就是DMA的触发模块,分为硬件触发和软件触发,由M2M(存储器到存储器)决定,当为1时,软件触发,它的作用是使得传输计数器尽快为0,因此它与自动重装器互斥,只能选其一。为0时硬件触发,可由ADC、串口等触发。
DMA可以使用的三个条件:
1、DMA_CMD开启使能。
2、传输计数器的值大于0,在写这个值时一定要DMA未开启使能才行,如果一次运输完之后想再次运行,需要先关闭DMA使能,写入计数器值,之后再次开启DMA使能。
3、选定触发源为硬件或者软件。
接下来是从A转运到B时分别数据的大小:
当源数据宽度<=目标数据宽度,进行高位补零,
反之只取源数据的低位数据。
之后进行例子:
也是刚刚实验的例子,实现将DataA到DataB的数据转运,相当于复制转运DataA的数据依然存在,采用软件触发
首先设置外设地址就是DataA的地址,数据宽度为uint8_t,地址自增
存储器的地址是DataB的地址,数据宽度为uint8_t,地址自增,这样可以保证数据一一进行传输
方向参数选择外设到存储器
传输计数器为7,自动重装为0
M2M选择1,为软件触发
之后是第二个例子
外设地址为ADC_DR的地址,数据宽度为uint16_t,地址不自增
存储器地址为自定义数据ADValue的地址,数据宽度为uint16_t,地址自增
方向为外设到存储器
传输计数器为7
当ADC为单次模式时,DMA中的自动重装不启用
当ADC为连续模式时,DMA中的自动重装启用,两者相配套。
M2M选择硬件触发
当任一通道将数据传输到外设后,就会给一个DMA请求从而进行数据转运。
之后是DMA的硬件触发实验
DMA+ADC
明天将学习串口模式