STM32单片机DMA存储器详解

文章目录

1. DMA概述

2. 存储器映像

3. DMA框架图

4. DMA请求

5. 数据宽度与对齐

6. DMA数据转运

7. ADC扫描模式和DMA

8. 代码示例


1. DMA概述

DMA(Direct Memory Access)可以直接访问STM32内部的存储器,DMA是一种技术,允许外设和存储器之间直接传输数据,而无需通过CPU进行数据搬运。这种技术大大提高了数据传输效率,减少了CPU的负担,使CPU能够专注于其他计算任务。

DMA可以提供外设(外设寄存器,⼀般是外设的数据寄存器DR(Data Register),比如ADC的数据寄存器,串口的数据寄存器)和存储器(运行内存(SRAM)和程序存储器(Flash)是存储变量数组和程序代码的地方)或者存储器与存储器之间的高速数据传输,非常适合用于需要高带宽数据流的应用,例如音频数据传输、图像处理等。

STM32系列一共有12个独立可配置的通道: DMA1(7个通道), DMA2(5个通道)。但是在STM32F103C8T6中,只有一个个DMA1控制器。每个通道都可以配置为不同的外设或存储器数据传输。

例如:DMA1的通道1可以配置为ADC(模数转换器)数据传输通道,DMA1的通道2可以配置为USART(通用同步/异步收发器)数据传输通道等。

每个通道都支持软件触发和特定的硬件触发,存储器到存储器的数据转运,⼀般用软件触发,外设到存储器的转运⼀般用硬件触发。

  • 软件触发:可以通过编程控制DMA的启动,例如在需要传输数据时,通过软件命令触发DMA操作。
  • 硬件触发:一些外设(例如ADC转换完成、USART接收到数据)可以配置为在特定事件发生时自动触发DMA进行数据传输。这种硬件触发机制可以进一步提高系统的实时性能。

2. 存储器映像

类型起始地址存储器用途
ROM

0x0800 0000

程序存储器Flash

存储C语言编译后的程序代码。这个区域主要用于存储用户的应用程序代码,通常是通过编程器或BootLoader进行烧录。

0x1FFF F000

系统存储器

存储BootLoader,用于串口下载。这个区域包含了STM32内部的系统启动加载程序,用户可以通过串口等方式下载新程序。

0x1FFF F800

选项字节

存储一些独立于程序代码的配置参数。这些配置参数包括读保护、写保护等安全设置。
RAM

0x2000 0000

运行内存SRAM

存储运行过程中的临时变量。这个区域用于程序运行时的堆栈、全局变量、动态分配的内存等。

0x4000 0000

外设寄存器

存储各个外设的配置参数。这个区域用于映射STM32的各个外设的寄存器地址,程序通过访问这些地址来配置和控制外设。

0xE000 0000

内核外设寄存器

存储内核各个外设的配置参数。这个区域主要包含Cortex-M3核心的系统控制寄存器、调试接口等。

计算机系统的五大组成部分

  1. 运算器:负责执行计算和逻辑操作,是计算机进行数据处理的主要部件。
  2. 控制器:负责指挥和协调计算机各部分的工作,控制指令的执行顺序和操作。
  3. 存储器:用于存储数据和程序,是计算机的重要组成部分,分为主存储器和辅助存储器。
  4. 输入设备:用于将外部信息输入到计算机中,如键盘、鼠标、扫描仪等。
  5. 输出设备:用于将计算机处理结果输出到外部,如显示器、打印机等。

存储器的分类

存储器主要分为两大类:只读存储器(ROM)和随机存储器(RAM)。

ROM(只读存储器)

ROM是一种非易失性存储器,即使在断电后,其内容也不会丢失。可以分为以下几种:

  • 程序存储器(Flash):主要用于存储经过编译的程序代码。一般情况下,程序从主闪存开始运行。
  • 系统存储器:存储启动加载程序(BootLoader),该程序通常在芯片出厂时写入,不允许用户修改。
  • 选项字节:用于存储配置数据,如Flash的读写保护设置和看门狗配置等。尽管它们也属于ROM范畴,但其存储介质也是Flash。

RAM(随机存储器)

