|
有人咨询STM32H7系列的MDMA如何与通用DMA实现联动传输。我这里准备了一个简单的应用场景,演示一下实现过程。 测试过程中我使用STM32H743开发板,IDE是ARM KEIL。用TIMER触发ADC,ADC EOC事件触发通用DMA将结果搬运到AXI SRAM缓冲区。基于该DMA的传输完成事件,触发MDMA的启动。MDMA再将AXI SRAM的数据搬运到DTCM区的缓冲区,交由CPU做后期数据高速处理。这里重点演示DMA/MDMA的联动传输过程 演示过程中的数据搬运流程如下图示意:
我使用STM32CubeMx进行配置。TIMER的配置就不贴图了。ADC的配置如下,重点关注其DMA配置。
根据配置不难看出ADC申请的是通用DMA1的Stream 0,缩写为DMA1-S0。 当DMA1将16个ADC结果搬运到AXI SRAM后,产生DMA传输完成事件。该事件去触发MDMA,让MDMA接着将存放于AXI SRAM的ADC结果搬运到DTCM缓存区。 在下面测试代码里,ADC_Result数组用于存放ADC结果,MDMA将其搬运到DTCM域的InDTCM数组。 先选择Buffer Transfer触发模式。基于该模式,MDMA每收到1个触发事件就完成一批Buffer Transfer Length字节长度的数据搬运。这里要搬运16个字,即64字节的数据。详见下图MDMA配置。红色注释是我加上去的,用于解释和提醒。
相关的用户代码如下。我在AXI RAM和DTCM RAM区通过指定地址方式定义了两个数组。其中,TIMER用来触发ADC。下面的define宏只是为了简化字符串长度,没啥特别意思。【手机模式下,代码可以左右滑动】
运行后的结果如下,MDMA成功实现将AXI RAM的数据搬运到DTCM区域。
当然,我们也可以选择MDMA的Block Transfer触发模式。即MDMA每收到触发事件,就做1个块的数据搬运。ADC的DMA配置完全不动。下面是MDMA的相应配置,注意此时的配置跟上面配置的细小差异。
此时的Block Data Length对应16个字的数据,即64字节。至于那个Buffer Transfer Length,设置为源数据宽度的倍数即可,比方4或8都行。 用户代码跟上面的完全一样,运行后的测试结果也完全符合预期,就不重复贴图了。 现在我们对上面测试做些小变动后再行验证。 假设ADC结果基于半字传输和存储,还是传输16个数据后停止搬运并产生DMA传输完成事件触发MDMA。ADC的DMA配置调整如下,这次是半字到半字的方式。
而MDMA这边呢,将储存于AXI RAM的ADC结果也按半字方式提取并存放到DTCM区。我们先看看MDMA基于Buffer Transfer触发模式的配置与实现。见下图配置:
用户代码除了局部数据有微调外,其它跟前面一样。我只把有变动的代码贴过来,注意数据宽度定义和Buffer Transfer 长度的字节数的变化。 uint16_t ADC_Result[16] attribute((section(".ARM.__at_0x24000400"))) ; uint16_t InDTCM[16] attribute((section(".ARM.__at_0x20000000"))) ; HAL_MDMA_Start_IT(&hmdmaCH0,(uint32_t)&ADC_Result[0], (uint32_t)&InDTCM[0], 16*2, 1); 运行基于当前配置和调整过的测试代码,结果完全正常。见如下结果截图:
保持ADC的配置及上面用户代码完全不变,若将MDMA的触发模式改成BLOCK 传输模式也是可以的。MDMA的参考配置如下,MDMA的源端和目的端数据宽度仍然都是16位。
基于上面配置的运行结果也完成正常。 在沿用目前ADC配置和用户执行代码的基础上,如果MDMA传输时,源端数据宽度是16位,而目的端的数据宽度按32位存放呢? 不妨还是以Block传输模式为例来演示这个场景。MDMA的参考配置如下:【注意:源端是16位,目的端是32位。还有注意Data Alignment那个选项】
用户代码稍作改动:【修改了InDTCM数组的数据宽度定义,其它不动】
测试结果如下,MDMA将16位源数据搬到目的端后通过补0形成32位数据,当然结果是正确的。
在刚才测试的基础上,若希望源端数据按照目的端数据宽度以打包的方式进行传输是否可以呢?即把源端每两个16位数据组合为一个32位数据存放到目的端,这样的话,源端的16个16位数据变成目的端的8个32位数据。如下图结果所示:
我们还是以BLOCK传输模式为例看看相关配置,此时只需在上面的MDMA配置的基础上稍作如下调整即可实现。见下图配置红色圆圈和方框圈出的地方,其它不动。
因此时代码方面完全没有改动,不难想象,最终目的端缓冲将多出8个空缺。 针对STM32H7系列MDMA与通用DMA的联动演示主要使用了MDMA的Buffer Transfer 和Block Transfer两种触发模式,也是两种基本的、常用的MDMA传输方式。还有另外两种模式,今天就不聊了。 就此打住,下次再聊~! |
经验分享 | STM32H7 LPTIM+DMAMUX+BDMA应用演示
经验分享 | STM32H7系列ADC DMA传输异常案例分享
STM32H750 基于 Keil 制作 QSPI 外部 Flash 下载算法 全流程实操指南
STM32H743 BDMA+LPTIM+LPUART应用演示
经验分享 | STM32H723 SPI 通讯异常排查:实时观察窗口的 “隐形干扰” 解决方案
经验分享 | STM32H7 SPI NSS 脉冲模式灵活应用:解决外置 ADC 通信干扰问题
经验分享 | STM32H7 双核调试配置:STM32CubeIDE 下 M7+M4 协同调试实操
经验分享 | STM32H7 TouchGFX 花屏速解:更换 HyperRAM 后 latency 值适配实操
经验分享 | STM32H743 BDMA+LPTIM+LPUART应用演示
经验分享 | STM32H7Sx MCE 加密解密:外部存储安全防护全解析
微信公众号
手机版