|
有人使用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。
另外还有个地方要注意,就是存放ADC结果的内存地址别给错了。STM32H7系列的通用DMA1、DMA2是没法访问TCM RAM的,这是很容易出错的一个地方。即不能将存放ADC结果的缓冲区安排在TCM区域,否则,看不到ADC结果就不足为奇了。下图是STM32H743内部系统框架图。
关于DTCM的地址区间不难从手册中找到,见下图中红色圈里的信息。
除了强调上面两点外,我还基于STM32H743芯片和CubeMx工具为其做了一个演示例程供其参考。 后来,该客户依然反馈说,即使参照我给的例程还是没有ADC结果出来。他把他的ADC缓存地址也给我看了,是安排在AXI RAM区,按理通用DMA应该可以访问得到。下图是客户提供的信息:
这就有点奇怪,我这边测试明明是OK的,到了他那边怎么就没结果了呢? 我反复检查相关配置,看看哪个地方可能没提醒到。 我在检查ADC3的DMA配置时,无意中发现在给ADC事件安排DMA时,除了DMA1 DMA2可以安排外,BDMA也是可以使用的。尽管我给了他参考例程,还是怀疑他在这个地方可能选择的是BDMA,而不是DMA1/2。经过跟客户再次确认,他还真是忽略这里了,选择的正是BDMA。
为什么这里选择BDMA就没法实现ADC的结果传输呢?我们还得看看STM32H743芯片的系统框图和总线互联图。下面是STM32H743内部主从设备总线互联图。
依据上面的系统总线互联框图也不难看出,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。我的确是看到输出结果了,而且初步判断结果也是正常的。
但当我尝试将DMA传输长度改为3或6时,果真发现问题了,这时根本没办法在实时窗口看到ADC结果,或者说结果都是0值。见下图:
这是怎么回事呢?回头看刚才传输数据长度为9时,DMA搬运的ADC结果其实也是不符合预期的。因为DMA配置在循环模式,虽然前8个数据是正确的,但第9个数据始终是0,明显不合理。为什么会这样呢?难度跟DCache有关? 保持DMA传输长度为9及其它配置不变的条件下,先直接禁用DCACHE测试看看结果怎么样。
显然,测试结果完全正常。看来目前实时显示窗口的显示的确跟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的传输长度了。
本文基于一个客户咨询出发,分享了使用STM32H7系列ADC的DMA传输时可能遇到的一些问题及注意事项。虽是些小问题,据个人经验来看,也是产品研发人员基于STM32H7系列从事产品开发过程中遇到的高频应用问题,分享出来希望帮到更多的人。 文章出处:茶话MCU |
经验分享 | STM32H7 LPTIM+DMAMUX+BDMA应用演示
经验分享 | STM32H7 MDMA 与通用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 加密解密:外部存储安全防护全解析
微信公众号
手机版