RAM是一种易失性存储器,断电后其内容会丢失。主要分为以下几种用途:

  • 运行内存(SRAM):用于存储程序中定义的变量、数组和结构体等临时数据。
  • 外设寄存器:用于存储初始化各个外设的配置数据,以及外设运行时读写的数据。这些寄存器的存储介质也是SRAM。
  • 内核外设:例如NVIC(中断控制器)和SysTick(系统定时器)的存储器,这些也是用来控制和管理计算机的外设功能。

3. DMA框架图

 左上角是Cortex-M3内核,其中包含了CPU和内核外设,其他部分可以视为存储器。Flash是主闪存,SRAM是运行内存,各个外设可以看成寄存器,它们也是一种SRAM存储器。寄存器是一种特殊的存储器,CPU可以像读写内存一样对寄存器进行操作。同时,寄存器的每一位连接着控制外设电路的导线,用于控制引脚的高低电平、导通和断开等。寄存器是软件与硬件的桥梁,通过读写寄存器,软件实际上在控制硬件。

为了高效管理存储器,设计了一个总线矩阵。总线矩阵的左边是主动单元(具有存储器访问权),右边是被动单元(只能被动读取)。内核中有DCode总线(专门访问Flash)和系统总线(访问其他存储器)。DMA作为主动单元,也需要总线访问权,有自己的总线(DMA1和DMA2),它们分别有7个和5个通道,负责设置数据的源地址和目标地址。仲裁器决定通道的优先级,确保公平访问。

在总线矩阵中,如果DMA和CPU同时访问同一目标,DMA会暂停CPU的访问,但总线仲裁器会保证CPU得到一半的总线带宽。DMA本身也有自己的配置寄存器,连接在AHB总线上,因此DMA既是主动单元也可以作为被动单元接受访问。DMA请求是硬件触发信号,用于在ADC转换完成或串口接收到数据时,触发DMA进行数据转运。

Flash是ROM的一种,通过总线直接访问时,无论是CPU还是DMA,都只能读取数据,不能写入。如果DMA的目标地址是Flash区域,会导致转运错误。写入Flash需要通过接口控制器,先擦除再写入数据。

DMA的数据转运可以从外设到存储器,也可以从存储器到外设,还可以在存储器之间进行。每个站点(外设或存储器)有三个参数:

  1. 起始地址:包括外设端的起始地址和存储器端的起始地址,决定数据从哪里来,到哪里去。
  2. 数据宽度:指定一次转运的数据宽度,可以是字节(8位),半字(16位),或字(32位)。例如,ADC的数据为16位(uint16_t),因此应选择半字。
  3. 地址自增:决定每次转运后,地址是否移动到下一个位置。例如,在ADC扫描模式下,外设地址不需自增,而存储器地址需要自增,以防止数据覆盖。

传输计数器与自动重装器

  • 传输计数器:指定总共转运的次数,是一个自减计数器。例如,设置为5,则DMA只能转运5次,每次转运后计数器减1。当计数器减到0后,DMA停止转运,并恢复到起始地址。
  • 自动重装器:决定计数器减到0后是否自动恢复到初始值。如果使用自动重装器,DMA会在计数器减到0后自动重装初始值,实现循环模式;否则是单次模式。

DMA触发控制

DMA的触发源有硬件触发和软件触发,通过M2M参数选择。当M2M为1时,使用软件触发,DMA以最快速度连续不断地触发,直到传输计数器清0。软件触发和循环模式不能同时使用,因为软件触发清零后不重装,循环模式清零后自动重装。

当M2M为0时,使用硬件触发,常用于与外设有关的转运。例如,ADC转换完成、串口接收到数据或定时时间到时,硬件触发DMA进行转运。

DMA启用条件

DMA准备进行转运的条件包括:

  1. 开关控制:DMA_Cmd必须使能。
  2. 传输计数器:必须大于0。
  3. 触发源:必须有触发信号。每次触发,传输计数器自减1。当计数器等于0且无自动重装时,DMA停止转运。此时,需要禁用DMA(DMA_Cmd给DISABLE),重设传输计数器,然后重新启用DMA(DMA_Cmd给ENABLE),才能继续工作。写传输计数器时,必须先关闭DMA,再进行设置。

4. DMA请求

 这张图显示了DMA1的请求映像,其中包括DMA的7个通道。每个通道都有一个数据选择器,可以选择硬件触发或软件触发。左边列出了硬件触发源,每个通道的硬件触发源是不同的。例如:

  • 若要选择ADC1来触发,则必须选择通道1。
  • 若要选择TIM2的更新事件来触发,则必须选择通道2。

