关于STM32 DMAMUX模块具体的应用示例代码

发布者:JoyfulHarmony最新更新时间:2024-08-05 来源: elecfans关键字:STM32  用户代码 手机看文章 扫描二维码
随时随地手机看文章

个人也发现,虽然STM32片内的DMAMUX不是什么新模块,似乎还是很多人并不太熟悉。这里借机聊聊这方面的内容,重点演示相关功能的实现,以供参考。

其实,DMAMUX作为一个外设模块,操作它并不需要添加太多用户代码,尤其是当我们基于STM32CubeMx进行配置时。它的主要功能就是为各种DMA请求做DMA传输通道的灵活调度与安排,并配合DMA使用,我们可以把它看成DMA控制器的前端拓展。


DMAMUX模块大体上由DMA请求转发通道和DMA请求发生器组成,其中每个DMA请求转发通道还配有同步控制单元。DMA请求发生器可以基于某些事件产生DMA请求申请DMA传输。至于同步控制单元,可以简单理解为每个DMA请求最终是否被转发出去的一个控制开关,就像蓄势待发的田径选手有时还得等信号枪响一样。

1eed29d4-ea3e-11ee-a297-92fbcf53809c.png?imageView2/2/w/1000

上图是DMAMUX与DMA功能关联示意图,供理解参考。关于STM32 DMAMUX的基本功能及特性,可以阅读本公众号的另外一篇分享笔记《STM32芯片中的DMAMUX是干啥用的?》,这里就不对其功能原理及特性赘述了。

下面使用STM32G0系列Nucleo板重点演示其主要功能的实现。实验会用到PC13的外部中断功能,LPTIM1的输出功能、USART2外设和USART1外设基于DMA方式的通信功能。

1efdff48-ea3e-11ee-a297-92fbcf53809c.png?imageView2/2/w/1000

我们先看看DMAMUX的路由转发功能。

DMAMUX对DMA请求做路由转发是其基本功能,应该也是设计它的初衷。我们平常使用该功能时是没啥明显感觉的,就像我们通过HUB让USB设备跟PC通信一样,尤其是在基于STM32CubeMx进行配置时。如果说,你之前用过其它不带DMAMUX的STM32系列的DMA功能,再来使用带DMAMUX的DMA功能时,使用STM32CubeMx工具做DMA配置,会发现DMA可选通道突然变多且可随意选择。不妨看看下图基于STM32F4【不带DMAMUX】和STM32G0系列【内置DMAMUX】对UART2接收进行DMA配置时的情形,差别一目了然。

1fd1a596-ea3e-11ee-a297-92fbcf53809c.png?imageView2/2/w/1000

说到这里,顺便介绍下目前内置DMAMUX模块的STM32系列。我从ST官方应用笔记AN5224截图过来,下面这些系列都内置了DMAMUX。后面我以STM32G0芯片演示相关功能的实现。

1fe54196-ea3e-11ee-a297-92fbcf53809c.png?imageView2/2/w/1000

我们接下来来看看DMAMUX的第2个功能---DMA请求生成功能。它能基于某些特定事件产生DMA请求,请求的个数可以从1~32之间。这里的特定事件主要是指各种外部中断事件和少数几个路由通道的DMA事件以及LPTIM的输出事件。

这里使用STM32G071的PC13外部中断功能。每次按键事件经DMAMUX的DMA generator申请10个DMA请求,让DMA将内存字符数据传输到UART2的数据发送寄存器,最终在串口终端显示字符串“Key In!”。下面是有关PC13外部中断和DMAMUX generator的配置。【注:下面代码都是基于HAL库的】

1ff3eb1a-ea3e-11ee-a297-92fbcf53809c.png?imageView2/2/w/1000

使用UART2将字符串输出到串口终端,UART2的基本配置如下:

20085cd0-ea3e-11ee-a297-92fbcf53809c.png?imageView2/2/w/1000

创建工程,添加下面用户代码【基于HAL库】后即可验证结果:

201efe0e-ea3e-11ee-a297-92fbcf53809c.png?imageView2/2/w/1000

现在继续看看DMAMUX的同步功能。针对该功能,这里再做两个小演示。

第一个演示,用DMA传输完成产生触发事件去触发另一个DMA传输操作。具体来说,我开启UART2的DMA方式收、发功能,从串口终端发送数据给UART2,UART2通过DMA方式收到数据后,基于DMAMUX产生DMA事件,触发UART2将刚才收到的数据回显到串口终端。从串口终端发送数据到再回显于串口终端一气呵成,无须CPU参与。

UART2的基本参数配置跟前面一样,不重复贴图了。下面是有关UART2 DMA接收的配置:

202ea3d6-ea3e-11ee-a297-92fbcf53809c.png?imageView2/2/w/1000

