为何STM32H7的ADC数据不变

发布时间:2023-09-26  

有人使用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位的]

039f9790-6289-11ed-8abf-dac502259ad0.png

03edf4a8-6289-11ed-8abf-dac502259ad0.png

生成初始化代码后,添加用户代码。我把数组AdcDataViaDMA【】指定在片内RAM2区域。

__attribute__((section(".AdcDataViaDMA")))   uint32_t AdcDataViaDMA [6];

041ddd8a-6289-11ed-8abf-dac502259ad0.png

0440856a-6289-11ed-8abf-dac502259ad0.png

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);

然后编译调试。同样出现数据纹丝不动的现象。我每次在传输完成中断回调函数里做数据处理。相关处理代码如下图所示:

046aa70a-6289-11ed-8abf-dac502259ad0.png

TIMER不停触发ADC,DMA传输也是循环的,按理数据应该动态改变。即使变化不大,也不至于纹丝不动。【除AdcDataViaDMA [5]外,其它均为AD转换值。】

0495e44c-6289-11ed-8abf-dac502259ad0.png

那是什么原因呢?目前我们是开启了Cache的。

05238356-6289-11ed-8abf-dac502259ad0.png

现在数据的大致流程就是,ADC转换结果出来后,DMA将数据写入SRAM,然后CPU读取SRAM里的数据。因为开启了D-Cache,当CPU针对SRAM做读操作时发生读Allocate,相应内存地址的数据被拷贝一份到Cache里。下次CPU再去相应SRAM地址去读取时,因D-Cache里已经有了一份有效数据,即发生Cache命中事件,CPU就直接从Cache读数据,而不读取SRAM了。

05790998-6289-11ed-8abf-dac502259ad0.png

所以,尽管后面时间里ADC因TIMER不停触发而产生新数据并被DMA传输到SRAM,但CPU除了第一次外总是从D-Cache取数据,导致该数据永远就是第一次读到的数据而不变。

既然这样,我们可以在CPU每次针对SRAM做了读操作后,对D-Cache相应内容做无效处理,迫使CPU每次要取数据时因Cache Miss而发生读Allocate操作并更新Cache数据,进而保证CPU读到跟内存SRAM里一致的Cache数据。

我在DMA完成中断回调函数里加上一句针对D-Cache作无效操作的代码。如下图红线标注的代码。

059720f4-6289-11ed-8abf-dac502259ad0.png

然后进行测试,立即可以看到不断实时变化的数据了。【下图我随机截取的几个结果】

05c01810-6289-11ed-8abf-dac502259ad0.png

不过,请注意这里针对D-Cache相应地址做了无效化处理的代码要放在最前面。你可以将该句试着放在对AdcDataViaDMA [5]赋0语句的后面验证下,看看会有什么现象,要看细致点,不然发现不了问题。顺便提醒,目前所用SRAM区域在没有做MPU配置的情况下,默认为write back加write allocate Cache属性,我在前面贴图时已经圈出来了。有兴趣的话,可以基于上述代码自行进一步探究下,此处就不延伸了。

另外,除了上面的解决办法外,还有就是将上面内存数组所在区域做MPU设置,关闭那部分区域的Cacheable属性。

05e9fbf8-6289-11ed-8abf-dac502259ad0.png

当这样配置后,之前那句针对Cache无效化的代码就不需要了。生成代码进行测试,结果跟预期一致,数据保持实时动态变化,结果也正常。

上面主要就开启D-Cache后,发生了主设备数据读取不一致的问题给出了些解决办法及思路,同时也算是给出些应用提醒,以后碰到类似问题时可以参考。当然,有人或许会说,完全不开启芯片的D-Cache功能也可以解决问题。诚然,但我们需要综合考虑开发便利性和芯片的性能发挥,尽量就问题做些针对性的处理以充分发挥芯片性能。


文章来源于:电子工程世界    原文链接
本站所有转载文章系出于传递更多信息之目的,且明确注明来源,不希望被转载的媒体或个人可与我们联系,我们将立即进行删除处理。

我们与500+贴片厂合作,完美满足客户的定制需求。为品牌提供定制化的推广方案、专属产品特色页,多渠道推广,SEM/SEO精准营销以及与公众号的联合推广...详细>>

利用葫芦芯平台的卓越技术服务和新产品推广能力,原厂代理能轻松打入消费物联网(IOT)、信息与通信(ICT)、汽车及新能源汽车、工业自动化及工业物联网、装备及功率电子...详细>>

充分利用其强大的电子元器件采购流量,创新性地为这些物料提供了一个全新的窗口。我们的高效数字营销技术,不仅可以助你轻松识别与连接到需求方,更能够极大地提高“闲置物料”的处理能力,通过葫芦芯平台...详细>>

我们的目标很明确:构建一个全方位的半导体产业生态系统。成为一家全球领先的半导体互联网生态公司。目前,我们已成功打造了智能汽车、智能家居、大健康医疗、机器人和材料等五大生态领域。更为重要的是...详细>>

我们深知加工与定制类服务商的价值和重要性,因此,我们倾力为您提供最顶尖的营销资源。在我们的平台上,您可以直接接触到100万的研发工程师和采购工程师,以及10万的活跃客户群体...详细>>

凭借我们强大的专业流量和尖端的互联网数字营销技术,我们承诺为原厂提供免费的产品资料推广服务。无论是最新的资讯、技术动态还是创新产品,都可以通过我们的平台迅速传达给目标客户...详细>>

我们不止于将线索转化为潜在客户。葫芦芯平台致力于形成业务闭环,从引流、宣传到最终销售,全程跟进,确保每一个potential lead都得到妥善处理,从而大幅提高转化率。不仅如此...详细>>