STM32标准库学习笔记-9.DMA 直接存储器存取
参考教程:【STM32入门教程-2023版 细致讲解 中文字幕】
DMA(Direct Memory Access)
- DMA(Direct Memory Access)直接存储器存取
- DMA可以提供外设和存储器或者存储器和存储器之间的高速数据传输,无须CPU干预,节省了CPU的资源
- 12个独立可配置的通道: DMA1(7个通道), DMA2(5个通道)
- 每个通道都支持软件触发和特定的硬件触发
- STM32F103C8T6 DMA资源:DMA1(7个通道)
STM32存储器映射
通俗的讲映射就是一种特殊的对应关系
Cortex‐M3 支持4GiB 存储空间。整块4G存储器开始地址标为0x00000000,结束地址为0xFFFFFFFF,地址的位数是32位,那么2^32=4,294,967,296。
这4GiB的空间指的是地址空间,每个地址对应一个具体的设备。CPU通过地址,然后对应到地址存储单元或者寄存器,进行读取或者写入数据即可。4GiB是它最大支持的地址数目,但是实际可能没有使用那么多。
| 类型 | 起始地址 | 存储器 | 用途 |
| ROM | 0x0800 0000 | 程序存储器Flash | 存储C语言编译后的程序代码 |
| 0x1FFF F000 | 系统存储器 | 存储BootLoader,用于串口下载 | |
| 0x1FFF F800 | 选项字节 | 存储一些独立于程序代码的配置参数 | |
| RAM | 0x2000 0000 | 运行内存SRAM | 存储运行过程中的临时变量 |
| 0x4000 0000 | 外设寄存器 | 存储各个外设的配置参数 | |
| 0xE000 0000 | 内核外设寄存器 | 存储内核各个外设的配置参数 |
DMA框图

DMA2仅存在于大容量产品和互联型产品。
DMA简化结构图

DMA请求

数据宽度与对齐

数据转运+DMA示意图

ADC扫描模式+DMA