在上面UART2 DMA接收配置中,使能了DMA 事件功能。该事件将作为UART2 DMA发送的同步事件。下图是有关UART2 DMA发送的配置,启用了同步触发功能。

20446586-ea3e-11ee-a297-92fbcf53809c.png?imageView2/2/w/1000

基于上面配置创建工程,添加必要代码即可验证结果。结果就是UART2每收到10个数据后立即通过DMA方式回显在串口终端。见下面截图:

206292c2-ea3e-11ee-a297-92fbcf53809c.png?imageView2/2/w/1000

最后再演示一个DMAMUX同步功能的实现案例。使用LPTIM的输出产生周期性的触发事件,作为UART1 DMA发送的同步事件。每次LPTIM产生触发事件,UART1就通过DMA发送一串字符出去。这里使用UART1自发自收来验证。显然,UART1每发送一串字符出去也同时收到同一串字符。下面是LPTIM1的参数配置,没啥过多解释的.

20741f38-ea3e-11ee-a297-92fbcf53809c.png?imageView2/2/w/1000

下面是有关UART1 DMA方式收发功能的配置,重点关注其DMA发送的配置。开启UART1 DMA发送的同步触发,LPTIM输出的上沿作为其同步事件。至于UART1 DMA接收功能保持常规配置即可,不做同步也不产生DMA输出事件。

208559d8-ea3e-11ee-a297-92fbcf53809c.png?imageView2/2/w/1000

基于上面配置,添加几行用户代码即可验证结果。参看下面截图:

209be202-ea3e-11ee-a297-92fbcf53809c.png?imageView2/2/w/1000

基于上面配置,如果我们不启动LPTIM1的话,可以发现UART1永远不会发送数据,自然它也接收不到任何数据。

关于STM32 DMAMUX的应用演示就介绍到这里。不难看出,使用DMAMUX相关功能及特性时,所需应用代码不多也不复杂,关键在原理及配置。DMAMUX有时会给我们的应用带来一些意想不到的方便,可以善加利用。


关键字:STM32  用户代码 引用地址:关于STM32 DMAMUX模块具体的应用示例代码

上一篇:STM32 TIM—基本定时器
下一篇:STM32裸机编程的基础知识(1)

推荐阅读最新更新时间:2026-03-21 10:22

