近期收到了一块STM32G4系列的开发板,作为试用开发板,尝试使用G4做电源类项目,在使用G4系列开发板的时候,碰到了ADC工作不正常的情况,具体情况如下所示:
由于项目需要,主频限定在20Mhz,使用了板载24Mhz晶振,时钟树分布如下:
图 1 时钟树分布
使用了ADC2,使能了ADC CH1 CH2 不使用多重采样,使能ADC2通道DMA,使用DMA2总线CH1,循环模式,传输方式为Half Word ,使能ADC中断和DMA中断,ADC配置如下图所示:
图 2 ADC配置图
ADC设置了12位 循环模式,使能DMA ,DMA非单次中断.
理论上,经过以上配置之后,在main函数中使用
HAL_ADC_Start_DMA(&hadc2, (uint32_t*) AD_G4Data.AD_Data, 256);
函数开启ADC采集之后,主函数应该得到轮询,通过DEBUG应该可以看到采样值得到变动,可是实际DEBUG的时候,主函数没有得到轮询,通过单步调试发现,函数卡在了ADC获取值的回调函数上,感觉很奇怪.一时找不出问题.
我开始怀疑是不是主频太低,导致CPU处理不过来ADC转换信号,我提高主频至80M,发现ADC采样正常,但是通过DMA模式获取的ADC数据,偶发通道传输错误现象,百思不得其解,起因主频问题,所以我将主频调整到160M,数据传输恢复正常.至此,可以总结为是主频问题,所以回去详细查看时钟树.
问题所在:
系统主频为20M,但是单片机ADC分频为160M,单片机AD请求太快,导致单片机来不及处理,所以一直在ADC取值请求等待,调整ADC时钟后,问题问题解决,附上调整后的时钟树.
图 3 调整后的时钟树
调整前后的时钟树,唯一的差别就是ADC12 Clock Mux 最开始为160M 调整后为20M
后来没有发现这个问题,原因是在STM32Cube FW_G4 V1.1.0包中已经修复了这个问题,使用V1.1.0创建的工程,如果使用了ADC,ADC12 Clock Mux的最大值自动锁定为系统主频,这个问题给我们提供了一条思路,当某一模块工作不正常时,分析代码,如果卡在某一特定的函数上,可以根据特定函数的功能进行分析,详细检查时钟树,DMA等功能,一般能排除故障。