stm32 DMA
目录
简介
框图
DMA请求
DMA通道
DMA优先级
DMA 数据
外设到存储器
存储器到外设
存储器到存储器
传多少,单位是什么
传输完成
hal库代码
标准库代码
简介
CPU根据代码内容执行指令,这些众多指令中,有的用于计算、有的用于控制程序、有的用于转移数据等。 其中转移数据的指令,尤其是转移大量数据,会占用大量CPU。如果是把外设A的数据,传给外设B,这种情况其实不需要CPU一直参与,只需在A、 B之间创建个通道,让它们自己传输即可。DMA(Direct Memory Access)直接内存访问,可以大大减轻CPU工作量。这就DMA设计的目的,减少大量数据转移指令消耗CPU, DMA专注数据转移, CPU专注计算、控制。
DMA主要实现将A处的数据直接搬运到B处,场景如下三种:内存到外设、外设到内存、内存到内存。无论是何种方式,都是先设置好DMA的数据源地址、数据目标地址、数据长度。设置好后,启动DMA就可以自动的把数据从源地址依次传输到目标地址。
框图
STM32F1系列有两个DMA控制器, 其中DMA2仅存在于大容量产品中。 DMA1有7个通道, DMA2有5个通道,总计12个通道。这里的通道可以理解为传输数据的一种管道。
DMA请求
外设想通过DMA传输数据,需要先向DMA控制器发送请求。 外设向DMA控制器发送请求后, DMA控制器根据通道优先级依次处理请求,控制器会给外设一个应答信号,当外设应答后且 DMA 控制器收到应答信号之后,就会启动 DMA 的传输,直到传输完毕
DMA 有 DMA1 和 DMA2 两个控制器, DMA1 有 7 个通道, DMA2 有 5 个通道,不同的 DMA 控制器的通道对应着不同的外设请求
DMA通道
不同的外设,向不同DMA的不同通道发送请求。比如ADC1想使用DMA,应向DMA1的通道1发送请求。 DMA1的通道1,可以接收多个外设的请求( ADC1、 TIM2_CH3、TIM4_CH1),但同一时间只能接收一个
DMA优先级
当多个DMA通道,同时发来请求时,这个就由仲裁器管理。仲裁器管理 DMA 通道请求分为两个阶段。第一阶段属于软件阶段,获取软件配置DMA_CCRx寄存器设置的优先级,有 4 个等级:非常高,高,中和低四个优先级依次响应。第二阶段属于硬件阶段,当软件配置优先级相同时,硬件优先级高的(通道编号小的)优先响应。DMA1 控制器拥有高于 DMA2 控制器的优先级。
DMA 数据
外设到存储器
比如ADC 采集配置,DMA 外设寄存器的地址对应的就是 ADC数据寄存器的地址, DMA 存储器的地址就是我们自定义的变量(用来接收存储 AD 采集的数据)的地址。方向设置外设为源地址。
存储器到外设
比如串口向电脑端发送数据,DMA 外设寄存器的地址对应的就是串口数据寄存器的地址, DMA 存储器的地址就是我们自定义的变量(相当于一个缓冲区,用来存储通过串口发送到电脑的数据)的地址。方向设置外设为目标地址。
存储器到存储器
比如内部 FLASH 向内部 SRAM 复制数据,DMA 外设寄存器的地址对应的就是内部 FLASH(把内部 FALSH 当作外设来看)的地址, DMA存储器的地址就是我们自定义的变量(相当于一个缓冲区,用来存储来自内部 FLASH 的数据)的地址。方向我们设置外设(即内部FLASH)为源地址。跟上面不一样的是,这里需要把DMA_CCR 位 14: MEM2MEM:存储器到存储器模式配置为 1,启动 M2M 模式
传多少,单位是什么
一个 32 位的寄存器,DMA一次可传输的最多65536个数据, 要想数据传输正确,源和目标地址存储的数据宽度还必须一致,如串口数据寄存器是 8 位的,所以要发送的数据也必须是 8 位。
数据要想有条不紊的从一个地方搬到另外一个地方,还必须正确设置两边数据指针的增量模式。以串口向电脑发送数据为例,要发送的数据很多,每发送完一个,那么存储器的地址指针就应该加 1,而串口数据寄存器只有一个,那么外设的地址指针就固定不变。具体的数据指针的增量模式由实际情况决定
传输完成
DMA在传输过程中会产生3个传输标志:半完成标志( Half Transfer, HT) 、完成标志( Transfer Complete, TC) 和错误标志( Transfer Error, TE) 。数据什么时候传输完成,可以通过查询标志位或者通过中断的方式来鉴别
每个标志会产生对应的中断信号,如果使能了三种类型的中断后,则会产生中断。假如有N个数据待DMA传输,设置到原地址和目的地址后,当收到一个传输请求DMA就会从原地址取出一个数据传输到目的地址,如果地址是外设则地址保持不变,若地址是内存则传输完一个数据之后地址自增一个数据单位。在传输过程中如果发生意外错误则会产生一个错误中断信号,当传输完成一半则会产生半传输完成中断,当全部数据都传输完成则会产生一个传输完成中断。
hal库代码
DMA_HandleTypeDef hdma;
/*标志位*/
__IO uint32_t transferErrorDetected;
__IO uint32_t transferCompleteDetected;/*发送缓冲区*/
uint32_t src_buffer[20] ={0x1234, 0x5678, 0x9876, 0x4586, 0xABCD,0x5678, 0xABCD, 0x4586, 0x4586, 0xABCD,0xABCD, 0x5678, 0x4586, 0x9876, 0x1234,0x1234, 0xABCD, 0x9876, 0x5678, 0xABCD,};
/*接收*/
uint32_t dst_buffer[20] = {0};#if 1
/*如果DMA传输完成且不发生错误,则在此函数将传输完成标志置一*/
static void tranfer_complete(DMA_HandleTypeDef *dma)
{transferCompleteDetected=1;
}
/*如果DMA传输过程中发生错误,则在此函数中将传输错误标志置一*/
static void tranfer_error(DMA_HandleTypeDef *dma)
{transferErrorDetected=1;
}
#endifvoid dma_init(void)
{/*使能DMA1时钟*/__HAL_RCC_DMA1_CLK_ENABLE();hdma.Init.Direction = DMA_MEMORY_TO_MEMORY;/*内存到内存模式*/hdma.Init.PeriphInc = DMA_PINC_ENABLE;/*外设地址递增*/hdma.Init.MemInc = DMA_MINC_ENABLE;/*内存地址递增*/hdma.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;/*外设数据以字对齐*/hdma.Init.MemDataAlignment = DMA_MDATAALIGN_WORD;/*内存数据以字对齐*/hdma.Init.Mode = DMA_NORMAL;/*正常传输模式,传输一次*/hdma.Init.Priority = DMA_PRIORITY_VERY_HIGH;/*传输优先级非常高*/hdma.Instance = DMA1_Channel1;/*选择DMA通道1*//*初始化配置*/HAL_DMA_Init(&hdma);
#if 1/*注册传输完成和传输错误回调函数*/HAL_DMA_RegisterCallback(&hdma, HAL_DMA_XFER_CPLT_CB_ID,tranfer_complete);/*传输完成的回调函数 ID*/HAL_DMA_RegisterCallback(&hdma, HAL_DMA_XFER_ERROR_CB_ID, tranfer_error);/*DMA中断优先级*/HAL_NVIC_SetPriority(DMA1_Channel1_IRQn , 0 , 0);HAL_NVIC_EnableIRQ(DMA1_Channel1_IRQn);
#endif}#if 1
/*DMA1通道1中断的中断处理函数*/
void DMA1_Channel1_IRQHandler(void)
{HAL_DMA_IRQHandler(&hdma);
}/*初始化 DMA_Channel1,配置为内存-内存模式,每次搬移一个 word 即 4bytes*/
void dma_start(uint32_t *SrcAddress, uint32_t *DstAddress, uint16_t DataLength)
{HAL_DMA_Start_IT(&hdma,(uint32_t)SrcAddress,(uint32_t)DstAddress,DataLength);
}
#endif
标准库代码
/*时钟使能的dma*/
#define CLK_DMAx RCC_AHBPeriph_DMA1
/*串口对应的DMA请求通道*/
#define USART_TX_DMA_CHANNEL DMA1_Channel4
/*外设接收数据寄存器地址*/
#define USART_DR_ADDRESS (USART1_BASE+0x04)
/*一次发送的数据量 <65535*/
#define SIZE 5000static uint32_t i;
uint8_t send_buf[SIZE];void uart_dma_init(void)
{DMA_InitTypeDef DMA_InitStruct;/*开启时钟*/RCC_AHBPeriphClockCmd(CLK_DMAx,ENABLE);/*设置DMA源地址:串口数据寄存器地址*/DMA_InitStruct.DMA_PeripheralBaseAddr = USART_DR_ADDRESS;/*内存地址,使DMA传输的数据从`send_buf`所指向的内存开始*/DMA_InitStruct.DMA_MemoryBaseAddr = (uint32_t)send_buf;/*方向:内存到外设*/DMA_InitStruct.DMA_DIR = DMA_DIR_PeripheralDST;/*传输大小*/DMA_InitStruct.DMA_BufferSize = SIZE;/*外设地址不增*/DMA_InitStruct.DMA_PeripheralInc = DMA_PeripheralInc_Disable;/*内存地址只增*/DMA_InitStruct.DMA_MemoryInc = DMA_MemoryInc_Enable;/*外设数据单位*/DMA_InitStruct.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;/*内存数据单位,每次传输的数据大小为1字节*/DMA_InitStruct.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;/*dma模式,一次或循环*/DMA_InitStruct.DMA_Mode = DMA_Mode_Normal;/*一次*///DMA_InitStruct.DMA_Mode = DMA_Mode_Circular;/*循环*//*优先级:中*/DMA_InitStruct.DMA_Priority = DMA_Priority_Medium;/*内存到内存的传输*/DMA_InitStruct.DMA_M2M = DMA_M2M_Disable;/*配置DMA通道*/DMA_Init(USART_TX_DMA_CHANNEL,&DMA_InitStruct);/*使能DMA*/DMA_Cmd(USART_TX_DMA_CHANNEL,ENABLE);/*使能USART的DMA传输功能,具体传输方向为USART的发送(Tx)方向。*///USART_DMACmd(USARTx,USART_DMAReq_Tx,ENABLE);
}/*发送*/
void dma_send(void)
{/*填充要发送的数据*/for(i=0;i<SIZE;i++){send_buf[i] = 'p';}
/*开启传输,USARTx表示要配置的USART接口,USART_DMAReq_Tx表示启用发送数据的DMA请求*/USART_DMACmd(USARTx,USART_DMAReq_Tx,ENABLE);}
相关文章:

stm32 DMA
目录 简介 框图 DMA请求 DMA通道 DMA优先级 DMA 数据 外设到存储器 存储器到外设 存储器到存储器 传多少,单位是什么 传输完成 hal库代码 标准库代码 简介 CPU根据代码内容执行指令,这些众多指令中,有的用于计算、有的用于控制程…...

厦门万宾科技智能井盖监测仪器的作用如何?
越来越多的人们希望改善生活,走出农村走出大山,前往城市之中居住。由此城市的人口和车辆在不断增加,与之而来的是城市的交通压力越来越大,时常会出现道路安全隐患,这给城市未来发展和智慧城市建设都带来一定的难题&…...

【带头学C++】----- 三、指针章 ---- 3.5 字符串与指针
在 C 中,字符串可以通过指针来表示和操作。C 的字符串是由字符组成的字符数组,而指针则用于引用和操作内存中的数据。 1. 字符数组 1. 字符数组: 字符数组是最基本的字符串表示方式。可以使用字符数组来存储字符串,并使用指针来引用它。字符…...
二十三种设计模式全面解析-深入解析桥接模式:解锁软件设计的灵活性
在软件开发中,我们经常面临需要处理多个不同维度变化的情况。这些变化可能涉及多个维度的组合,导致类的爆炸性增长和难以维护的代码。在这种情况下,桥接模式(Bridge Pattern)是一种强大的设计模式,能够帮助…...

Ansible中的角色使用
Ansible中的角色使用: 目录 一、ansible角色简介 二、roles目录结构 三、roles的创建 四、roles的使用 1、书写task主任务 2、触发器模块 3、变量模块 4、j2模块 5、files模块 6、启用模块 7、执行playbook 五、控制任务执行顺序 六、多重角色的使用 一…...
C通过指针访问数组元素
在C语言中,数组除了通过数组索引访问,也可以通过指针来访问数组中的元素。下面是一个简单的例子: #include <stdio.h>int main() {int array[5] {1, 2, 3, 4, 5};int *ptr array; // 指向数组的第一个元素的指针printf("数组元…...

程序员成长树
- 10年以后我在做什么? 成为项目负责人(管理事、管理人) - 如何处理同事的关系: 平时生活中最简单的一句问候,闲暇时间的聊天了解,互帮互助 - miss yang: - 1、软件UI设计 - 2、需求分析 - 3、协调推进任务的安排 …...

数字化时代,数据仓库是什么?有什么用?
在激烈的市场竞争和全新的数字经济共同作用下,数字化转型成为了大多数企业的共识,也是获取数字经济的最佳方式。在整个数据价值生产链路中,数据仓库的主要作用就是中心化分发,将原始数据与数据价值挖掘活动隔离。 所有的原始数据…...
android NetworkMonitor和ConnectivityService记录
一、NetworkMonitor packages/modules/NetworkStack/src/com/android/server/connectivity/NetworkMonitor.java 网络上都叫网络可用性校验,在WIFI和数据(以太网切换中使用) 有多个状态机 方法:isCaptivePortal 11-03 12:01:17…...

Technology strategy Pattern 学习笔记1-Context: Architecture and Strategy
Context: Architecture and Strategy 1 Architect and Strategist 1.1 three primary concerns of the architect 1.1.1 Contain entropy(熵-混乱程度,不确定性,惊奇程度,不可预测性,信息量等等) The architect wh…...

数据结构-顺序表
1.线性表 线性表(linear list)是n个具有相同特性的数据元素的有限序列。 线性表是一种在实际中广泛使用的数据结构,常见的线性表:顺序表、链表、栈、队列、字符串... 线性表在逻辑上是线性结构,也就说是连续的一条直线…...

数据结构与算法 | 第三章:栈与队列
本文参考网课为 数据结构与算法 1 第三章栈,主讲人 张铭 、王腾蛟 、赵海燕 、宋国杰 、邹磊 、黄群。 本文使用IDE为 Clion,开发环境 C14。 更新:2023 / 11 / 5 数据结构与算法 | 第三章:栈与队列 栈概念示例 实现顺序栈类定义…...

oracle查询数据库内全部的表名、列明、注释、数据类型、长度、精度等
Oracle查询数据库内全部的表名、列明、注释、数据类型、长度、精度 SELECT a.TABLE_NAME 表名, row_number() over(partition by a.TABLE_NAME order by a.COLUMN_NAME desc) 字段顺序,a.COLUMN_NAME 列名, b.COMMENTS 注释,a.DATA_TYPE 数据类型, a.DATA_LENGTH 长度,DATA_SC…...

数据可视化:折线图
1.初看效果 (1)效果一 (2)数据来源 2.JSON数据格式 其实JSON数据在JAVA后期的学习过程中我已经是很了解了,基本上后端服务器和前端交互数据大多是采用JSON字符串的形式 (1)JSON的作用 &#…...

Python语言_matplotlib包_共80种--全平台可用
Python语言_matplotlib包_共80种–全平台可用 往期推荐: Python语言_single_color_共140种–全平台可用 R语言_RColorBrewer包–全平台可用 R语言gplots包的颜色索引表–全平台可用 R语言中的自带的调色板–五种–全平台可用 R语言657中单色colors颜色索引表—全平台…...

OpenFeign 的超时重试机制以及底层实现原理
目录 1. 什么是 OpenFeign? 2. OpenFeign 的功能升级 3. OpenFeign 内置的超时重试机制 3.1 配置超时重试 3.2 覆盖 Retryer 对象 4. 自定义超时重试机制 4.1 为什么需要自定义超时重试机制 4.2 如何自定义超时重试机制 5. OpenFeign 超时重试的底层原理 5…...
redis安装
redis安装 mac下直接安装 mac下安装redis还是很简单的(其实mac下安装什么软件都挺简单的,brew啥都有) brew install redis 之后就是漫长的等待,下了好久,终于下载完了 修改redis.conf中的配置 # 后台启动daemonize yes 启动服务端 redis-serv…...

VM虚拟机逆向 --- [NCTF 2018]wcyvm 复现
文章目录 前言题目分析 前言 第四题了,搞定,算是独立完成比较多的一题,虽然在还原汇编的时候还是很多问题。 题目分析 代码很简单,就是指令很多。 opcode在unk_6021C0处,解密的数据在dword_6020A0处 opcode [0x08, …...

2024天津理工大学中环信息学院专升本机械设计制造自动化专业考纲
2024年天津理工大学中环信息学院高职升本科《机械设计制造及其自动化》专业课考试大纲《机械设计》《机械制图》 《机械设计》考试大纲 教 材:《机械设计》(第十版),高等教育出版社,濮良贵、陈国定、吴立言主编&#…...

华为OD机试 - 服务失效判断 - 逻辑分析(Java 2023 B卷 200分)
目录 专栏导读一、题目描述二、输入描述三、输出描述1、输入2、输出3、说明 四、解题思路五、Java算法源码六、效果展示1、输入2、输出3、说明 华为OD机试 2023B卷题库疯狂收录中,刷题点这里 专栏导读 本专栏收录于《华为OD机试(JAVA)真题&a…...
CVPR 2025 MIMO: 支持视觉指代和像素grounding 的医学视觉语言模型
CVPR 2025 | MIMO:支持视觉指代和像素对齐的医学视觉语言模型 论文信息 标题:MIMO: A medical vision language model with visual referring multimodal input and pixel grounding multimodal output作者:Yanyuan Chen, Dexuan Xu, Yu Hu…...

盘古信息PCB行业解决方案:以全域场景重构,激活智造新未来
一、破局:PCB行业的时代之问 在数字经济蓬勃发展的浪潮中,PCB(印制电路板)作为 “电子产品之母”,其重要性愈发凸显。随着 5G、人工智能等新兴技术的加速渗透,PCB行业面临着前所未有的挑战与机遇。产品迭代…...

【Redis技术进阶之路】「原理分析系列开篇」分析客户端和服务端网络诵信交互实现(服务端执行命令请求的过程 - 初始化服务器)
服务端执行命令请求的过程 【专栏简介】【技术大纲】【专栏目标】【目标人群】1. Redis爱好者与社区成员2. 后端开发和系统架构师3. 计算机专业的本科生及研究生 初始化服务器1. 初始化服务器状态结构初始化RedisServer变量 2. 加载相关系统配置和用户配置参数定制化配置参数案…...

【Zephyr 系列 10】实战项目:打造一个蓝牙传感器终端 + 网关系统(完整架构与全栈实现)
🧠关键词:Zephyr、BLE、终端、网关、广播、连接、传感器、数据采集、低功耗、系统集成 📌目标读者:希望基于 Zephyr 构建 BLE 系统架构、实现终端与网关协作、具备产品交付能力的开发者 📊篇幅字数:约 5200 字 ✨ 项目总览 在物联网实际项目中,**“终端 + 网关”**是…...
【C++从零实现Json-Rpc框架】第六弹 —— 服务端模块划分
一、项目背景回顾 前五弹完成了Json-Rpc协议解析、请求处理、客户端调用等基础模块搭建。 本弹重点聚焦于服务端的模块划分与架构设计,提升代码结构的可维护性与扩展性。 二、服务端模块设计目标 高内聚低耦合:各模块职责清晰,便于独立开发…...

华硕a豆14 Air香氛版,美学与科技的馨香融合
在快节奏的现代生活中,我们渴望一个能激发创想、愉悦感官的工作与生活伙伴,它不仅是冰冷的科技工具,更能触动我们内心深处的细腻情感。正是在这样的期许下,华硕a豆14 Air香氛版翩然而至,它以一种前所未有的方式&#x…...
Web中间件--tomcat学习
Web中间件–tomcat Java虚拟机详解 什么是JAVA虚拟机 Java虚拟机是一个抽象的计算机,它可以执行Java字节码。Java虚拟机是Java平台的一部分,Java平台由Java语言、Java API和Java虚拟机组成。Java虚拟机的主要作用是将Java字节码转换为机器代码&#x…...
在鸿蒙HarmonyOS 5中使用DevEco Studio实现企业微信功能
1. 开发环境准备 安装DevEco Studio 3.1: 从华为开发者官网下载最新版DevEco Studio安装HarmonyOS 5.0 SDK 项目配置: // module.json5 {"module": {"requestPermissions": [{"name": "ohos.permis…...

在 Spring Boot 中使用 JSP
jsp? 好多年没用了。重新整一下 还费了点时间,记录一下。 项目结构: pom: <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://ww…...
Kafka主题运维全指南:从基础配置到故障处理
#作者:张桐瑞 文章目录 主题日常管理1. 修改主题分区。2. 修改主题级别参数。3. 变更副本数。4. 修改主题限速。5.主题分区迁移。6. 常见主题错误处理常见错误1:主题删除失败。常见错误2:__consumer_offsets占用太多的磁盘。 主题日常管理 …...