DMA学习
DMA简介
- DMA(Direct Memory Access)直接存储器存取
- DMA可以提供外设和存储器或者存储器和存储器之间的高速数据传输,无须CPU干预,节省了CPU的资源
- 12个独立可配置的通道:DMA1(7个通道),DMA2(5个通道)
- 每个通道都支持软件触发和特定的硬件触发
- STM32F103C8T6 DMA资源:DMA1(7个通道)
存储器映像
DMA框架
总之就是CPU或者DMA直接访问Flash的话,是只可以读而不可以写的。
然后SRAM是运行内存,可以任意读写,没有问题
DMA基本结构
DMA进行转运,有几个条件:
第一:就是开关控制,DMA_Cmd必须使能。
第二:就是传输计数器必须大于零。
第三:就是触发源,必须有触发信号。
触发一次,转运一次,传输计数器自减一次。当传输计数器等于零,且没有自动重装时,这时无论是否触发,DMA都不会再进行转运了。此时就需要DMA_Cmd,给DISABLE,关闭DMA,再为传输计数器写入一个大于零的数。再DMA_Cmd,给ENABLE,开启DMA。DMA才能继续工作。
注意一下:写传输计数器时,必须要先关闭DMA,再进行,不能在DMA开启时,写传输计数器,这是手册里的规定
DMA请求:
数据宽度对齐
数据转运+DMA
ADC扫描模式+DMA
示例程序一:
源数组(DataA
)、目标数组(DataB
)
DataA
(源)和DataB
(目标)。
调用
MyDMA_Transfer()
启动DMA搬运。
MyDMA_Init()
:初始化DMA1通道1,配置为存储器到存储器模式,支持字节宽度和地址自增。
MyDMA_Transfer()
:启动DMA传输,等待传输完成并清除标志位。(
MyDMA.h
)声明DMA初始化和传输函数。
DMA配置要点
时钟使能:
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE)
传输方向:外设(源)→ 存储器(目标)
数据宽度:字节(
DMA_PeripheralDataSize_Byte
)地址自增:使能(源和目标地址均自增)
传输模式:正常模式(非循环)
触发方式:软件触发(存储器到存储器模式)
优先级:中等
工作流程
初始化DMA,但不立即启动。
主循环中更新
DataA
的值。调用
MyDMA_Transfer()
启动DMA传输。DMA自动将
DataA
的数据搬运到DataB
。等待传输完成标志位,清除标志。
在OLED上显示传输结果。
显示效果
第1行:显示"DataA"及其地址。
第3行:显示"DataB"及其地址。
第2、4行:分别显示
DataA
和DataB
的当前值(十六进制)。
适用场景:
需要高效数据搬运的应用(如音频处理、图像传输、通信协议等)。
希望减少CPU占用,提高系统响应能力的场景。
示例程序二
ADC(模数转换器)与DMA(直接存储器访问)结合,实现多通道模拟信号的连续采集与实时显示。
使用STM32的ADC模块,配合DMA实现多通道(4通道)模拟信号的自动采集,并将转换结果实时显示在OLED屏幕上。通过DMA传输,减少了CPU的干预,提高了系统的效率。
主要文件结构1.
main.c
初始化OLED和ADC(含DMA配置)。
在主循环中实时显示4个ADC通道的转换结果(
AD_Value[0]
~AD_3]
)。每100ms更新一次显示。
2.
AD.c
AD_Init()
:初始化ADC1、GPIOA和DMA1。配置ADC为独立模式、连续转换、扫描模式,使用软件触发。
配置DMA为循环模式,实现ADC数据的自动搬运到全局数组
AD_Value
。执行ADC校准并启动转换。
3.
AD.h
声明外部变量
AD_Value
和初始化函数。4.
Key.c
/Key.h
按键初始化与读取函数,支持两个按键(PB1和PB11),带消抖处理。
5.
LED.c
/LED.h
LED初始化与控制函数,支持两个LED(PA1和PA2)的开关和翻转。
6.
OLED.c
/OLED.h
/OLED_Font.h
OLED显示屏的I2C驱动,支持字符、字符串、数字(十进制、十六进制、二进制)显示。
ADC配置要点
时钟配置:ADC时钟为12MHz(72MHz / 6)。
GPIO配置:PA0~PA3为模拟输入模式。
规则组通道:配置4个通道,分别对应PA0~PA3。
ADC模式:
独立模式
连续转换
扫描模式
右对齐数据
软件触发
DMA配置:
循环模式
外设地址固定(ADC数据寄存器)
存储器地址自增(数组
AD_Value
)半字宽度(16位)
工作流程
初始化后,ADC开始连续转换。
每次转换完成后,DMA自动将数据从
ADC1->DR
搬运到AD_Value
数组中。主循环中每隔100ms读取并显示
AD_Value
的4个值。按键和LED模块可供其他功能扩展使用。
显示效果
第1行:AD0: [值]
第2行:AD1: [值]
第3行:AD2: [值]
第4行:AD3: [值]
使用场景
- 多通道模拟信号采集(如传感器数据读取)
- 实时数据监控系统
- 低功耗、高效率的数据采集应用