当前位置: 首页 > news >正文

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

  • 地址自增:使能(源和目标地址均自增)

  • 传输模式:正常模式(非循环)

  • 触发方式:软件触发(存储器到存储器模式)

  • 优先级:中等

工作流程

  1. 初始化DMA,但不立即启动。

  2. 主循环中更新DataA的值。

  3. 调用MyDMA_Transfer()启动DMA传输。

  4. DMA自动将DataA的数据搬运到DataB

  5. 等待传输完成标志位,清除标志。

  6. 在OLED上显示传输结果。

显示效果

  • 第1行:显示"DataA"及其地址。

  • 第3行:显示"DataB"及其地址。

  • 第2、4行:分别显示DataADataB的当前值(十六进制)。


适用场景:

  • 需要高效数据搬运的应用(如音频处理、图像传输、通信协议等)。

  • 希望减少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位)


工作流程

  1. 初始化后,ADC开始连续转换。

  2. 每次转换完成后,DMA自动将数据从ADC1->DR搬运到AD_Value数组中。

  3. 主循环中每隔100ms读取并显示AD_Value的4个值。

  4. 按键和LED模块可供其他功能扩展使用。


显示效果

  • 第1行:AD0: [值]

  • 第2行:AD1: [值]

  • 第3行:AD2: [值]

  • 第4行:AD3: [值]


使用场景

  • 多通道模拟信号采集(如传感器数据读取)
  • 实时数据监控系统
  • 低功耗、高效率的数据采集应用
http://www.dtcms.com/a/354388.html

相关文章:

  • 【0420】Postgres内核 smgr + md + vfd 实现为指定 table(CREATE TABLE)创建 disk file
  • 每日八股文8.27
  • Linux系统调优工具
  • [Sync_ai_vid] 数据处理流水线 | 配置管理系统
  • 【重学 MySQL】九十二、 MySQL8 密码强度评估与配置指南
  • mysql mvcc机制详解
  • 期权交易中的“道”:从《道德经》中汲取投资智慧
  • RHEL9部署MySQL数据库及数据库的基本使用(增删改查,数据备份恢复)
  • 基于SpringBoot的社区儿童疫苗接种预约系统设计与实现(代码+数据库+LW)
  • Vue将内容生成为二维码,并将所有二维码下载为图片,同时支持批量下载(下载为ZIP),含解决一次性生成过多时页面崩溃解决办法
  • 【雅思020】Opening a bank account
  • C语言二级考试环境配置教程【window篇】
  • 能源行业数据库远程运维安全合规实践:Web化平台的落地经验
  • 【系统分析师】高分论文:论快速应用开发方法及应用
  • Linux初始——基础指令篇
  • Libvio 访问异常排查指南​
  • List | 常见的List实现类(ArrayList、LinkedList、Vector)以及ArrayList源码解读
  • 【Redis】数据分片机制和集群机制
  • 8.28 模拟|双指针
  • 零基础-力扣100题从易到难详解(持续更新1-10题)
  • Windows 命令行:rmdir 命令
  • Qt 6 与 Qt 5 存在的兼容性差异
  • C# 数组C# 多维数组
  • QML(2) - Qt 中如何注册一个 C++ 类到 QML
  • MySQL的类split方法实现
  • Java表格处理详解以及结合实际项目使用
  • WebStrom-如何设置前端项目快捷启动
  • 29. String, StringBuffer,StringBuilder 的区别是什么
  • 统一虚拟试穿框架OmniTry:突破服装局限,实现多品类可穿戴物品虚拟试穿无蒙版新跨越。
  • 【小白笔记】网速