最近在学习蓝桥杯的stm32G431芯片时,发现同一段ADC转换代码,转换有时成功有时不成功,偶然间发现加上延迟函数LL_mDelay(50);就可以转换成功了,非常疑惑。因为加入延迟的解决方法与时间有关,是时域问题,我猜测可能是ADC的时钟频率出问题了。故尝试寻找了一个从根本上解决ADC转换的方法。
核心方法:降低ADC的时钟频率
具体方法1 ,降低ADC时钟频率的方法有很多,最简单的一种就是使用异步时钟,并增加ADC时钟的分频系数。如图1,在ADC_Settings里的Clock Prescaler选择 “32分频后的异步时钟”。这是因为使用异步时钟后分频系数更多。
图1 使用异步时钟,增加分频系数
具体方法2,降低AHB的时钟频率。AHB的时钟来自SYSCLK,可以增加SYSCLK到AHB的分频系数或者降低SYSCLK频率。如图2,是通过增加SYSCLK到AHB的分频系数来降低AHB时钟频率,从而降低ADC时钟频率。 同时,还要在ADC设置界面选择ADC的时钟来源“同步时钟”,如图3
图2 使用同步时钟,降低AHB时钟频率
图3 选择同步时钟
至于为什么降低ADC的时钟频率就可以转换正常,我推测是和ADC的输入时钟频率有关,ADC的输入时钟频率不可以太高,否则转换结果会异常。我之前配置的AHB频率是170Mhz,同步时钟2分频后输入给ADC,85Mhz远高于ADC允许的输入时钟频率,所以导致了ADC转化不成功的问题。
关于ADC时钟的“异步时钟”(Synchronous clock)和“同步时钟”(Asynchronous clock)有什么区别,可以参考这个博主的这篇文章:STM32配置ADC时钟分频因子问题小结