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

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依赖问题&#xff1a; <dependency> <groupId>com.deepoove</groupId> <artifactId>poi-tl</artifactId> <version>1.12.2</version> </dependency> 使用 poi-tl 的 1.12.2版本&#xff0c;如果使用了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查看权限&#xff0c;如果是白色的使…...

聚星文社和虹猫哪个好

聚星文社和虹猫是两个不同的公司&#xff0c;各有各的特点。下面是它们各自的优点&#xff1a; 聚星文社&#xff1a;Docshttps://docs.qq.com/doc/DRU1vcUZlanBKR2xy 聚星文社是一家传媒公司&#xff0c;专注于出版漫画、动画、小说等内容&#xff0c;拥有丰富的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&#xff1f;为什么需要 Vuex&#xff1f; Vuex 的核心概念stategettersmutationsactionsmodules Vuex 的安装和基本使用安装 Vuex创建 store在 Vue 应用中使用 store在组件中访问和修改状态 Vuex 的模块化模块化的好…...

无人机电子调速器详解!!!

电子调速器是无人机动力系统中的关键组件&#xff0c;主要负责将电池提供的直流电转换为交流电&#xff0c;并精确控制电机的转速&#xff0c;从而实现对无人机飞行状态的精确控制。以下是对无人机电子调速器的详细解析&#xff1a; 一、基本功能与原理 功能&#xff1a; 直…...

Clichouse数据导出导入(数据迁移)

背景&#xff1a;因为clickhouse数据持续增加&#xff0c;导致服务器磁盘不够使用&#xff0c;云服务器的系统盘不能扩容&#xff0c;所以只能进行迁移 连接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种蘑菇进行训练预测

该项目旨在利用卷积神经网络&#xff08;Convolutional Neural Networks, CNN&#xff09;实现蘑菇的自动识别。通过对蘑菇图片进行分类&#xff0c;可以有效地将不同类型的蘑菇进行辨别&#xff0c;对于蘑菇的研究、食用安全及自然保护等方面具有重要意义。本文将详细描述项目…...

[论文翻译]使用 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滚动轴承故障诊断系统

滚动轴承是多种机械设备中的关键组件&#xff0c;其性能直接影响整个机械系统的稳定性和安全性。由于轴承在运行过程中可能会遇到多种复杂的工作条件和环境因素影响&#xff0c;这就需要一种高效、准确的故障诊断方法来确保机械系统的可靠运行。利用LabVIEW开发的故障诊断系统&…...

【论文分享】通过社交媒体图片和计算机视觉分析城市绿道的使用情况

城市街道为路面跑步提供了环境。本次给大家带来一篇SCI论文的全文翻译&#xff01;该论文提出了一种非参数方法&#xff0c;使用机器学习模型来预测路面跑步强度。该论文提供了关于路面跑步的实证证据&#xff0c;并突出了规划者、景观设计师和城市管理者在设计适于跑步的城市街…...

业务系统对接大模型的基础方案:架构设计与关键步骤

业务系统对接大模型&#xff1a;架构设计与关键步骤 在当今数字化转型的浪潮中&#xff0c;大语言模型&#xff08;LLM&#xff09;已成为企业提升业务效率和创新能力的关键技术之一。将大模型集成到业务系统中&#xff0c;不仅可以优化用户体验&#xff0c;还能为业务决策提供…...

【位运算】消失的两个数字(hard)

消失的两个数字&#xff08;hard&#xff09; 题⽬描述&#xff1a;解法&#xff08;位运算&#xff09;&#xff1a;Java 算法代码&#xff1a;更简便代码 题⽬链接&#xff1a;⾯试题 17.19. 消失的两个数字 题⽬描述&#xff1a; 给定⼀个数组&#xff0c;包含从 1 到 N 所有…...

可靠性+灵活性:电力载波技术在楼宇自控中的核心价值

可靠性灵活性&#xff1a;电力载波技术在楼宇自控中的核心价值 在智能楼宇的自动化控制中&#xff0c;电力载波技术&#xff08;PLC&#xff09;凭借其独特的优势&#xff0c;正成为构建高效、稳定、灵活系统的核心解决方案。它利用现有电力线路传输数据&#xff0c;无需额外布…...

聊一聊接口测试的意义有哪些?

目录 一、隔离性 & 早期测试 二、保障系统集成质量 三、验证业务逻辑的核心层 四、提升测试效率与覆盖度 五、系统稳定性的守护者 六、驱动团队协作与契约管理 七、性能与扩展性的前置评估 八、持续交付的核心支撑 接口测试的意义可以从四个维度展开&#xff0c;首…...

Redis的发布订阅模式与专业的 MQ(如 Kafka, RabbitMQ)相比,优缺点是什么?适用于哪些场景?

Redis 的发布订阅&#xff08;Pub/Sub&#xff09;模式与专业的 MQ&#xff08;Message Queue&#xff09;如 Kafka、RabbitMQ 进行比较&#xff0c;核心的权衡点在于&#xff1a;简单与速度 vs. 可靠与功能。 下面我们详细展开对比。 Redis Pub/Sub 的核心特点 它是一个发后…...

保姆级教程:在无网络无显卡的Windows电脑的vscode本地部署deepseek

文章目录 1 前言2 部署流程2.1 准备工作2.2 Ollama2.2.1 使用有网络的电脑下载Ollama2.2.2 安装Ollama&#xff08;有网络的电脑&#xff09;2.2.3 安装Ollama&#xff08;无网络的电脑&#xff09;2.2.4 安装验证2.2.5 修改大模型安装位置2.2.6 下载Deepseek模型 2.3 将deepse…...

【学习笔记】erase 删除顺序迭代器后迭代器失效的解决方案

目录 使用 erase 返回值继续迭代使用索引进行遍历 我们知道类似 vector 的顺序迭代器被删除后&#xff0c;迭代器会失效&#xff0c;因为顺序迭代器在内存中是连续存储的&#xff0c;元素删除后&#xff0c;后续元素会前移。 但一些场景中&#xff0c;我们又需要在执行删除操作…...

elementUI点击浏览table所选行数据查看文档

项目场景&#xff1a; table按照要求特定的数据变成按钮可以点击 解决方案&#xff1a; <el-table-columnprop"mlname"label"名称"align"center"width"180"><template slot-scope"scope"><el-buttonv-if&qu…...

通过MicroSip配置自己的freeswitch服务器进行调试记录

之前用docker安装的freeswitch的&#xff0c;启动是正常的&#xff0c; 但用下面的Microsip连接不上 主要原因有可能一下几个 1、通过下面命令可以看 [rootlocalhost default]# docker exec -it freeswitch fs_cli -x "sofia status profile internal"Name …...

Neko虚拟浏览器远程协作方案:Docker+内网穿透技术部署实践

前言&#xff1a;本文将向开发者介绍一款创新性协作工具——Neko虚拟浏览器。在数字化协作场景中&#xff0c;跨地域的团队常需面对实时共享屏幕、协同编辑文档等需求。通过本指南&#xff0c;你将掌握在Ubuntu系统中使用容器化技术部署该工具的具体方案&#xff0c;并结合内网…...