第4章:ADC多通道扫描与队列转换
各位工程师朋友,欢迎来到第四章。这一章我们聊聊ADC的多通道扫描和队列转换。说实话,这是我在实际项目中最常用到的功能之一。你想想看,一个系统里往往要采集好几个模拟信号——电流、电压、温度、压力……如果每个通道都单独配置、单独启动,那代码写起来得多累?效率也低。
所以英飞凌设计了两种机制:自动扫描和队列转换。它们的目的是一样的——让你用最少的CPU干预,完成最多的采样任务。但实现思路和适用场景不太一样。我一个个说。
4.1 自动扫描模式:简单粗暴的轮询
自动扫描模式,说白了就是让ADC自己按顺序把一组通道挨个采一遍。你只需要告诉它:从哪个通道开始,到哪个通道结束,然后启动一次,它就自己跑完了。
我在一个电机控制项目里用过这个模式。当时需要同时采集三相电流和母线电压,一共四个通道。用自动扫描,一次触发就能拿到所有数据,省心得很。
配置起来也不复杂。关键寄存器是GxARBPR和GxARBCR。前者设置仲裁优先级,后者设置扫描的起始和结束通道。举个例子:
// 配置组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跑得更快,而是靠硬件机制用得巧。