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

经验分享 | STM32H7系列ADC DMA传输异常案例分享

[复制链接]
攻城狮Melo 发布时间:2026-4-21 14:22

有人使用STM32H743芯片开发产品,用到片内ADC3外设。他发现当使用DMA做ADC结果的传输时总是失败,具体就是根本看不到结果的搬运。但如果使用查询方式来获取ADC结果又是正常的。

基于这个反映,我们自然怀疑到他的跟ADC及DMA有关的相关配置可能有问题。

这里主要有两个地方要注意,一个就是在ADC基本配置里的coversion Data Management Mode项,所选择的要跟所采用的ADC结果的数据提取方式一致,即是通过CPU去查询DR寄存器还是通过DMA去获取。其中通过DMA获取又分两种情况,以匹配DMA传输的Normaol模式和Circular模式。在STM32CubeMx的配置里就像下图所示的One Shot Mode和Circular Mode。

image.png

另外还有个地方要注意,就是存放ADC结果的内存地址别给错了。STM32H7系列的通用DMA1、DMA2是没法访问TCM RAM的,这是很容易出错的一个地方。即不能将存放ADC结果的缓冲区安排在TCM区域,否则,看不到ADC结果就不足为奇了。下图是STM32H743内部系统框架图。

image.png

关于DTCM的地址区间不难从手册中找到,见下图中红色圈里的信息。

image.png

除了强调上面两点外,我还基于STM32H743芯片和CubeMx工具为其做了一个演示例程供其参考。

后来,该客户依然反馈说,即使参照我给的例程还是没有ADC结果出来。他把他的ADC缓存地址也给我看了,是安排在AXI RAM区,按理通用DMA应该可以访问得到。下图是客户提供的信息:

image.png

这就有点奇怪,我这边测试明明是OK的,到了他那边怎么就没结果了呢?

我反复检查相关配置,看看哪个地方可能没提醒到。

我在检查ADC3的DMA配置时,无意中发现在给ADC事件安排DMA时,除了DMA1 DMA2可以安排外,BDMA也是可以使用的。尽管我给了他参考例程,还是怀疑他在这个地方可能选择的是BDMA,而不是DMA1/2。经过跟客户再次确认,他还真是忽略这里了,选择的正是BDMA。

image.png

为什么这里选择BDMA就没法实现ADC的结果传输呢?我们还得看看STM32H743芯片的系统框图和总线互联图。下面是STM32H743内部主从设备总线互联图。

image.png

依据上面的系统总线互联框图也不难看出,BDMA能访问的RAM区只能是SRAM4和Backup RAM,没法访问AXI SRAM或SRAM1/2/3。现在客户则是将ADC存储缓冲安排在AXI RAM区。当他将ADC的DMA配置里DMA选择为DMA1后就可以看到结果了。

不过,很快他又发现一个有趣的问题,结果虽然有了,但发现在ARM KEIL IDE调试窗口的实时输出结果跟预期似乎不一致,ADC输出结果的显示感觉跟DMA传输的数据个数有关!

我刚开始给其提供演示例程时,选择了ADC3的3个内部通道,配置为字到字的循环传输模式,传输长度设置为9。我的确是看到输出结果了,而且初步判断结果也是正常的。

image.png

但当我尝试将DMA传输长度改为3或6时,果真发现问题了,这时根本没办法在实时窗口看到ADC结果,或者说结果都是0值。见下图:

image.png

这是怎么回事呢?回头看刚才传输数据长度为9时,DMA搬运的ADC结果其实也是不符合预期的。因为DMA配置在循环模式,虽然前8个数据是正确的,但第9个数据始终是0,明显不合理。为什么会这样呢?难度跟DCache有关?

保持DMA传输长度为9及其它配置不变的条件下,先直接禁用DCACHE测试看看结果怎么样。

image.png

显然,测试结果完全正常。看来目前实时显示窗口的显示的确跟DCache有关。

目前存放ADC结果的缓冲区被安排在AXI SRAM,它是支持DCache的,系统默认使用Cache回写策略。DMA在不停修改实际缓冲里的数据,而调试器借助CPU往往读取的是DCache里的数据。为了避免CPU读取的Cache数据跟实际缓存里的数据不一致的情形发生,我们就有必要针对存放ADC结果的内存区域做合适的MPU配置,令相应区域不使用Cache,将其配置成NonCacheable。或者说不改变其Cacheable属性,而是适时地、针对性地对存放ADC数据的Cache行做数据维护操作。

关于MPU的配置这里就不展开聊了,毕竟这里的重点是做些应用提醒。我们可以在每次DMA的传输完成中断里针对ADC数据的Cache行做数据一致性维护操作,这样的话,DMA每传输一轮新数据后,都令CPU都去读实际缓存的数据并再行Cache分配,保证每次读到的数据都是新的。

见下图,当我每次在DMA传输完成中断里做了Cache行的数据维护操作后,具体就是对相应的DCache行做失效操作,此时显示结果就正常了,也不再挑DMA的传输长度了。

image.png

本文基于一个客户咨询出发,分享了使用STM32H7系列ADC的DMA传输时可能遇到的一些问题及注意事项。虽是些小问题,据个人经验来看,也是产品研发人员基于STM32H7系列从事产品开发过程中遇到的高频应用问题,分享出来希望帮到更多的人。

文章出处:茶话MCU

收藏 评论0 发布时间:2026-4-21 14:22

举报

0个回答

所属标签

相似分享

官网相关资源

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