第4章:ADC多通道扫描与队列转换

各位工程师朋友,欢迎来到第四章。这一章我们聊聊ADC的多通道扫描和队列转换。说实话,这是我在实际项目中最常用到的功能之一。你想想看,一个系统里往往要采集好几个模拟信号——电流、电压、温度、压力……如果每个通道都单独配置、单独启动,那代码写起来得多累?效率也低。

所以英飞凌设计了两种机制:自动扫描队列转换。它们的目的是一样的——让你用最少的CPU干预,完成最多的采样任务。但实现思路和适用场景不太一样。我一个个说。

4.1 自动扫描模式:简单粗暴的轮询

自动扫描模式,说白了就是让ADC自己按顺序把一组通道挨个采一遍。你只需要告诉它:从哪个通道开始,到哪个通道结束,然后启动一次,它就自己跑完了。

我在一个电机控制项目里用过这个模式。当时需要同时采集三相电流和母线电压,一共四个通道。用自动扫描,一次触发就能拿到所有数据,省心得很。

配置起来也不复杂。关键寄存器是GxARBPRGxARBCR。前者设置仲裁优先级,后者设置扫描的起始和结束通道。举个例子:

// 配置组0的自动扫描,从通道0扫到通道3
IfxAdc_G0_arbpr.U |= (0 << IfxAdc_G0_arbpr_ASENUM_OFFSET);  // 使能自动扫描
IfxAdc_G0_arbcr.U |= (3 << IfxAdc_G0_arbcr_REQCHNR_OFFSET); // 结束通道为3
IfxAdc_G0_arbcr.U |= (0 << IfxAdc_G0_arbcr_REQCHNR_OFFSET); // 起始通道为0

嗯,这里要注意:自动扫描模式下,所有通道的采样时间、分辨率等参数必须一致。因为硬件只配置了一套转换参数。如果你需要不同通道用不同采样时间,那就得用队列模式了。

核心要点:自动扫描适合通道参数统一、顺序固定的场景。配置简单,CPU负载低。

4.2 队列转换模式:灵活但复杂

队列转换就灵活多了。你可以把不同的通道、不同的采样时间、不同的触发源,甚至不同的结果寄存器,都塞进一个队列里。硬件按你定义的顺序一个个执行。

我记得有一次做电池管理系统,需要采集电芯电压(高精度、慢速)和温度(低精度、快速)。两种信号对采样时间和分辨率要求完全不同。自动扫描搞不定,队列模式正好派上用场。

队列的配置稍微复杂一点。每个队列条目(Entry)包含:

  • 通道号:要采哪个通道
  • 采样时间:可以独立设置
  • 结果寄存器:采完存到哪个位置
  • 中断标志:采完是否触发中断

看个例子:

// 配置队列条目0:通道2,采样时间40个时钟周期,结果存到RES0
IfxAdc_G0_queuelo.U |= (2 << IfxAdc_G0_queuelo_CHNR_OFFSET);   // 通道2
IfxAdc_G0_queuelo.U |= (3 << IfxAdc_G0_queuelo_STCS_OFFSET);   // 采样时间=40周期
IfxAdc_G0_queuelo.U |= (0 << IfxAdc_G0_queuelo_REQCHNR_OFFSET); // 结果存到RES0

// 配置队列条目1:通道5,采样时间20个时钟周期,结果存到RES1
IfxAdc_G0_queuelo.U |= (5 << IfxAdc_G0_queuelo_CHNR_OFFSET);
IfxAdc_G0_queuelo.U |= (1 << IfxAdc_G0_queuelo_STCS_OFFSET);   // 采样时间=20周期
IfxAdc_G0_queuelo.U |= (1 << IfxAdc_G0_queuelo_REQCHNR_OFFSET);

我的经验:队列条目数有限(TC3xx一般是8个)。如果通道数超过8个,可以配合自动扫描一起用。先扫一组,再扫另一组。

4.3 两种模式的对比与选择

到底用哪个?我一般这样判断:

场景 推荐模式 原因
所有通道参数相同 自动扫描 配置简单,硬件开销小
通道参数不同 队列转换 每个条目独立配置
需要动态改变采样顺序 队列转换 可以运行时修改队列内容
通道数超过8个 自动扫描+队列 组合使用,灵活扩展

我曾经在一个项目中,一开始用了自动扫描,后来发现有个通道需要更长的采样时间。没办法,只能改成队列模式。改代码倒不麻烦,但调试花了不少时间。所以我的建议是:如果预见到未来可能调整,直接上队列模式。省得后面返工。

4.4 避坑指南

我曾经踩过的坑:

  • 队列溢出:队列条目写满了,硬件会停止转换。一定要检查GxQUEUEFLAG寄存器的溢出标志。
  • 结果覆盖:多个队列条目指向同一个结果寄存器,后一个会覆盖前一个。我建议每个通道用独立的结果寄存器。
  • 触发源冲突:自动扫描和队列模式不能同时用同一个触发源。否则硬件会懵掉。

嗯,还有一个细节:队列模式支持循环执行。你可以在队列末尾设置一个特殊条目,让它跳回开头。这样就能实现周期性的多通道采样,非常实用。

4.5 实战建议

最后给几个实战建议:

  • 先画流程图:把要采的通道、顺序、采样时间、结果存放位置画出来。别急着写代码。
  • 用中断收数据:队列转换完成后触发中断,在中断里读取结果。别在主循环里轮询。
  • 留够余量:采样时间别卡太紧。我一般比手册推荐值多留20%。
  • 验证结果:用示波器看ADC的触发信号和转换完成信号,确认时序没问题。

好了,这一章就到这里。多通道扫描和队列转换是ADC高效采样的基础。掌握了它们,你的系统就能同时处理多个模拟信号,而且CPU几乎不用操心。下一章我们聊聊DSADC——那个专门为高精度测量设计的家伙。到时候你会发现,有些场景下DSADC比普通ADC好用得多。

记住:采样效率的提升,往往不是靠CPU跑得更快,而是靠硬件机制用得巧