STM32 启动代码 __main 与用户主程序 main() 的区别
1、__main 作用 __main函数是C/C++运行时库的一个函数,嵌入式系统在进入应用主程序之前必须有一个初始化的过程,使用__main标号引导系统时必须将应用程序的入口定义为main()。 在初始化的过程中,__main函数的作用主要有两点: 1) 完成对映像文件的初始化操作 a、映像文件 链接器把多个目标文件链接成一个映像文件。 b、加载地址和执行地址 映像文件可以有两种地址:加载地址和执行地址。 加载地址是映像文件在存储器中的存储地址;执行地址就是映像文件运行时的地址。 c、加载域和执行域 文件加载的存储区叫加载域,文件运行的存储区叫执行域。 d、从加载地址到执行地址 在结构比较简单的系统中,加载地址就是执
[单片机]
<font color='red'>STM32</font> 启动<font color='red'>代码</font> __main 与<font color='red'>用户</font>主程序 main() 的区别
STM32一种从用户代码调用系统存储器中Bootloader 的方法
前言 大家都知道,任何STM32 都包含有一块系统存储器(System Memory),里边存储着内部的启动代码Bootloader。不同的 STM32 型号所支持的用于升级代码的通讯口不尽相同,需要参考应用笔记AN2606。但是,有一个问题避免不了,那就是如 何进入System Memory 去执行Bootloader?通常的办法都是将BOOT1 和BOOT0 进行配置:BOOT0 拉高,BOOT1 拉低 (有些型号的BOOT1 由选项字节nBOOT1 进行控制)。可是在一些产品中,由于外观的要求,往往不方便在外边开口去放 置按键或跳线来改变BOOT 脚的电平。而且,用户并不想自己写IAP 代码,觉得麻烦。特别是一些产品,需要使
[单片机]
<font color='red'>STM32</font>一种从<font color='red'>用户</font><font color='red'>代码</font>调用系统存储器中Bootloader 的方法
基于STM32F4系列芯片和STM32CubeF4 HAL库组织和添加用户代码
我们在MCU的嵌入式应用开发过程中,有时需要做些较大量的数据传输和适时处理,此时使用DMA的双缓冲模式可能是个不错的选择。这样既可以保障数据的连续、流畅传输,又能保障数据的及时处理【包括数据更新】,同时又能减轻CPU的负荷。 常有人想使用STM32 DMA的双缓冲模式,但又觉得实现起来似乎有点困难,也不太容易找到现存的例程。我这里就基于STM32F4芯片及Cube库简单地演示下实现过程。 STM32的DMA硬件双缓冲模式,只支持从外设到内存或从内存到外设两种应用场景,且工作在循环模式。内存到内存是不支持双缓冲模式的,当然它也不支持DMA循环模式。【下图截取于STM32F4的参考手册】 关于STM32 DMA双缓冲模式实
[单片机]
基于STM32F4系列芯片和STM32CubeF4 HAL库组织和添加<font color='red'>用户</font><font color='red'>代码</font>
STM32F091空片编程后怎样直接运行用户代码
问题 某客户在其产品的设计中,使用了STM32F091RCT6。客户使用ST-Link 对STM32F091RCT6 进行编程,发现对空片进行编程之后,必须要重新上电才能运行用户代码;但是如果不是空片,则编程后就可以直接运行用户代码。由于客户的测试系统是直接烧写完芯片后在不断电的情况直接进入测试模式,如果空片烧写需要断电的话,带来一定的麻烦。客户希望搞明白这件事,并希望找到办法,能在空片编程后也可以直接运行用户代码。 调研 1.还原问题 在这里,使用带有STM32F091RCT6 的NUCLEO-F091RC 板来进行问题还原,将此Nucleo 板通过USB 线连接到电脑。打开STM32 ST-LINK Utility,点击“C
[单片机]
STM32F091空片编程后怎样直接运行<font color='red'>用户</font><font color='red'>代码</font>
MPLAB X 设置用户程序代码偏移
当编写用户代码时(用boot来引导启动),我们都需要设置用户代码的偏移。 例如:boot 引导用户代码的入口地址为0x2000。 下面我们需要把用户代码下载到0x2000地址处(设置如下图所示)。 设置后的编译结果: 可以看到代码的入口地址变成了0x2000,低优先级中断入口变成了0x2018。
[单片机]
MPLAB X 设置<font color='red'>用户</font>程序<font color='red'>代码</font>偏移
基于STM32的矿井作业环境监测系统设计与实现
针对煤矿开采中瓦斯爆炸等严重安全隐患,设计了一套矿井安全系统。该系统实时监测瓦斯浓度、温度、火情、粉尘等环境参数,自动控制除尘、灭火、通风等设备,以保障矿井安全。通过WiFi将数据传输至监控平台,并支持APP远程监控与操作,从而提升应急响应速度和管理效率。 PART 01 系统总体结构 系统实现了对矿井内甲烷气体体积分数、粉尘浓度、火焰及温湿度等关键参数的实时采集与分析;并通过预设的自动控制策略触发联动设备,实现安全隐患的快速响应与主动防控。同时,支持数据远程传输至云端平台,并通过机智云APP提供实时监控、报警及远程操控功能,为矿井安全管理提供高效、可靠的技术支撑。系统总体结构如图1所示。 PART 02 系统详细设计
[单片机]
基于<font color='red'>STM32</font>的矿井作业环境监测系统设计与实现
使用 Keil Studio for Visual Studio Code开发 STM32 设备
Keil Studio是 Arm 最新一代的集成开发环境(IDE),将嵌入式开发工具直接集成到了 Visual Studio Code 中。作为 µVision 的后继者,它提供了现代化的特性,包括与业界工具的无缝集成、版本控制支持,以及用于 CI 工作流的命令行接口(CLI)。 Keil Studio 作为 Arm Keil MDK 6的一部分,为基于 Cortex M 的微控制器提供了全面支持,其中包括 STMicroelectronics 广泛的 STM32 产品系列。它将 Arm 编译器的可靠性与成熟度、广泛的器件支持,与 Visual Studio Code 的灵活性和可扩展性有机结合在一起。 快速上手 借
[单片机]
使用 Keil Studio for Visual Studio Code开发 <font color='red'>STM32</font> 设备
如何用 STM32 FLASH 实现等效 100 万次擦写的 EEPROM 功能?
在单片机开发中, 数据存储 是一个绕不开的话题。EEPROM因其非易失性存储特性,常用于保存配置参数等数据。 然而,EEPROM的擦写次数通常有限,以STM32为例,STM32L0、STM32L4自带的EEPROM一般 10万次 左右,而很多单片机并不内置EEPROM,这时候,利用单片机的FLASH存储器来模拟EEPROM就成为了一个高性价比的解决方案,但,FLASH的擦写次数一般在 1万次 左右,这个我们可以通过ST的官方数据手册看到: 1万次,在很多场景下并不够。 今天,老宇哥跟大家一起探讨,如何用单片机FLA
[嵌入式]
如何用 <font color='red'>STM32</font> FLASH 实现等效 100 万次擦写的 EEPROM 功能?
小广播
最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

厂商技术中心

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

 
机器人开发圈

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2026 EEWORLD.com.cn, Inc. All rights reserved