每个通道的硬件触发源是固定的,所以要使用某个硬件触发源,就必须使用其对应的通道。而如果使用软件触发,则可以任意选择通道。

硬件触发与软件触发

  • 硬件触发:每个硬件触发源对应固定的通道。例如,使用ADC1作为触发源时,需要调用库函数ADC_DMACmd来开启ADC1的DMA输出。同理,使用定时器2的通道3时,需要使用TIM_DMACmd函数来控制DMA输出。具体选择哪个触发源,取决于你开启了哪个外设的DMA输出。

  • 软件触发:软件触发时,通道选择是任意的,不受硬件触发源的限制。

优先级仲裁

这7个触发源进入仲裁器,进行优先级判断,最终产生内部的DMA1请求。默认情况下,通道号越小,优先级越高。但是,这个优先级可以在程序中进行配置。

5. 数据宽度与对齐

第一列表示源端宽度,第二列表示目标宽度,第三列表示传输数量。以下是不同情况下的操作:

源端宽度和目标宽度都是8位

  • 源端0位置读数据B0,目标0位置写数据B0。

  • 依次将B1、B2、B3从源端挪到目标端。

源端宽度8位,目标宽度16位

  • 源端读取B0,目标写入00B0。

  • 源端读取B1,目标写入00B1,依此类推。

  • 目标宽度大于源端宽度时,目标数据前面多出来的空位补0。

源端宽度8位,目标宽度32位

  • 类似地,源端读取8位数据,目标写入32位数据时,前面空位补0。

源端宽度16位,目标宽度8位

  • 源端读取B1B0,只写入B0,舍弃高位B1。

  • 源端读取B3B2,只写入B2,舍弃高位B3。

总结

  • 当目标宽度大于源端宽度时,目标数据前面空位补0。

  • 当目标宽度小于源端宽度时,舍弃多余的高位数据。

  • 当源端和目标宽度相同时,数据直接传输,无需额外处理。

6. DMA数据转运

将SRAM中的数组DataA转运到另一个数组DataB中,参数配置如下:

  • 外设地址:DataA数组的首地址

  • 存储器地址:DataB数组的首地址

  • 数据宽度:两个数组的类型都是uint8_t,所以数据宽度为8位(字节)传输

  • 地址自增

    • 如果两个站点的地址都自增,转运完成后,DataB数组的所有数据将与DataA数组相同。
    • 如果源地址(DataA)不自增,而目标地址(DataB)自增,转运完成后,DataB的所有数据都会等于DataA[0]。
    • 如果源地址(DataA)自增,而目标地址(DataB)不自增,DataB[0]将等于DataA的最后一个数,DataB的其他数据保持不变。
    • 如果两个地址都不自增,DataA[0]转到DataB[0],其他数据不变。
  • 方向参数:从外设站点(DataA)转运到存储器站点(DataB)。

  • 传输计数器:设置为7,不需要自动重装。

  • 触发选择:选择软件触发。

最后,调用DMA_Cmd使能DMA,转运7次后,传输计数器减到0,DMA停止,转运完成。需要注意的是,这种数据转运是一种复制转运,转运完成后DataA的数据不会消失。

7. ADC扫描模式和DMA

左边展示的是ADC扫描模式下的转运流程。每次触发后,7个通道依次进行AD转换,并将转换结果存放在ADC_DR寄存器中。每个通道转换完成后,进行一次DMA数据转运,同时自增目标地址,防止数据覆盖。

DMA配置

  1. 外设地址:设置为ADC_DR寄存器的地址。
  2. 存储器地址:在SRAM中定义一个数组ADValue,并将其地址作为存储器地址。
  3. 数据宽度:因为ADC_DR和SRAM数组都使用uint16_t数据类型,数据宽度设置为16位(半字)传输。
  4. 地址自增
    • 外设地址不自增。
    • 存储器地址自增。
  5. 传输方向:从外设站点(ADC_DR)到存储器站点(ADValue数组)。
  6. 传输计数器:设置为7,与通道数量相同。
  7. 自动重装:根据ADC的配置决定。
    • 如果ADC是单次扫描,DMA传输计数器不需要自动重装,完成一次转换后停止。
    • 如果ADC是连续扫描,DMA可以选择自动重装,在ADC启动下一轮转换时,DMA也启动下一轮转运,使ADC和DMA同步工作。
  8. 触发选择:选择ADC的硬件触发。ADC扫描模式在单个通道完成转换后,不会置任何标志位或产生中断,但会产生DMA请求,触发DMA转运。

