有人使用STM32H7系列的ADC模块,定时器触发ADC,数据通过DMA传输到内存。对某通道连续转换几次后求个平均值。他却发现ADC结果虽没有什么问题,但一批数据出来后就纹丝不动了。DMA传输本来设计成的Circular模式,感觉好像工作在Normal模式,结果显然有点不合理。
鉴于这个现象和所用芯片,估计是因为Cache使用方面的原因,客户也的确使能了Cache。具体怎么回事呢?我们一起来看看。
我这边使用H743Nucleo板和ST免费的STM32CubeIDE。STM32H743片内有个Vrefint信号,电压一般在1.2v左右,用它做ADC的输入信号来测试。用LPTIM触发ADC转换,每读到5个数据就求个平均值。
我这里定义了一个6字大小的数组,uint32_t AdcDataViaDMA [6];前5个位置放实时ADC数据,第6个位置即AdcDataViaDMA [5]存放换算后的最终Vrefint电压平均值,单位是mv。
我们使用STM32CubeMx进行配置。重点看下ADC的配置:[注:ADC是16位的]
生成初始化代码后,添加用户代码。我把数组AdcDataViaDMA【】指定在片内RAM2区域。
__attribute__((section(".AdcDataViaDMA"))) uint32_t AdcDataViaDMA [6];
HAL_ADCEx_Calibration_Start(&hadc3, ADC_CALIB_OFFSET, ADC_SINGLE_ENDED );
HAL_ADC_Start_DMA(&hadc3,(uint32_t*)&AdcDataViaDMA [0], 5);
HAL_LPTIM_PWM_Start(&hlptim2, Period, Pulse);
然后编译调试。同样出现数据纹丝不动的现象。我每次在传输完成中断回调函数里做数据处理。相关处理代码如下图所示:
TIMER不停触发ADC,DMA传输也是循环的,按理数据应该动态改变。即使变化不大,也不至于纹丝不动。【除AdcDataViaDMA [5]外,其它均为AD转换值。】
那是什么原因呢?目前我们是开启了Cache的。
现在数据的大致流程就是,ADC转换结果出来后,DMA将数据写入SRAM,然后CPU读取SRAM里的数据。因为开启了D-Cache,当CPU针对SRAM做读操作时发生读Allocate,相应内存地址的数据被拷贝一份到Cache里。下次CPU再去相应SRAM地址去读取时,因D-Cache里已经有了一份有效数据,即发生Cache命中事件,CPU就直接从Cache读数据,而不读取SRAM了。
所以,尽管后面时间里ADC因TIMER不停触发而产生新数据并被DMA传输到SRAM,但CPU除了第一次外总是从D-Cache取数据,导致该数据永远就是第一次读到的数据而不变。
既然这样,我们可以在CPU每次针对SRAM做了读操作后,对D-Cache相应内容做无效处理,迫使CPU每次要取数据时因Cache Miss而发生读Allocate操作并更新Cache数据,进而保证CPU读到跟内存SRAM里一致的Cache数据。
我在DMA完成中断回调函数里加上一句针对D-Cache作无效操作的代码。如下图红线标注的代码。
然后进行测试,立即可以看到不断实时变化的数据了。【下图我随机截取的几个结果】
不过,请注意这里针对D-Cache相应地址做了无效化处理的代码要放在最前面。你可以将该句试着放在对AdcDataViaDMA [5]赋0语句的后面验证下,看看会有什么现象,要看细致点,不然发现不了问题。顺便提醒,目前所用SRAM区域在没有做MPU配置的情况下,默认为write back加write allocate Cache属性,我在前面贴图时已经圈出来了。有兴趣的话,可以基于上述代码自行进一步探究下,此处就不延伸了。
另外,除了上面的解决办法外,还有就是将上面内存数组所在区域做MPU设置,关闭那部分区域的Cacheable属性。
当这样配置后,之前那句针对Cache无效化的代码就不需要了。生成代码进行测试,结果跟预期一致,数据保持实时动态变化,结果也正常。
上面主要就开启D-Cache后,发生了主设备数据读取不一致的问题给出了些解决办法及思路,同时也算是给出些应用提醒,以后碰到类似问题时可以参考。当然,有人或许会说,完全不开启芯片的D-Cache功能也可以解决问题。诚然,但我们需要综合考虑开发便利性和芯片的性能发挥,尽量就问题做些针对性的处理以充分发挥芯片性能。
上一篇:基于STM32的OLED舵机菜单显示
下一篇:stm32单片机GPIO端口的特点及应用解析
推荐阅读最新更新时间:2024-11-17 11:44
设计资源 培训 开发板 精华推荐
- DER-600 - 45 W 超紧凑型 USB PD 3.0 电源,采用 InnoSwitch3-Pro 及 PowiGaN 和 VIA Labs VP302 控制器
- BW6101超级电容保护均衡均压板
- AM1S-0315SH30Z 1W DC-DC转换器典型应用
- 无线物联网、低功耗 Bluetooth®、4½ 位、100kHz 真正 RMS 数字万用表
- LT1615-1、1 节碱性电池至 3V 升压转换器
- MAXREFDES104#: 健康传感器平台3.0版
- STEVAL-IKR002V5D、SPIRIT1 915-MHz 低数据速率收发器子板
- 使用 NXP Semiconductors 的 MC32BC3770CS 的参考设计
- 用于电池充电器的 1.8V、2.5V DC 至 DC 单路输出电源
- LTC3897EUHF 高效两相 48V 升压转换器的典型应用电路,具有浪涌电流控制、输入电压浪涌保护和过流保护
- 消息称 AMD 将入局手机芯片领域,采用台积电 3nm 工艺
- 英飞凌推出OptiMOS™ Linear FET 2 MOSFET, 赋能先进的热插拔技术和电池保护功能
- SGMII及其应用
- 贸泽开售用于机器人和机器视觉的 STMicroelectronics B-CAMS-IMX模块
- 三星 Exynos 2600 芯片前景堪忧:良率挑战严峻,有被取消量产风险
- 苹果搁置反垄断报告的请求遭印度监管机构拒绝,案件将继续推进
- 2024年Automechanika Shanghai海量同期活动刷新历届记录,汇聚行业智慧,共谋未来发展
- 企业文化分享 如何培养稀缺的硅IP专业人员?SmartDV开启的个人成长与团队协作之旅
- 恩智浦发布首个超宽带无线电池管理系统解决方案
- 北交大本科生探秘泰克先进半导体开放实验室,亲历前沿高科技魅力
- wince6.0中,IE6.0无法自动弹出软键盘
- Sealevel Systems公司8口串行PC/104模块面向串行密集应用
- 求一块LM3S学习板
- USB设备开发中,既然遵循协议2.0的usb接口部件数据传输速率比较高,那么51单片机作为其微控制器,单片机本身的速度会不会成为整个usb速度或性能的瓶颈??
- 什么叫X86开放式构架?
- #eeworld漫画力作#TI MCU漫画,电子小强&永不言休!
- 什么是Aperture Time, Aperture Jitter, Aperture Delay Time?
- 请教430中断问题
- STM8S003F3P6,需两路IIC,如何做
- 气相色谱仪采用PID控温有哪些策略?