1、问题描述
使用 STM32G4 系列芯片开发产品,用到其中一个 ADC 模块的多个通道,他希望使
用 TIMER 来定时触发这几个通道的转换。不过他有两点疑惑。第一,他期望定时器触发这几个
通道是每触发一次则只转换一个通道,这样依次触发转换,而不是触发一次就把几个通道都转换
完结。他不知这样是否可行?第二,既然是 TIMER 每触发一次就转换一次,如果说某个通道正
在转换时来了触发,这个触发事件是否会丢失?是否会导致最终转换的数据混乱。
2、问题分析
先说他的第一问题。多个通道进行转换,定时器每触发 1 次则转换 1 个通道,这是可以做到
的。我们可以采用 ADC 模块的间断分组转换模式,我们可以指定每次启动 ADC 所需要转换的通
道数。比方现在用到 6 个 ADC 通道需要做转换,我们可以指定每次触发启动时转换 2 个通道,
这样 3 次触发后 6 个通道即告完成 1 轮转换。这里截取 STM32G4 系列参考手册有关 ADC 规则
通道实施间断转换【或称非连续转换】的相关描述如下:
图 1、STM32G4 ADC 间断转换模式介绍截图
具体到客户的需求,他希望每次触发只转换 1 个通道,我们在配置时将上面截取信息中的 n
设置为 1 即可。
现在说他的第2个问题。当某通道正在进行ADC时,此时出现的触发事件是否会被无视掉,
其实是会的。ADC 模块并没有对外来触发事件提供缓冲能力,针对这点,在各个系列的参考手册
上都明确的描述。我下面截取了几个系列的相关描述如下几幅图所示。
图 2、有关 ADC 转换时出现触发事件的处理情形
如果出现触发事件被忽略掉,在多通道间断转换模式下,是否会出现转换数据的混乱呢,按
理不会出现,因为只是有些触发事件被无视掉了,ADC 的转换顺序并没有乱,这个顺序没乱,结
果就不该乱。
3、结果验证
我们不妨使用 STM32G474 芯片做下相关验证,看看当 TIMER 触发事件的速率快到一定程
度时是否会出现触发事件被无视、转换结果是否混乱。这里使用片内两个 ADC 专用通道,一个
是测试𝑉𝐵𝐴𝑇信号的,另一个是测试内部𝑉𝑅𝐸𝐹𝐼𝑁𝑇信号的。这两个信号的转换结果相对稳定、数据相
差有明显,便于观察。ADC 转换结果使用 DMA 进行传输。
先使用 STM32CubeMx 进行配置。【注意:ADC 的启动触发选择 TIMER 的 TRGO 信号,
具体就是 TIMER 的更新事件。TIMER 的时基参数配置就不截图了,验证过程中也要不停修改时间参数,以改变触发频率。另外,我把那两个被采样信号的采样时间故意设置比较大,当然,本
身这两个通道对采样时间也有最小需求,这里就不延伸了。】
配置完成后创建工程,先把 TIMER 的时间参数,这里先把溢出周期设置够久,保证溢出周
期足够长于转换通道的最长转换时间即可。【只是为了演示效果,时间无须精确】
我让 TIMER 溢出 10 次,亦即产生 10 更新事件去触发 ADC,同时在定时器更新中断里对更
新事件次数进行统计,变量是 cnt_Update。 ADC 结果通过 DMA 传输到内存数组。我们运行程
序查看结果【见下图】:
从上面结果可以看到,TIMER 产生 10 次更新事件,ADC 也依次转换了 10。通道转换结果
0x130y 和 0x143y 很有规律【数据结尾的 y 因为数字略有波动故用 y 表示,同时区别于 x】。
我们尝试将 TIMER 溢出周期慢慢调短,即溢出频率加快。但总的溢出次数不变,依然是 10
次。我们在看看下面的情形。
从上面结果看到,尽管 TIMER 产生了 10 次触发,但 ADC 转换结果才 5 个。不过转换顺序
及结果并无混乱,结合前面结果来看,总是先出现 0x130y 结果、然后 0x143y,这样交替进行。
当然,我在实际测试时做了多次验证,这里只是代表性地放一张截图过来。整个过程中随着
TIMER 溢出频率的提升,会发现转换结果变少,但没见到输出结果顺序混乱的。
随着我将 TIMER 溢出周期不断调短,最后可以发生只能见到一次转换结果了。如下图所
示:
从上图结果来看,虽然只有 1 个转换结果,即对第一个通道做了转换,第 2 通道都没有来得
及转换,但定时器的溢出次数依然是 10 次,只是除了 1 次外的其它 9 次都被无视掉了。
4、问题拓展
既然谈到 ADC 的触发事件,我们也该知道基于外部事件对 ADC 进行触发时,其触发频率
也是有限制的,这点在各个芯片的 ADC 特性参数那里都有介绍。我这里做部分截图过来,抛砖
引玉。在具体应用时我们可以 针对性地阅读查看。
图 3、STM32 ADC 特性有关外部触发频率的信息截图
4、问题小结
本文着重针对客户的疑问作了相关解释,并做了相关验证确认。在涉及多通道 ADC 转换,同时又不期望一次触发就将整个序列转换完成时,考虑使用 ADC 的间断分组转换模式或许是个不错的方案。
本文档参考ST官方的《【应用笔记】LAT1362+利用STM32+TIMER触发ADC实现分组转换》文档。