8. 代码示例

STM32基于DMA数据转运和AD多通道

STM32基于DMA数据转运和AD多通道-CSDN博客

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/29188.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【 ARMv8/ARMv9 硬件加速系列 3.5.1 -- SVE 谓词寄存器有多少位?】

文章目录 SVE 谓词寄存器(predicate registers)简介SVE 谓词寄存器的位数SVE 谓词寄存器对向量寄存器的控制SVE 谓词寄存器位数计算SVE 谓词寄存器小结SVE 谓词寄存器(predicate registers)简介 ARMv9的Scalable Vector Extension (SVE) 引入了谓词寄存器(Predicate Register…

打造工业操作系统开源开放体系

我国制造业具有细分行业、领域众多,产品丰富,制造模式多样等特点,围绕以工业操作系统为核心的工业软件赋能体系建设,离不开平台运营商、工业软件开发商、系统服务商、科研机构、工业企业等多方联合参与。聚众同行、聚力创新&#…

【数据库系统概论复习】关系数据库与关系代数笔记

文章目录 基本概念数据库基本概念关系数据结构完整性约束 关系代数关系代数练习课堂练习 语法树 基本概念 数据库基本概念 DB 数据库, 为了存用户的各种数据,我们要建很多关系(二维表),所以把相关的关系(二…

创建型模式--抽象工厂模式

产品族创建–抽象工厂模式 工厂方法模式通过引入工厂等级结构,解决了简单工厂模式中工厂类职责太重的问题。 但由于工厂方法模式中的每个工厂只生产一类产品,可能会导致系统中存在大量的工厂类,势必会增加系统的开销。此时,可以考虑将一些相关的产品组成一个“产品族”,…

Java基础16(集合 List)

目录 一、什么是集合? 二、集合接口 三、List集合 1. ArrayList容器类 1.1 常用方法 1.1.1 增加 1.1.2 查找 int size() E get(int index) int indexOf(Object c) boolean contains(Object c) boolean isEmpty() List SubList(int fromindex,i…

运行SpringBoot项目失败?代码出现爆红横线,提示“No beans of ‘UserService‘ type found”让我来看看~

今天在做实验运行项目的时候,发现userService: 一直在提示“No beans of UserService type found”,回去翻了Service业务层的代码,Service注解我也加了呀,奇了怪了。 运行项目,出现了这样的提示&#xff1…

判断一组数据哪些是素数,并统计一个数组中元素的出现频率

import java.util.HashMap; import java.util.Map; public class Test_A26 {//判断一个数是不是素数public static boolean isPrime(int num){if(num<1){return false;}for(int i2;i<Math.sqrt(num);i){if(num%i0){return false;}}return true;}//统计数组中出现的频率 p…

python安装目录文件说明----Dlls文件夹

在Python的安装目录下&#xff0c;通常会有一个DLLs文件夹&#xff0c;它是Python标准库的一部分。这个文件夹包含了一些动态链接库&#xff08;Dynamic Link Libraries&#xff0c;DLL&#xff09;&#xff0c;这些库提供了Python解释器和标准库的一些关键功能。以下是对这个文…

模拟自动滚动并展开所有评论列表以及回复内容(如:抖音、b站等平台)

由于各大视频平台的回复内容排序不都是按照时间顺序&#xff0c;而且想看最新的评论回复讨论内容还需逐个点击展开&#xff0c;真的很蛋疼&#xff0c;尤其是热评很多的情况&#xff0c;还需要多次点击展开&#xff0c;太麻烦&#xff01; 于是写了一个自动化展开所有评论回复…

Kaggle比赛:成人人口收入分类

拿到数据首先查看数据信息和描述 import pandas as pd import seaborn as sns import matplotlib.pyplot as plt # 加载数据&#xff08;保留原路径&#xff0c;但在实际应用中建议使用相对路径或环境变量&#xff09; data pd.read_csv(r"C:\Users\11794\Desk…

嵌入式技术学习——c51——串口

一、串口介绍。 串口是一个 通讯接口。成本低&#xff0c;容易使用&#xff0c;通信线路简单&#xff0c;可实现两个设备的相互通信 单片机的串口可以实现单片机于单片机&#xff0c;单片机与电脑&#xff0c;单片机与其他模块相互通信。 51单片机内部自带UART&#xff0c;通…

Flutter图像编辑器应用:创造生动美丽的照片体验

介绍 引言 想象一下&#xff0c;在一个阳光明媚的下午&#xff0c;与家人或朋友漫步在风景如画的街道上。拿出手机&#xff0c;迫不及待地捕捉这一刻的美好&#xff0c;按下快门&#xff0c;留下了一张充满回忆的照片。 然而&#xff0c;回到家后发现照片的亮度有些偏暗&…

【完结】无代码网页爬虫软件——八爪鱼采集器入门基础教程

《八爪鱼采集器入门基础教程》大纲如下&#xff1a; 课程所提软件&#xff0c;八爪鱼采集器下载&#xff1a; 1.软件分享[耶]八爪鱼&#xff0c;爬取了几百条网站上的公开数据&#xff0c;不用学代码真的很方便。[得意]2.发现了一个很棒的软件&#xff0c;?不用学python也可…

周跳的探测及修复

前言&#xff1a; 本章节代码均在Gitee中开源&#xff1a; 导航工程: 导航工程及其有关的所有项目 - Gitee.comhttps://gitee.com/Ehundred/navigation-engineering/tree/master/%E5%8D%AB%E6%98%9F%E5%AF%BC%E8%88%AA%E5%8E%9F%E7%90%86/%E5%91%A8%E8%B7%B3%E6%8E%A2%E6%B5%…

什么是Vue开发技术

概述 Vue.js 是一个用于构建用户界面的渐进式框架&#xff0c;它设计得非常灵活&#xff0c;可以轻松地被集成到任何项目中。 vue是视图的发音&#xff0c;其目的是帮助开发者易于上手&#xff0c;提供强大的功能构建复杂的应用程序 示例 以下是vue基本的语法概述 声明式渲…

探索未来工作新伙伴:机器人流程自动化(RPA)揭秘

想象一下&#xff0c;如果你的日常工作中那些繁琐、重复的任务&#xff0c;比如数据录入、文件整理、邮件发送等&#xff0c;都能自动完成&#xff0c;你将拥有更多时间专注于真正需要创造力和智慧的工作&#xff0c;是不是听起来就像拥有了一个私人助理&#xff1f;这并不是遥…

VUE3版本新特性

VUE3版本新特性 VUE3和VUE2的区别路由的使用vite安装项目新特性使用 1.VUE3和VUE2的区别 2020年9月18日&#xff0c;Vue.js发布版3.0版本&#xff0c;代号&#xff1a;One Piece 于 2022 年 2 月 7 日星期一成为新的默认版本! Vue3性能更高,初次渲染快55%, 更新渲染快133% 。…

推荐 3 款小巧的文件压缩、投屏和快速启动软件,请收藏,避免找不到

Maya Maya是一款由博主25H开发的体积小巧、简单易用的快速启动工具。它的操作逻辑和界面设计几乎复刻了Rolan早期版本&#xff0c;功能上与Rolan几乎别无二致。Maya支持多文件拖拽添加启动、快捷键呼出、自动多列显示等功能。此外&#xff0c;Maya还具备lnk文件解析功能。 May…

多目标粒子群算法(MOPSO):原理讲解与代码实现 Matlab代码免费获取

声明&#xff1a;文章是从本人公众号中复制而来&#xff0c;因此&#xff0c;想最新最快了解各类智能优化算法及其改进的朋友&#xff0c;可关注我的公众号&#xff1a;强盛机器学习&#xff0c;不定期会有很多免费代码分享~ 目录 粒子群算法 多目标粒子群算法 一、外部档案…

Android11 以Window的视角来看FallbackHome的启动

在WMS中&#xff0c;使用WindowState代表着一个Window并维护着一个Window的"层级树"&#xff0c;每个Window需要按照"层级"的规则进行排列。对于FallbackHome&#xff0c;其Window是挂载在home task上&#xff0c;而home task挂载在DefaultTaskDisplayArea…