工业现场和楼宇暖通系统里的温度采集,看起来是个再普通不过的需求,但真正做过项目的人都知道,这里面的坑一点都不少。PT100、PT1000、热电偶、热敏电阻,传感器类型五花八门;现场电磁干扰、长线缆压降、冷端补偿、断线检测,每一个环节都能让测量结果偏出好几度。我最近在做一个 HVAC 机组的温度监控模块,核心方案就是 ADS122U04IPWR 搭配 PIC18F47K42,从选型到调试折腾了挺长时间,中间踩了不少坑,也积累了一些实战经验。这篇文章就把整个方案的设计思路、硬件细节、固件实现和调试过程完整梳理一遍,给正在做类似项目的朋友一个可参考的路径。
1. 为什么 HVAC 温度采集不能随便选一颗 ADC
1.1 工业与 HVAC 场景对温度测量的真实要求
很多人一提到温度测量,第一反应就是找个带 ADC 的单片机,接上传感器读电压就完事了。这种思路在实验室里做 demo 没问题,但放到 HVAC 机组或者工业现场,很快就会出问题。HVAC 场景有几个非常鲜明的特点:第一,传感器到控制板的线缆往往很长,几米到几十米都正常,导线电阻会直接叠加到测量回路里;第二,现场有大功率风机、变频器、接触器,电磁环境相当恶劣;第三,温度是个慢变量,但要求长期稳定,不能今天准明天飘;第四,很多场合需要多路温度同时采集,比如回风、送风、盘管、室外环境温度。
这些特点决定了你不能用普通 MCU 内部那个 10 位或 12 位 ADC 直接凑合。内部 ADC 的参考电压通常就是电源电压,电源一波动测量就跟着变;分辨率也不够,PT100 在 0 到 100 度范围内满量程也就几十毫伏的变化,12 位 ADC 分下来每一度才几个 LSB,根本没法做精细控制。所以必须上一颗专门的外部 ADC,而且最好是带 PGA(可编程增益放大器)和差分输入的 Σ-Δ 型 ADC。
1.2 ADS122U04IPWR 在这类场景里的定位
ADS122U04IPWR 是 TI 的一款 24 位、4 通道、带 PGA 的 ΔΣ ADC,带 UART 接口。注意这个 U 后缀,它和常见的 SPI 版本 ADS1220 不一样,走的是 UART 通信。这一点在选型时非常关键,因为很多工程师习惯了 SPI 版本,拿到 U 版本发现引脚对不上、驱动写不通,白白浪费时间。
它的核心参数我列一下,方便对照:24 位无失码分辨率,内置低噪声 PGA 支持 1 到 128 倍增益,两个差分输入通道或者四个单端输入通道,内置 2.048V 基准电压,可选 50/60Hz 工频抑制,数据速率从 5SPS 到 2000SPS 可调。这些参数放在 HVAC 温度采集场景里,几乎是量身定做的。24 位分辨率意味着你可以把 PT100 那点微弱的电压变化放大到足够精细;内置 PGA 省掉了外部运放,减少了噪声源和 BOM 成本;内置基准电压省掉了一颗基准芯片;工频抑制直接对付现场 50Hz 干扰。
1.3 PIC18F47K42 作为主控的搭配逻辑
主控选 PIC18F47K42,主要是看中它的外设资源和性价比。这颗芯片是 PIC18 系列里比较新的一代,带 128KB Flash、8KB RAM,有多个 UART、SPI、I2C 外设,工作电压 1.8V 到 5.5V,工业级温度范围 -40 到 125 度。用它来对接 ADS122U04 的 UART 接口非常合适,因为 PIC18F47K42 有独立的 UART 模块,可以专门分配给 ADC 通信,不占用调试串口。
另外它的 12 位内部 ADC 也不是完全没用,可以用来做电源电压监测、冷端补偿热敏电阻的粗测等辅助功能。整体搭配下来,一颗主控加一颗高精度 ADC,就能覆盖 HVAC 机组里大部分温度采集需求,成本可控,可靠性也够。
2. 硬件设计里那些容易翻车的细节
2.1 传感器接口电路:PT100 三线制还是四线制
温度传感器选型直接决定接口电路。HVAC 里最常用的是 PT100 和 PT1000,也有用 NTC 热敏电阻的。PT100 精度高、线性度好,但阻值低,100 欧姆在 0 度时,导线电阻几欧姆就能带来好几度的误差。所以 PT100 必须用三线制或四线制接法来消除线阻影响。
三线制是工业现场最常见的折中方案,用两根线做电流激励回路,第三根线做电压检测补偿。四线制精度最高,但多一根线,布线成本高。我的方案里用的是三线制,配合 ADS122U04 的两个差分通道,一个通道测传感器电压,另一个通道测参考电阻电压,通过比例法计算阻值,这样激励电流的漂移和基准电压的漂移会相互抵消。
具体接法上,PT100 一端接激励电流输出,另一端接参考电阻到地,两个差分输入分别跨接在 PT100 和参考电阻上。参考电阻选 0.1% 精度、低温漂的金属膜电阻,阻值根据激励电流和量程来定。这里有个经验:参考电阻的阻值最好和 PT100 在量程中点的阻值接近,这样两个通道的电压水平相近,PGA 增益可以设成一样,共模抑制效果最好。
2.2 ADS122U04 的模拟前端配置要点
ADS122U04 的模拟输入有几种配置模式,差分输入、单端输入、还有内部多路复用器切换。做 PT100 比例测量时,我建议用两个差分通道,通道 0 接 PT100,通道 1 接参考电阻。PGA 增益根据信号幅度来选,PT100 在 0 到 100 度时阻值从 100 欧姆变到 138.5 欧姆,如果激励电流选 500 微安,电压变化范围是 50mV 到 69.25mV,这个幅度用增益 32 或 64 比较合适,既能充分利用 ADC 量程,又不会让 PGA 输出饱和。
基准电压用内部 2.048V 还是外部基准,要看精度要求。内部基准的初始精度是 0.1% 左右,温漂典型值 5ppm/度,对于大多数 HVAC 应用够用了。如果要求更高,可以外接一颗高精度基准,但要注意外部基准的噪声和驱动能力,ADS122U04 的基准输入阻抗不是特别高,需要基准源有足够的驱动能力。
2.3 电源与地平面处理:噪声控制的根基
模拟电路的噪声控制,七分靠布局,三分靠器件。ADS122U04 的电源引脚必须加去耦电容,而且要大电容和小电容并联。我的做法是每个电源引脚旁边放一个 100nF 的陶瓷电容,再在电源入口放一个 10uF 的钽电容。模拟电源和数字电源最好分开走线,在 ADC 下方做单点接地,避免数字电流流过模拟地平面。
PCB 布局上,模拟输入走线要尽量短,远离时钟线和数字信号线。PT100 的激励电流走线和电压检测走线要分开,不要平行走太长距离,否则会形成耦合。如果传感器线缆很长,建议在输入端加 RC 滤波,截止频率设在几赫兹到几十赫兹,把高频干扰滤掉。但要注意滤波电阻会引入额外的误差,阻值不能太大,一般几十欧姆以内,而且要选低温漂的。
提示:ADS122U04 的 UART 接口在空闲时应该保持高电平,如果主控 UART 引脚在复位期间是浮空的,建议加一个上拉电阻,避免 ADC 误触发。
3. 固件实现:从 UART 驱动到温度换算
3.1 ADS122U04 的 UART 通信协议拆解
ADS122U04 的 UART 接口和标准 UART 不太一样,它的波特率是固定的,根据芯片版本不同有几种可选,通信格式是 8 位数据、无校验、1 位停止位。命令结构是命令字节加数据字节,比如写寄存器是 0x40 加寄存器地址,读寄存器是 0x20 加地址。每次读写操作之间需要等待转换完成或者命令处理完成,不能连续无间隔发送。
这里有个容易忽略的点:ADS122U04 的 UART 是半双工的,发送和接收共用一根线还是分开的,要看具体型号。IPWR 封装的是分开的 TX 和 RX,但通信时序上仍然是命令响应模式,主控发完命令后要切换到接收状态等待 ADC 返回数据。如果主控 UART 配置成全双工,发送和接收同时进行,可能会收到自己发出去的回显,导致数据错乱。
我在固件里是这样处理的:每次发送命令前先清空接收缓冲区,发送完成后延时几个字节时间,再读取响应。延时时间根据波特率算,比如 9600 波特率下,一个字节大约 1ms,命令加数据最多几个字节,延时 5ms 足够。这个延时不能省,否则 ADC 还没处理完命令,主控就去读,读回来的是无效数据。
3.2 PIC18F47K42 的 UART 初始化与中断处理
PIC18F47K42 的 UART 模块配置比较灵活,需要设置波特率发生器、数据位、停止位、中断优先级。我的配置是波特率 9600,8 位数据,1 位停止位,无校验,接收中断使能。波特率计算要注意 PIC18F47K42 的时钟源,如果用 16MHz 外部晶振,波特率寄存器值按公式算:BRG = Fosc / (4 × 波特率) - 1。16MHz 下 9600 波特率,BRG 约等于 415,实际写入值要取整,误差在 2% 以内可以接受。
中断处理里,我建议用环形缓冲区接收数据,主循环里再解析。因为 ADS122U04 返回的数据长度不固定,有时候是寄存器值,有时候是转换结果,用状态机解析比较稳妥。接收中断里只做一件事:把数据放进缓冲区,更新写指针。主循环里检查缓冲区是否有完整帧,然后根据当前命令状态解析。
// PIC18F47K42 UART 初始化示例 void UART_Init(void) { TRISCbits.TRISC6 = 1; // RX 输入 TRISCbits.TRISC7 = 1; // TX 输出 SP1BRGL = 415 & 0xFF; // 波特率低字节 SP1BRGH = 415 >> 8; // 波特率高字节 TX1STA = 0x24; // 使能发送,8位数据 RC1STA = 0x90; // 使能接收,8位数据 PIE3bits.RC1IE = 1; // 接收中断使能 INTCONbits.PEIE = 1; // 外设中断使能 INTCONbits.GIE = 1; // 全局中断使能 }3.3 温度换算的数学过程与校准方法
ADS122U04 读回来的是 24 位有符号数,代表两个差分通道的电压比值。温度换算分几步:先算 PT100 阻值,再查表或公式算温度。比例法下,PT100 阻值 Rpt = Rref × (Code_pt / Code_ref),其中 Code_pt 和 Code_ref 分别是两个通道的转换码值。这个公式的前提是两个通道的 PGA 增益相同、基准相同,所以配置时要保证一致。
算出阻值后,用 Callendar-Van Dusen 公式换算温度。0 到 850 度范围内,R(t) = R0 × (1 + A×t + B×t²),其中 R0 是 0 度时的阻值,A 和 B 是常数。反解温度需要解二次方程,或者用查表加线性插值。我在固件里用的是分段线性插值,把 -50 到 150 度分成若干段,每段用两个校准点做线性拟合,精度可以做到 0.1 度以内,计算量也小。
校准是保证精度的关键。我的做法是至少做两点校准:冰水混合物 0 度和沸水 100 度(注意当地气压对沸点的影响),记录两个温度点下的 ADC 码值,算出增益误差和偏移误差,写入 Flash 保存。如果条件允许,用高精度温度计做多点校准,效果更好。
4. 调试过程中踩过的坑与排查思路
4.1 读数跳动大:从电源到布局的逐层排查
第一次上电测试,读数跳动超过 1 度,完全没法用。排查过程是这样的:先看电源纹波,用示波器交流耦合测 ADC 电源引脚,发现有几毫伏的高频噪声,频率和主控时钟相关。判断是数字噪声耦合到模拟电源,解决办法是在模拟电源路径上加 LC 滤波,电感选 10uH 左右,电容 10uF 加 100nF。
电源改善后,跳动降到 0.3 度左右,但还是不够。接着查布局,发现模拟输入走线从 ADC 下方穿过,而且和 UART 走线平行了一段距离。重新布线,模拟输入走线远离数字信号,并且用地线包围。这一改,跳动降到 0.1 度以内。
最后还有一个细节:ADS122U04 的配置寄存器里有个 50/60Hz 抑制位,默认是 50Hz 抑制,如果现场干扰主要是 60Hz,要改成 60Hz 抑制。这个位不设置对,工频干扰会直接体现在读数上。
4.2 UART 通信丢包:时序与缓冲区的双重问题
调试 UART 通信时,偶尔会出现读回来的数据全 0 或者全 FF。一开始怀疑是波特率不匹配,用示波器抓波形,发现波特率是对的,但命令发送和响应读取之间的间隔太短。ADS122U04 处理命令需要时间,特别是启动转换命令,需要等转换完成才能读结果。我原来的代码发完启动命令就立刻去读,结果读回来的是旧数据或者无效数据。
解决办法是在启动转换后,根据配置的数据速率计算等待时间。比如 20SPS 的速率,一次转换需要 50ms,那就延时 60ms 再读。另外接收缓冲区要足够大,我一开始用 8 字节缓冲区,结果读 3 字节转换结果时,前面还有状态字节,缓冲区溢出丢数据。改成 32 字节后问题消失。
4.3 断线检测与故障安全设计
工业现场传感器断线是常见故障,如果不做检测,ADC 读回来的可能是满量程或者随机值,控制系统会误动作。ADS122U04 本身有激励电流源,可以通过检测激励回路是否正常来判断断线。我的做法是定期切换激励电流源的通断,如果断开时读数和接通时一样,说明回路断了。
另外在固件里加了合理性检查:温度值超出传感器量程范围、变化率超过物理可能的最大值,都判定为故障,输出一个预设的安全值,同时上报故障状态。这个逻辑看起来简单,但在实际运行中救过好几次,避免了因为传感器故障导致的误报警。
5. 精度验证与长期稳定性测试
5.1 实验室精度测试方法与结果
精度验证我用的是高精度温度校准炉,设定几个温度点,等炉温稳定后记录 ADC 读数和标准温度计的读数,做对比。测试点选了 -20、0、25、50、80、100 度,每个点稳定 10 分钟后连续采样 100 次取平均。结果显示,在 0 到 80 度范围内,误差在 ±0.15 度以内;-20 度和 100 度附近误差稍大,约 ±0.3 度,主要是 PT100 在量程边缘的非线性导致的。
这个精度对于 HVAC 应用完全够用了,一般机组温度控制精度要求也就 ±0.5 度。如果要求更高,可以换 PT1000 或者用更高精度的参考电阻,但成本会上去。
5.2 现场长期运行的数据观察
实验室测完只是第一步,真正考验是在现场长期运行。我把模块装在一台组合式空调机组上,连续跑了三个月,每天记录温度数据。观察下来,短期波动在 ±0.1 度以内,长期漂移在三个月内小于 0.2 度,主要是参考电阻和 PT100 自身的长期漂移。这个漂移量在可接受范围内,如果要求更高,可以定期自动校准,用内部基准或者外部精密电阻做参考。
现场还遇到过一次干扰事件:旁边一台变频器启动时,温度读数瞬间跳了 2 度,但很快恢复。检查后发现是变频器产生的共模干扰通过传感器线缆耦合进来。后来在传感器输入端加了共模扼流圈,问题解决。这也说明,再好的 ADC 也挡不住恶劣的电磁环境,外围防护必须做到位。
6. 方案扩展与不同传感器类型的适配
6.1 从 PT100 扩展到热电偶的注意事项
这套方案稍作修改就能支持热电偶。热电偶输出的是微伏级电压,比 PT100 的毫伏级还小一个数量级,所以 PGA 增益要开到 128 甚至更高。ADS122U04 在增益 128 时的等效输入噪声大约几十纳伏,对于 K 型热电偶约 41 微伏每度来说,分辨率足够。
但热电偶有个绕不开的问题:冷端补偿。热电偶测量的是热端和冷端的温差,必须知道冷端温度才能算出热端温度。我的做法是用一颗 NTC 热敏电阻贴在接线端子附近,用 PIC18F47K42 的内部 ADC 或者 ADS122U04 的另一个通道测量冷端温度,然后在固件里做补偿计算。冷端补偿的精度直接影响整体精度,NTC 的测温精度要做到 0.1 度以内,而且要和接线端子热耦合良好。
6.2 多路温度采集的通道扩展思路
HVAC 机组经常需要同时测多路温度,ADS122U04 只有 4 个输入通道,不够用怎么办。两个思路:一是用多颗 ADS122U04,通过 UART 地址区分或者用主控的多个 UART 分别连接;二是用外部多路复用器切换传感器,但要注意多路复用器的导通电阻和漏电流会影响精度。
我倾向于第一种方案,多颗 ADC 各自独立,互不干扰,软件上也好处理。PIC18F47K42 有多个 UART,可以同时接几颗 ADC。如果 UART 不够,可以用 SPI 版本的 ADS1220,通过片选信号切换,但 SPI 版本没有 UART 版本抗干扰好,长线通信时要注意。
6.3 低功耗设计在电池供电场景的应用
有些 HVAC 场合,比如无线温度传感器节点,需要电池供电,低功耗就很重要。ADS122U04 有单次转换模式和掉电模式,不测量时可以关掉大部分电路,功耗降到微安级。PIC18F47K42 也有多种低功耗模式,休眠电流可以做到纳安级。
我的做法是让系统大部分时间处于休眠,定时唤醒测量一次温度,然后通过无线模块发送出去,再回到休眠。测量时 ADC 和主控都全速运行,测量完立刻进入低功耗。这样平均功耗可以做到几十微安,一节电池能用好几年。但要注意,频繁唤醒和休眠会增加软件复杂度,而且 ADC 每次上电都需要稳定时间,不能刚上电就测量,要等基准和 PGA 稳定。
7. 一些实战中总结的经验与建议
做这个项目最大的体会是,高精度温度测量是个系统工程,ADC 只是其中一环。传感器、参考电阻、电源、布局、固件、校准,每个环节都会影响最终精度。我见过太多人把精力全花在选 ADC 上,结果因为一个去耦电容没放对,或者校准没做好,精度始终上不去。
选型阶段,先明确精度要求和成本预算,再倒推需要多少位的 ADC、什么类型的传感器。不要盲目追求高位数,24 位 ADC 在噪声环境下有效位数可能只有 16 位,多出来的位数是给 PGA 和滤波留余量的。ADS122U04 的 UART 接口在长线通信和隔离场合有优势,但如果主控就在旁边,SPI 版本可能更简单。
调试阶段,一定要有高精度仪器做参考,万用表和普通温度计不够用。示波器看电源纹波和通信波形,能解决大部分疑难问题。遇到读数不对,先查电源和地,再查配置寄存器,最后查通信时序,这个顺序能帮你快速定位问题。
最后,工业产品的可靠性设计不能省。断线检测、故障安全输出、看门狗、参数掉电保存,这些功能平时看不出价值,但关键时刻能避免大问题。我在现场跑的那三个月,模块经历过电源波动、电磁干扰、温度骤变,最终稳定运行,靠的就是这些看似冗余的设计。