你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

经验分享 | STM32H7 LPTIM+DMAMUX+BDMA应用演示

[复制链接]
攻城狮Melo 发布时间:2026-4-23 17:24

有人使用STM32H7系列芯片的LPTIM事件触发DMAMUX申请BDMA传输,发现没法产生BDMA传输完成中断。我这里使用STM32H743开发板演示一下实现过程。具体实现是这样的:

使用片内LPTIM5的超时唤醒事件,触发DMAMUX模块,申请BDMA的传输,让BDMA将存于SRAM4的内存数据搬运到GPIO,并通过示波器观察GPIO_G0脚的高低电平翻转输出。大致功能流程如下图所示:

image.png

现在使用STM32CubeMx开始配置。下面是片内LPTIM5的基本配置: image.png

下面是BDMA相关的配置,BDMA的请求由DMAMUX的generator产生,而DMAMUX generator又由LPTIM5的唤醒事件触发。BDMA的传输方向是从内存到外设,目的端及源端的访问宽度都是两字节的半字。

为了便于查看演示效果,我将BDMA配置在循环模式。 image.png

做好各种配置后,创建基于STM32HAL库的c代码工程。此处测试时所用IDE是ARM keil v6。下面代码定义了一个8元素的内存数组,用于BDMA的内存访问。另外声明并定义了BDMA channel0的传输完成中断的回调函数,同时定义了用于在回调函数里自增的一个32位变量。

__attribute__((section(".ARM.__at_0x38000000"))) uint16_t ToGPIO_Data[]={0,1,0,1,0,1,0,1};  //定义用于传输给GPIOG的8个数据,位于SRAM4区
uint32_t cnt_BDMA_Cplt; //该变量将在BDMA完成中断的回调函数里实现自增效果
void BDMA_cb_Handle( DMA_HandleTypeDef *hdma);// BDMA完成中断的回调函数
void BDMA_cb_Handle( DMA_HandleTypeDef *hdma){ cnt_BDMA_Cplt ++;}

在main()里添加的用户代码:

#define LPTIM5_Period (50000)#define LPTIM5_Timeout (25000)
#define Length_BDMA (8)  
hdma_bdma_generator0.XferCpltCallback = BDMA_cb_Handle;
HAL_DMAEx_EnableMuxRequestGenerator(&hdma_bdma_generator0);
HAL_DMA_Start_IT(&hdma_bdma_generator0, (uint32_t)&ToGPIO_Data[0],(uint32_t)&GPIOG->ODR, Length_BDMA);
HAL_LPTIM_TimeOut_Start_IT(&hlptim5, LPTIM5_Period,  LPTIM5_Timeout);
While(1){ }

基于上面配置和用户代码,编译调试OK后,可以看到GPIOG_PIN0脚呈现高低电平的方波输出,符合预期。 image.png

到此基本功能就实现了,现在看看BDMA的传输完成中断能否发生。

在HAL库的 API函数HAL_DMA_Start_IT()里是开启了BDMA的传输完成中断的。但是我发现在CubeMx创建的工程的stm32h7xx.it.c文件里根本就看不到有关BDMA的中断服务函数,另外在MX_BDMA_Init()初始化函数里也没有看到有关BDMA中断的NVIC配置。这样看来,此时显然没法响应BDMA的传输完成中断,怎么会缺少这些东西呢?

再回头看cubeMx那边有关BDMA的配置: image.png

这个地方没有BDMA相关中断的使能配置,难怪创建工程后没有相应的NVIC配置及中断服务函数。感觉这里是CubeMx的一个小bug。

怎么办呢?自己手动添加BDMA channel0的相关中断代码吧。

为了方便省事,我先在CubeMx那边基于ADC3配置了一个BDMA的通道channel 1,在ADC3配置那里使能BDMA channel 1的相关中断,然后我在代码那边再基于该配置修改成BDMA channel 0的。 image.png

在CubeMx这边做了上述配置后,再创建工程。此时我们可以在工程代码的MX_BDMA_Init()初始化函数里看到有关BDMA通道的NVIC配置了,不过此时是针对BDMA channel 1的,我将它改为Channel 0即可。

image.png

另外,我们在stm32h7xx.it.c文件里也可以看到有关BDMA channel 1的中断服务函数,我们将其修改为对应Channel 0的即可。 image.png

在前面介绍用户代码时提到过,我准备了BDMA传输完成中断的用户回调函数void BDMA_cb_Handle( DMA_HandleTypeDef *hdma)。当我手动完成了上述代码调整后就可以发现BDMA Channel 0的传输中断能得到响应了。 image.png

OK,今天的分享交流就到这里,供有心人参考。祝君好运~!

文章出处:茶话MCU

收藏 评论0 发布时间:2026-4-23 17:24

举报

0个回答

所属标签

相似分享

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版