DMA教程代码实例:
#include "stm32f10x.h" // Device headeruint16_t MyDMA_Size; //定义全局变量,用于记住Init函数的Size,供Transfer函数使用/*** 函 数:DMA初始化* 参 数:AddrA 原数组的首地址* 参 数:AddrB 目的数组的首地址* 参 数:Size 转运的数据大小(转运次数)* 返 回 值:无*/
void MyDMA_Init(uint32_t AddrA, uint32_t AddrB, uint16_t Size)
{MyDMA_Size = Size; //将Size写入到全局变量,记住参数Size/*开启时钟*/RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); //开启DMA的时钟/*DMA初始化*/DMA_InitTypeDef DMA_InitStructure; //定义结构体变量DMA_InitStructure.DMA_PeripheralBaseAddr = AddrA; //外设基地址,给定形参AddrADMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; //外设数据宽度,选择字节DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Enable; //外设地址自增,选择使能DMA_InitStructure.DMA_MemoryBaseAddr = AddrB; //存储器基地址,给定形参AddrBDMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; //存储器数据宽度,选择字节DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //存储器地址自增,选择使能DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; //数据传输方向,选择由外设到存储器DMA_InitStructure.DMA_BufferSize = Size; //转运的数据大小(转运次数)DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; //模式,选择正常模式DMA_InitStructure.DMA_M2M = DMA_M2M_Enable; //存储器到存储器,选择使能DMA_InitStructure.DMA_Priority = DMA_Priority_Medium; //优先级,选择中等DMA_Init(DMA1_Channel1, &DMA_InitStructure); //将结构体变量交给DMA_Init,配置DMA1的通道1/*DMA使能*/DMA_Cmd(DMA1_Channel1, DISABLE); //这里先不给使能,初始化后不会立刻工作,等后续调用Transfer后,再开始
}/*** 函 数:启动DMA数据转运* 参 数:无* 返 回 值:无*/
void MyDMA_Transfer(void)
{DMA_Cmd(DMA1_Channel1, DISABLE); //DMA失能,在写入传输计数器之前,需要DMA暂停工作DMA_SetCurrDataCounter(DMA1_Channel1, MyDMA_Size); //写入传输计数器,指定将要转运的次数DMA_Cmd(DMA1_Channel1, ENABLE); //DMA使能,开始工作while (DMA_GetFlagStatus(DMA1_FLAG_TC1) == RESET); //等待DMA工作完成DMA_ClearFlag(DMA1_FLAG_TC1); //清除工作完成标志位
}
AD+DMA教程代码实例:
#include "stm32f10x.h" // Device headeruint16_t AD_Value[4]; //定义用于存放AD转换结果的全局数组/*** 函 数:AD初始化* 参 数:无* 返 回 值:无*/
void AD_Init(void)
{/*开启时钟*/RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE); //开启ADC1的时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //开启GPIOA的时钟RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); //开启DMA1的时钟/*设置ADC时钟*/RCC_ADCCLKConfig(RCC_PCLK2_Div6); //选择时钟6分频,ADCCLK = 72MHz / 6 = 12MHz/*GPIO初始化*/GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure); //将PA0、PA1、PA2和PA3引脚初始化为模拟输入/*规则组通道配置*/ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_55Cycles5); //规则组序列1的位置,配置为通道0ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 2, ADC_SampleTime_55Cycles5); //规则组序列2的位置,配置为通道1ADC_RegularChannelConfig(ADC1, ADC_Channel_2, 3, ADC_SampleTime_55Cycles5); //规则组序列3的位置,配置为通道2ADC_RegularChannelConfig(ADC1, ADC_Channel_3, 4, ADC_SampleTime_55Cycles5); //规则组序列4的位置,配置为通道3/*ADC初始化*/ADC_InitTypeDef ADC_InitStructure; //定义结构体变量ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; //模式,选择独立模式,即单独使用ADC1ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; //数据对齐,选择右对齐ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; //外部触发,使用软件触发,不需要外部触发ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; //连续转换,使能,每转换一次规则组序列后立刻开始下一次转换ADC_InitStructure.ADC_ScanConvMode = ENABLE; //扫描模式,使能,扫描规则组的序列,扫描数量由ADC_NbrOfChannel确定ADC_InitStructure.ADC_NbrOfChannel = 4; //通道数,为4,扫描规则组的前4个通道ADC_Init(ADC1, &ADC_InitStructure); //将结构体变量交给ADC_Init,配置ADC1/*DMA初始化*/DMA_InitTypeDef DMA_InitStructure; //定义结构体变量DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&ADC1->DR; //外设基地址,给定形参AddrADMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; //外设数据宽度,选择半字,对应16为的ADC数据寄存器DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //外设地址自增,选择失能,始终以ADC数据寄存器为源DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)AD_Value; //存储器基地址,给定存放AD转换结果的全局数组AD_ValueDMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; //存储器数据宽度,选择半字,与源数据宽度对应DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //存储器地址自增,选择使能,每次转运后,数组移到下一个位置DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; //数据传输方向,选择由外设到存储器,ADC数据寄存器转到数组DMA_InitStructure.DMA_BufferSize = 4; //转运的数据大小(转运次数),与ADC通道数一致DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; //模式,选择循环模式,与ADC的连续转换一致DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; //存储器到存储器,选择失能,数据由ADC外设触发转运到存储器DMA_InitStructure.DMA_Priority = DMA_Priority_Medium; //优先级,选择中等DMA_Init(DMA1_Channel1, &DMA_InitStructure); //将结构体变量交给DMA_Init,配置DMA1的通道1/*DMA和ADC使能*/DMA_Cmd(DMA1_Channel1, ENABLE); //DMA1的通道1使能ADC_DMACmd(ADC1, ENABLE); //ADC1触发DMA1的信号使能ADC_Cmd(ADC1, ENABLE); //ADC1使能/*ADC校准*/ADC_ResetCalibration(ADC1); //固定流程,内部有电路会自动执行校准while (ADC_GetResetCalibrationStatus(ADC1) == SET);ADC_StartCalibration(ADC1);while (ADC_GetCalibrationStatus(ADC1) == SET);/*ADC触发*/ADC_SoftwareStartConvCmd(ADC1, ENABLE); //软件触发ADC开始工作,由于ADC处于连续转换模式,故触发一次后ADC就可以一直连续不断地工作
}
相关文章:
STM32标准库学习笔记-9.DMA 直接存储器存取
参考教程:【STM32入门教程-2023版 细致讲解 中文字幕】 DMA(Direct Memory Access) DMA(Direct Memory Access)直接存储器存取DMA可以提供外设和存储器或者存储器和存储器之间的高速数据传输,无须CPU干预…...
ubuntu VCS+verdi安装遇到的一些问题
主体流程:https://blog.51cto.com/u_15346322/4995147 我的是Ubuntu22.4 安装目录问题 执行 ./installer -gui 只能安装到home 或者 sudo ./setup.sh -install_as_root 能安装到/usr/ 目录 运行 vcs 出现 bin/sh: Illegal option -h sudo rm -f /bin/sh sudo…...
使用Poi-tl对word模板生成动态报告
一、pom依赖问题: <dependency> <groupId>com.deepoove</groupId> <artifactId>poi-tl</artifactId> <version>1.12.2</version> </dependency> 使用 poi-tl 的 1.12.2版本,如果使用了poi依赖&#x…...
day45-dynamic programming-part12-8.16
tasks for today: 1. 115.不同的子序列 2. 583.两个字符串选的删除操作 3. 72.编辑距离 4. 总结编辑两个序列关系的问题 ------------------------------------------------------------------- 1. 115.不同的子序列 In this practice, it is necessary to compare with t…...
C# String的方法
目录 #region 知识点九 字符串切割 #region 知识点一 字符串指定位置获取 #region 知识点二 字符串拼接 #region 知识点三 正向查找字符位置 #region 知识点四 反向查找指定字符串位置 #region 知识点五 移除指定位置后的字符 #region 知识点六 替换指定字符串 #region 知识点七…...
Oracle RAC vs Clusterware vs ASM
Oracle RAC vs Clusterware vs ASM Oracle RACCache FusionRAC后台进程自动负载管理DBA管理工具Oracle ClusterwareCRS组件HAS组件管理工具Oracle ASMASM实例ASM磁盘组镜像和故障组ASM磁盘ASM文件Oracle RAC RAC即Real Application Clusters,是一种Oracle高可用部署架构。Orac…...
“华为杯”第十五届中国研究生数学建模竞赛-F题:机场新增卫星厅对中转旅客影响的研究
目录 摘 要: 一、 问题重述 1.1 研究背景 1.2 已知信息 1.3 需要解决的问题 二、 模型假设 三、 符号说明 四、 问题一模型的建立与求解 4.1 问题描述与分析 4.2 模型的求解 4.3 求解结果与分析 五、 问题二模型的建立与求解 5.1 问题描述与分析 5.2 模型的求解 5.3 求解结果与…...
正点原子linux开发板 qt程序交叉编译执行
1.开发板光盘 A-基础资料->5、开发工具->1、交叉编译器->fsl-imx-x11-glibc-x86_64-meta-toolchain-qt5-cortexa7hf-neon-toolchain-4.1.15-2.1.0.sh 拷贝到 Ubuntu 虚拟机 用文件传输系统或者共享文件夹传输到linux虚拟机 用ls -l查看权限,如果是白色的使…...
聚星文社和虹猫哪个好
聚星文社和虹猫是两个不同的公司,各有各的特点。下面是它们各自的优点: 聚星文社:Docshttps://docs.qq.com/doc/DRU1vcUZlanBKR2xy 聚星文社是一家传媒公司,专注于出版漫画、动画、小说等内容,拥有丰富的IP资源和创作…...
三十八、【人工智能】【机器学习】【监督贝叶斯网络(Bayesian Networks)学习】- 算法模型
系列文章目录 第一章 【机器学习】初识机器学习 第二章 【机器学习】【监督学习】- 逻辑回归算法 (Logistic Regression) 第三章 【机器学习】【监督学习】- 支持向量机 (SVM) 第四章【机器学习】【监督学习】- K-近邻算法 (K-NN) 第五章【机器学习】【监督学习】- 决策树…...
[书生大模型实战营][L0][Task1] Linux 远程连接 InternStudio
[书生大模型实战营][Task1] Linux 远程连接 InterStudio 1. 申请 InterStudio 账号 https://studio.intern-ai.org.cn/console/dashboard 2. ssh 生成公匙与密匙 使用 ssh-gen 生成公匙与密匙 # 1. ssh-gen ssh-gen# 2. 查看生成的文件 ls ~/.ssh# 3. 打开生成的公匙&#…...
【vue教程】六. Vue 的状态管理
目录 往期列表本章涵盖知识点回顾Vuex 的基本概念什么是 Vuex?为什么需要 Vuex? Vuex 的核心概念stategettersmutationsactionsmodules Vuex 的安装和基本使用安装 Vuex创建 store在 Vue 应用中使用 store在组件中访问和修改状态 Vuex 的模块化模块化的好…...
无人机电子调速器详解!!!
电子调速器是无人机动力系统中的关键组件,主要负责将电池提供的直流电转换为交流电,并精确控制电机的转速,从而实现对无人机飞行状态的精确控制。以下是对无人机电子调速器的详细解析: 一、基本功能与原理 功能: 直…...
Clichouse数据导出导入(数据迁移)
背景:因为clickhouse数据持续增加,导致服务器磁盘不够使用,云服务器的系统盘不能扩容,所以只能进行迁移 连接clickhouse查看要迁移那些数据库 rootjcdata:~/buckup/clickhouse# clickhouse-client -udefault --password 123456…...
Java基础——IService.class 中查询数据方法list() 源码剖析及使用
下面详细介绍Mybatis-plus 的默认服务IService.class 中的查询数据的方法及使用。 方法定义及其详细介绍 default List<T> list(Wrapper<T> queryWrapper) default List<T> list(Wrapper<T> queryWrapper) {return this.getBaseMapper().selectList(q…...
MySQL库表的基本操作
目录 1.库的操作1.1 创建数据库1.2字符集和校验规则①查看系统默认字符集以及校验规则②查看数据库支持的字符集③查看数据库支持的字符集校验规则④校验规则对数据库的影响 1.3操纵数据库①查看数据库②显示创建的数据库的语句③修改数据库④数据库删除⑤备份和恢复⑥还原注意…...
基于ResNeSt50神经网络模型的蘑菇分类设计与实现,使用注意力机制,分别对应8种蘑菇进行训练预测
该项目旨在利用卷积神经网络(Convolutional Neural Networks, CNN)实现蘑菇的自动识别。通过对蘑菇图片进行分类,可以有效地将不同类型的蘑菇进行辨别,对于蘑菇的研究、食用安全及自然保护等方面具有重要意义。本文将详细描述项目…...
[论文翻译]使用 BERT 检测安卓恶意软件
Android Malware Detection Using BERT Souani B, Khanfir A, Bartel A, et al. Android malware detection using bert[C]//International Conference on Applied Cryptography and Network Security. Cham: Springer International Publishing, 2022: 575-591. 摘要 在本文…...
LabVIEW滚动轴承故障诊断系统
滚动轴承是多种机械设备中的关键组件,其性能直接影响整个机械系统的稳定性和安全性。由于轴承在运行过程中可能会遇到多种复杂的工作条件和环境因素影响,这就需要一种高效、准确的故障诊断方法来确保机械系统的可靠运行。利用LabVIEW开发的故障诊断系统&…...
【论文分享】通过社交媒体图片和计算机视觉分析城市绿道的使用情况
城市街道为路面跑步提供了环境。本次给大家带来一篇SCI论文的全文翻译!该论文提出了一种非参数方法,使用机器学习模型来预测路面跑步强度。该论文提供了关于路面跑步的实证证据,并突出了规划者、景观设计师和城市管理者在设计适于跑步的城市街…...
C++ 与 事务多版本并发控制(MVCC):在 C++ 存储内核中利用时间戳排序实现无锁读写冲突控制
各位开发者、架构师,以及对高性能并发系统充满热情的同仁们,大家好!今天,我们将深入探讨一个在现代数据库和存储系统中至关重要的主题:多版本并发控制(MVCC),并聚焦于如何在 C 存储内…...
3步打造waifu2x-caffe轻量化部署方案:图像增强绿色版打包全流程
3步打造waifu2x-caffe轻量化部署方案:图像增强绿色版打包全流程 【免费下载链接】waifu2x-caffe waifu2xのCaffe版 项目地址: https://gitcode.com/gh_mirrors/wa/waifu2x-caffe waifu2x-caffe是一款基于深度学习的图像增强工具,能够通过AI算法实…...
机器学习模型配置终极指南:yaml-cpp如何彻底解决参数管理难题 [特殊字符]
机器学习模型配置终极指南:yaml-cpp如何彻底解决参数管理难题 🚀 【免费下载链接】yaml-cpp A YAML parser and emitter in C 项目地址: https://gitcode.com/gh_mirrors/ya/yaml-cpp 在当今的机器学习开发中,YAML配置文件已成为管理复…...
深度学习概率分布与核心运算 —— 概率论的工具箱(八)
1. 定位导航 上一篇回答了"为什么需要概率"。本篇开始构建概率论的基本工具箱——这些工具是理解后续所有内容(损失函数、贝叶斯推断、生成模型、信息论)的数学基础。 本篇覆盖六大核心概念:随机变量与概率分布(PMF/PDF)、边缘概率、条件概率、链式法则、独立…...
交通顶刊TR Part C 2026年5月论文导读(上)
一期刊简介Transportation Research Part C (TR-C): Emerging Technologies 是交通领域顶刊,由 Elsevier 出版,中科院与 JCR 均为 1 区,近年影响因子约8–9.6。该期刊以交通系统为核心,聚焦 AI、大数据、运筹学等新兴技术对交通规…...
数据库基础知识----数据库大观
这里写目录标题绪论发展历程数据模型三层模式两层映像基本概念关系数据库简介(基本术语)关系模型组成数据结构数据操纵数据完整性规则关系代数五个基本操作并差笛卡尔积投影(π)选择四个组合操作交连接除法关系数据库语言----SQL简…...
Zenith.NET v0.0.7:Metal 后端落地,.NET GPU 抽象的跨平台旅程
为什么要做 Zenith.NET?.NET 生态有不少图形相关的库——绑定层如 Silk.NET、Vortice,抽象层如 Veldrid、Evergine。但现有的抽象层要么停留在较旧的 API 版本(如 DX11/OpenGL),要么是商业引擎的一部分,难以…...
Flowable建模器汉化实战:如何用SecurityUtils绕过官方认证实现本地化部署
Flowable建模器深度汉化与本地化部署实战指南 当企业级工作流系统需要深度定制时,Flowable建模器的原生界面往往成为用户体验的瓶颈。本文将揭示一套完整的解决方案,从界面元素汉化到认证体系重构,最终实现开箱即用的中文建模环境。 1. 汉化…...
AI识别人,是最落后的能力——真正的智能,不是“看见你是谁”,而是“知道你在哪里”
AI识别人,是最落后的能力——真正的智能,不是“看见你是谁”,而是“知道你在哪里”一、开头:行业正在集体卷错方向过去十年,AI行业一直在做一件事:👉 更准确地“识别人”我们不断看到这些突破&a…...
s2-pro新手避坑指南:3步搞定文本转语音,常见问题全解析
s2-pro新手避坑指南:3步搞定文本转语音,常见问题全解析 1. s2-pro语音合成快速入门 s2-pro是Fish Audio开源的专业级语音合成工具,它能将文字转换成自然流畅的语音。对于刚接触语音合成的新手来说,这个工具特别友好,…...
