ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

HVAC温度采集实战:ADS122U04+PIC18LF47K42完整方案

HVAC温度采集实战:ADS122U04+PIC18LF47K42完整方案

开年接了个典型的HVAC控制柜项目,甲方要求在一台空气处理机组里测回风、送风、盘管水温、室外温度四个点,传感器既有PT1000铂电阻,又有K型热电偶,还得预留一路4-20mA变送器接口。我一看到这个需求清单,脑子里第一个冒出来的方案就是TI的ADS122U04IPWR加Microchip的PIC18LF47K42。这个组合在工业和HVAC温度采集场景里,属于那种“看着不花哨,但每个零件都在关键位置上”的搭配。很多工程师一提到精密温度测量就习惯性选内部带24位ADC的高端MCU,或者干脆用SPI接口的独立ADC,但实际做过工业现场的人会告诉你,UART接口的精密ADC在某些场景下反而更让人省心。

这篇博文我就把这个组合从传感器选型、硬件连线、固件协议到现场校准的完整链路拉通讲一遍,重点包括RTD比例测量的激励电流计算、热电偶冷端补偿的处理细节、24位数据的解析和温度换算,以及我在HVAC机柜里踩过的几个噪声和误码的坑。内容偏向实操,适合正在做温度采集、变送器接口、楼宇自控节点或者工业仪表项目的嵌入式工程师参考。

1. 为什么这个组合能解决工业温度测量的三个核心痛点

先说说ADS122U04IPWR和PIC18LF47K42各自是什么来头。ADS122U04是TI的一款4通道24位Δ-Σ ADC,内置可编程增益放大器(PGA)、两个可编程激励电流源(IDAC)、内部2.048V基准电压和片上温度传感器,最关键的是它带的是UART接口而不是传统SPI/I2C。PIC18LF47K42是Microchip的8位低功耗MCU,工作电压1.8V到3.6V,内部最高64MHz振荡器,带三个UART模块、12位ADC、可配置逻辑单元(CLC)这些外围,跑一个温度采集节点绰绰有余。

把这两颗芯片放在一起,解决的是工业温度测量里最让人头疼的三个问题:

第一是信号太微弱。铂电阻的温度系数大约只有0.00385欧姆每摄氏度,K型热电偶的塞贝克系数约41微伏每摄氏度,这些信号如果不经过高增益、高分辨率的ADC直接送进MCU自带的12位ADC,等于让一个视力正常的人去看视力表上最小的那一行的最后一个字母,偶尔能看清,但大部分时间在猜。24位Δ-Σ ADC配合PGA,把信号先放大、再积分,这样微伏级的温差才能被稳定分辨出来。

第二是传感器和控制器之间往往有相当长的线缆。HVAC机柜里传感器可能分布在风管、水管、室外,线缆长则二三十米。SPI接口对时序敏感,线一长就容易出现时钟歪斜和时序违例;I2C虽然只有两根线,但电平兼容性和地址冲突也麻烦。UART是异步串行,只要波特率和帧格式约定好,线长一点、隔离一下,稳定性反而更好。

第三是电源和噪声环境恶劣。控制柜里变频器、接触器、电机启停带来的电磁干扰非常严重,内部24位ADC很容易被数字噪声淹没。独立ADC芯片的模拟前端和数字通信在物理上分得开,配合合理的滤波和布局,比集成在MCU内部的ADC更能扛干扰。

还需要破除一个常见的思维定式:UART接口上不了精密ADC的台面。这种想法完全过时了。ADS122U04的UART接口工作在CMOS电平,直接和3.3V单片机连接毫无压力,而且通信协议足够简单:发送命令、读取数据、配置寄存器,就这么几件事。在整个系统架构里,MCU扮演的其实是“感知网关”的角色:一边通过UART把ADC的数据读回来,另一边用自己的UART2接RS-485去连接Modbus总线或者楼宇自控系统。分工非常清楚。

1.1 24位Δ-Σ ADC到底怎么把毫伏信号变成有效数字

很多人看到“24位”就以为分辨率是1/16777216,这个理解容易把人带沟里去。Δ-Σ ADC的关键在于过采样和噪声整形,它输出的是位数很高的原始码值,但有效分辨率取决于你最终能接受的输出速率和噪声水平。ADS122U04的输出数据速率从20SPS到1000SPS可调,速率越低,数字滤波越强,有效分辨率越高。在20SPS下配合PGA增益,它能把有效无噪声分辨率做到20位左右,这个水平对于0.1℃级的温度测量来说绰绰有余。

具体到信号链:传感器信号先经过外部RC滤波,然后进入PGA放大,Δ-Σ调制器被速率几十倍的时钟驱动,把模拟信号转换成一串高密度的脉冲流,后面的数字滤波器把这些脉冲做抽取和平均,输出一个平滑的24位码值。这个过程的本质就是用一个相对便宜的高精度调制器加上数字滤波,替代传统逐次逼近型ADC里昂贵的模拟滤波器。理解了这个,你就知道为什么板子上的电源噪声和参考电压质量对最终结果影响那么大——数字滤波拯救不了模拟前端的脏。

1.2 选UART而不选SPI的现场理由,以及代价

我自己的经验是,SPI在板级通信里确实最高效,但要拉到温度传感器这么远的应用场景,需要在数据手册里仔细看时序,还要考虑主从设备之间的地电位差。UART则不同,它是异步协议,只要双方的波特率误差控制在合理范围(通常±2%以内),通信稳定性就有保障。PIC18LF47K42的内部振荡器出厂校准后误差在±1%左右,配上ADS122U04的波特率容限,工程上完全够用。

代价是什么?UART协议没有硬件片选信号,所以如果需要挂多个ADC,必须在ADC这边用地址功能来区分。ADS122U04支持通过寄存器配置设备地址,多个设备可以共用一条UART总线。不过说实话,在绝大多数HVAC节点里一个ADC的四个通道就够用了,多个ADC并存的需求很少见。

还有一个细节值得注意:UART是点对点全双工,ADS122U04的TX引脚在空闲状态是高电平,如果MCU的RX引脚没有配置成上拉或者内部弱上拉,可能出现起始位误判。我在初版设计里就吃过这个亏,后面会专门讲到。

2. 传感器接入设计:RTD、热电偶、4-20mA变送器怎么接才算专业

硬件设计的核心不是把线连上就行,而是要根据每一种传感器的特性和精度要求,去设计激励电流、参考电阻、增益和滤波参数。这一节我按三类最常见的传感器分别说。

2.1 PT100/PT1000三线制比例测量:用IDAC和参考电阻消除误差

铂电阻测温的原理简单粗暴:电阻随温度变化,测电阻就能算温度。但难点在于,怎么把“测电阻”变成“测电压”,而且不让引线电阻把精度毁掉。ADS122U04内置了两个可编程电流源IDAC1和IDAC2,电流档位从50μA到1.5mA可调。把这些电流源引到铂电阻上,在铂电阻两端产生一个随温度变化的电压,再用ADC去测这个电压。

比例测量的精髓在于,ADC的参考电压不是用内部固定的2.048V,而是用一个精密参考电阻RREF上产生的压降作为参考。这样激励电流的任何波动都会同时影响传感器电压和参考电压,两者相除之后,电流的影响就抵消了。这个思路跟电子秤用惠斯通电桥一个道理,极其经典。

具体算一组参数,以PT100为例:

  • 激励电流选择250μA。电流太小信号太弱,电流太大铂电阻自身发热会导致温升误差(自热效应)。250μA在PT100上产生的自热可以接受,在PT1000上也没问题。
  • RREF选2.5kΩ,则参考电压 = 250μA × 2.5kΩ = 0.625V。
  • 0℃时PT100阻值100Ω,感应电压 = 250μA × 100Ω = 25mV;如果PGA增益设成8,ADC输入端电压 = 25mV × 8 = 200mV。对应满量程0.625V,码值约为 200mV / 625mV × 2^23 ≈ 2,684,354,有效分辨率绰绰有余。
  • 100℃时PT100阻值约138.5Ω,感应电压 = 34.6mV,PGA增益8后 = 277mV,仍然在0.625V参考电压以内。

这个增益选择背后的逻辑是,让最坏情况下的放大信号不要超过参考电压范围,同时尽量接近满量程以获得最大分辨率。如果把温度范围扩大到-50℃到200℃,PT100对应阻值约80.3Ω到175.8Ω,感应电压20.1mV到44mV,PGA增益8时最大352mV,也还是在0.625V以内,完全够用。

三线制和四线制的区别在于补偿引线电阻的方式。三线制有两个激励电流源分别从两根引线灌入,这样两根引线电阻产生的压降分别落在参考电压回路上和传感器信号回路上,通过差分测量可以抵消一部分。四线制则是独立的电流线和电压线,电压测量线不载流,理论上引线电阻完全不进入测量回路。现场工程里,如果线缆长度超过10米或精度要求优于0.1%,我建议直接上四线制。

2.2 K型热电偶直接接入:增益32和冷端补偿才是重头戏

热电偶输出的是差分电压,K型热电偶在0℃到1300℃范围内的热电势大约从0mV到52mV。这个信号直接用PGA放大,增益选择有个讲究:

  • 如果增益128,满量程只有2.048V / 128 = 16mV,K型热电偶超过400℃左右就会超量程。
  • 如果增益64,满量程32mV,约覆盖到800℃。
  • 如果增益32,满量程64mV,完整覆盖K型热电偶的量程。

所以我常态性推荐K型热电偶配增益32,除非你的应用温度范围确实很窄(比如只测0到200℃),那可以用增益64获得更高分辨率。

热电偶测量的第二个重点是冷端补偿(CJC)。热电偶产生的热电势实际上是测量端与冷端(接线端子处)之间的温差电势,而不是绝对温度电势。如果接线端子处的环境温度是30℃,而你以为冷端是0℃,算出来的温度就全偏了。正确做法是:用另一个温度传感器测量接线端子本身的实际温度(冷端温度),把这个冷端温度对应的热电势加到热电偶测量得到的电压上,再用总电压查热电偶分度表得到真实温度。

冷端温度传感器选择上有两种路线:一是用ADS122U04内部自带的温度传感器二极管,这个传感器测量的是ADC芯片自身温度,如果芯片紧挨着热电偶接线端子,可以近似认为它就是冷端温度;二是用一颗NTC或者PIC18LF47K42内部温度指示器。我的建议是,冷端传感器应该贴在热电偶端子排上,而不是贴在电路板随便一个位置,否则温度梯度带来的误差比ADC本身的噪声大得多。

CJC的实现算法后面在固件章节里详细展开。

2.3 4-20mA变送器接收端:250Ω采样电阻和衰减的注意事项

工业现场大量使用两线制4-20mA变送器输出温度信号,接收端只要在信号线和地之间接一个250Ω精密电阻,就能把4-20mA转换成1-5V电压。但这个1-5V电压对于ADS122U04的内部参考2.048V来说太大了,直接进ADC必然超量程。

处理办法是先用电阻分压把1-5V衰减到合适的ADC输入范围,比如衰减1/4变成250mV到1.25V,或者衰减1/5变成200mV到1V,然后再送进ADC。这个过程里要注意两点:分压电阻的精度要选0.1%级别的,因为4-20mA的精度等级通常在0.1%到0.5%之间,分压电阻如果只用1%就把人家变送器的精度糟蹋了。另外,接收端的地要干净,变送器电流回路在大电流设备启停时容易在地线上产生共模干扰,必要时用差模输入方式接入ADC。

3. 硬件关键连线:从ADS122U04到PIC18LF47K42的每一根线

这一节是PCB和原理图层面的落地方案。我会把电源、UART通信、模拟输入这几个部分逐一说清楚,讲完这部分你基本可以直接照做。

3.1 电源和去耦设计,别让小电容毁了大精度

ADS122U04的供电范围是2.3V到5.5V,PIC18LF47K42是1.8V到3.6V,两者共用的最佳折中是3.3V。系统用一个低压差线性稳压器(LDO)把5V或者24V降压到3.3V。为什么推荐LDO而不是DC-DC?因为DC-DC的开关噪声会直接耦合进ADC的电源引脚,对精密模拟测量是致命的。如果系统里确实必须用DC-DC,那么距离和滤波要足够:至少两级LC滤波,ADC的AVDD引脚单独走一小段星形接地。

每个电源引脚旁边放一个100nF陶瓷电容,同时再放一个10μF左右的钽电容或者X5R陶瓷电容吸收低频纹波。ADS122U04的数字电源和模拟电源建议分别走线,参考电压引脚上的滤波电容选用低ESR、低温度系数的C0G材质。

我踩过的一个真实教训是:参考电压引脚旁边的100nF电容用的是X7R材质,在温度变化时容量漂移了将近15%,导致参考电压漂移,结果整个系统在常温下校准得好好的,一到60℃机柜里就跑偏了零点几度。后来换成C0G电容,问题消失。电容选型这件事,精密测量的板子上真不能偷懒。

3.2 UART电平匹配和引脚分配

PIC18LF47K42和ADS122U04都在3.3V下工作,TTL电平直接互连没有问题,不需要电平转换。连线方式很简单:

  • PIC的UART_TX(比如RC6引脚)接ADS122U04的RXD引脚
  • ADS122U04的TXD引脚接PIC的UART_RX(比如RC7引脚)
  • 公共地线一定要连好,两边地线电位差太大时UART的起始位会误判

这组线在布线上建议加33Ω到47Ω的串联电阻,用来抑制信号振铃和过冲。线长控制在3厘米以内比较稳,如果PCB空间允许,UART线上也可以加小容量的RC滤波。

需要特别提醒的是:PIC18LF47K42的RX引脚要配置成输入模式,同时使能内部弱上拉。因为ADS122U04的TXD在空闲时是高电平,但如果它还没上电或者处于复位状态,TXD可能输出高阻,这时如果PIC的RX没有上拉,线路上就会出现不确定电平,UART模块会把它当作持续的空闲或者意外的起始位,导致接收逻辑错乱。这个问题在断电重启时尤其容易出现,加一个10kΩ外部上拉或者用MCU内部弱上拉都能解决。

3.3 传感器输入端的滤波与保护电路

传感器信号进ADC之前,必须经过RC低通滤波。这个滤波有两个作用:一是滤除高频电磁干扰,二是配合Δ-Σ调制器内部的输入采样电路,抑制电荷注入引起的电压毛刺。

常用的滤波结构是差模RC:在每个模拟输入引脚串联一个电阻(比如1kΩ到10kΩ),然后在ADC输入引脚和AINN参考地之间并一个电容(比如1nF到10nF)。电阻和电容的取值需要参考ADC数据手册中关于输入阻抗和源阻抗的建议,源阻抗过大会导致增益误差。

对于工业现场,输入端还要加ESD防护和过压保护。最常见的是在输入线上放TVS二极管或者PTC自恢复保险丝加钳位二极管的方式。HVAC机柜里静电和雷击浪涌不像户外那么严重,但变频器旁边的高频开关噪声是真实存在的,TVS钳位位置要尽量靠近连接器,滤波位置要尽量靠近ADC引脚,这是基本排布原则。

4. 固件实现:从UART协议到24位数据解析的完整链

硬件画完只是万里长征第一步,真正让系统跑起来的是固件里那一套命令交互和数据处理逻辑。我把核心流程拆成四段:初始化配置、读取数据、RTD换算、热电偶换算。

4.1 UART驱动与寄存器配置的关键序列

PIC18LF47K42的UART模块初始化很简单,设置波特率为19200、8位数据、1位停止位、无校验。内部振荡器FOSC选择16MHz或者32MHz,配置好BRG寄存器。ADS122U04上电后默认状态可能不是我们想要的,所以固件要做一套标准的初始化序列:

  1. 发送复位命令,让ADC进入已知状态
  2. 写入配置寄存器0:设置输入通道多路复用选择、PGA增益
  3. 写入配置寄存器1:设置数据速率、转换模式(连续/单次)和内部温度传感器使能
  4. 写入配置寄存器2:选择内部参考电压或者外部参考,设置PGA旁路状态
  5. 写入配置寄存器3:设置IDAC电流源档位和流向通道
  6. 发送启动命令,开始转换

这里我不列出每一字节的具体值,因为不同版本的数据手册在寄存器映射上有细小的差异,固件里建议用宏定义把配置参数集中起来,并且加一段上电自检流程:回读配置寄存器,确认写入值和目标值一致,如果不一致就报错重试。这个自检流程在实际项目中能帮你排查一大半的通信问题。

PIC端UART发送命令时要注意,命令与命令之间要留出足够的响应间隔。ADS122U04的UART模块需要时间处理命令,连续快速发送命令可能导致丢字节。我习惯的做法是每发送一条命令后延时1ms到2ms,读寄存器时还要等数据稳定后再发下一条。这个节奏在调试阶段很管用。

4.2 24位数据的符号扩展与电压计算

ADS122U04的输出是24位二进制补码。读数据的时候,发送读数据命令,然后接收三个字节:最高字节、中间字节、最低字节。接收完后,要把这三个字节组合成一个32位整数,再做符号扩展。

C语言里的典型处理方式如下:

#include <stdint.h> // 把三个字节拼成24位有符号整数 int32_t ads_read_signed24(uint8_t msb, uint8_t mid, uint8_t lsb) { int32_t raw = ((int32_t)msb << 16) | ((int32_t)mid << 8) | lsb; // 如果最高位是1,按24位符号扩展 if (raw & 0x800000) { raw |= ~0xFFFFFF; // 扩展符号位到32位 } return raw; } // 电压换算 // vref为参考电压,pga为增益 float ads_raw_to_voltage(int32_t raw, float vref, float pga) { float voltage = (float)raw / 8388608.0f; // 除以2^23 voltage *= vref; voltage /= pga; return voltage; }

这里除以2^23的原因是24位二进制补码的满量程对应±Vref/pga。实际上有些Δ-Σ ADC的满量程是±0.5×Vref,不同器件定义略有不同,建议查看数据手册里编码(code)与输入电压的换算公式,按官方公式来。工程上这个系数差一倍的错误不难通过接一个已知电压源来验证,别偷懒。

4.3 RTD温度换算:直接用Callendar-Van Dusen方程还是查表

PT100的阻值和温度的关系不是线性直线,温度越高,斜率略微变大。工程上有两种换算路线:

第一种是直接用Callendar-Van Dusen方程解析计算。这个方程是一个关于温度T的多项式:

  • 对于0℃以上:Rt = R0 * (1 + AT + BT²)
  • 对于0℃以下:Rt = R0 * (1 + AT + BT² + C*(T-100)*T³)

其中,PT100的典型系数A=3.9083e-3,B=-5.775e-7,C=-4.183e-12。这个方程从阻值反推温度时,需要解一元二次方程(0℃以上),计算量不大,8位MCU上用浮点算也毫无压力。

第二种是查表法:把温度-阻值分度表预先存在Flash里,用二分法查找到最接近的相邻两点,再做线性插值。查表法的优点是无需解方程,适合对精度要求不极致、希望代码简单的场合。

我个人的建议是:如果你手头MCU的Flash够大(PIC18LF47K42有32KB以上Flash,放一个301点分度表只需要1.2KB左右),强烈推荐查表法。因为查表法天然规避了浮点解方程的复杂性和潜在的小数运算误差,而且装分度表这种方案在后期换传感器类型(比如PT100换PT1000)时只需要换表,不用动算法。

如果用Callendar-Van Dusen方程,还要注意:RTD实际测到的是阻值,但ADC读回的是电压,中间需要先根据激励电流和增益反算出阻值,再做温度换算。以PT100做比例测量为例:

// 已知:idac为激励电流,gain为PGA增益 // 测得电压为v_sense float rtd_resistance(float v_sense, float idac, float gain) { float v_in = v_sense * gain; // 回到ADC输入端实际电压 return v_in / idac; // 电阻 = 电压 / 电流 }

注意这里v_sense是ADC读到的电压,除以激励电流得到的是包括引线电阻在内的总电阻,如果用了四线制,引线电阻的影响才可忽略。三线制上面说过有补偿机制,但补偿的前提是两根引线电阻相等且IDAC1和IDAC2的实际电流一致,现场做不到完美,所以会有残余误差。

4.4 热电偶查表和冷端补偿的具体步骤

热电偶的换算流程比RTD多一点,因为要先处理冷端补偿。我把K型热电偶的标准处理流程写成伪代码:

1. 读取热电偶通道原始码值,换算成电压v_tc_raw 2. 读取冷端温度传感器(NTC或ADC内部温度),换算成冷端温度T_cold(单位℃) 3. 用T_cold查K型热电偶分度表,得到冷端温度对应的热电势v_cold_offset 4. 修正后的总热电势 v_total = v_tc_raw + v_cold_offset 5. 用v_total查热电偶分度表(温度-热电势的反向表),得到测量端温度T_hot

这里有一个很容易做反的点:第3步查出来的冷端热电势的极性。冷端补偿电压是要加到热电偶测量电压上去的,因为实际冷端温度高于0℃时,热电偶输出电压比“冷端假设为0℃”时低了,所以必须加上这个补偿电压。如果你发现最终温度越往高处越偏小,多半是这一步的极性搞反了。

查表的时候,推荐用二分查找加线性插值。K型热电偶的分度表数据密度通常是每1℃一条或者每10℃一条,插值后的误差远小于热电偶本身的不确定度。我这里给一个C语言里做线性插值的示意:

// table: 温度表,电压表,点数n;target: 目标电压 float table_interpolate(const float *temp_tab, const float *volt_tab, int n, float target) { int lo = 0, hi = n - 1; while (hi - lo > 1) { int mid = (lo + hi) / 2; if (volt_tab[mid] < target) lo = mid; else hi = mid; } float t0 = temp_tab[lo]; float t1 = temp_tab[hi]; float v0 = volt_tab[lo]; float v1 = volt_tab[hi]; return t0 + (target - v0) * (t1 - t0) / (v1 - v0); }

冷端温度传感器在HVAC应用里用NTC就足够了,因为NTC的非线性会导致大范围温度内误差较大,但冷端温度通常只在-10℃到70℃这个范围内变化,用NTC查表能在0.2℃以内,已经满足绝大多数HVAC项目要求。如果用ADS122U04的内部温度传感器,精度等级看数据手册,多数时候是±1℃量级,做CJC时这个误差会直接叠加到最终温度结果上,所以对精度要求高的项目,我建议外接精度更高的NTC或者半导体温度传感器,不要把宝押在ADC内部的温度传感器上。

5. 现场校准与噪声排查:HVAC机柜里的实战心得

硬件和固件都能跑通之后,系统离“好用”还差一步:校准和抗噪。这部分的经验往往来自现场,在任何开发文档里都学不到。

5.1 两点校准和多点校准的实际操作

精密温度测量系统,光靠理论计算往往达不到标称精度,因为电阻容差和基准电压误差会叠加。现场校准的最简单方法是两点校准:把传感器放到冰水混合物(0℃)和沸水(100℃)里,记录ADC读数,然后修正比例系数和偏置。

对于RTD,校准的是整个信号链的比例因子——从激励电流、参考电阻到PGA增益的一切增益误差。做校准时要让系统在实际工作状态下运行至少15分钟,让参考电压和ADC温度都稳定下来再记录数据。冰水混合物要注意混合均匀,沸水要注意大气压对沸点的影响,100℃这个点在高原地区并不准确,这是工程常识。

对于热电偶,校准的重点是冷端补偿。方法是:把热电偶测量端和参考端放在同一个温度环境中(比如都放在恒温箱里),此时理论上输出电压应该是0mV,如果系统读出来不为零,那就是冷端补偿误差,记录下来作为偏置修正。

我做过最靠谱的校准流程是三步:先用精密电阻箱代替PT100扫一遍整个温度范围,记录ADC码值;再用标准温度源(恒温槽加二等标准铂电阻)做最终校准;最后把所有校准数据拟合成多项式存进EEPROM。这套流程做完,系统在-20℃到120℃范围内的实测误差可以稳定控制在0.15℃以内。

5.2 变频器干扰引起的跳数问题:一个典型排查过程

有个项目在实验室里一切正常,装上AHU控制柜通电就发现,热电偶通道的数据时不时跳出几个完全不合逻辑的尖峰,比如显示35℃突然跳到-120℃然后又回来。我当时的第一反应是UART通信出了问题,因为这种大跳变很像解包错误。但把波特率降到9600、加上停止位校验都没用。

后来用示波器挂在热电偶输入端,才发现问题根本不是通信,而是变频器启动时在模拟输入上感应了几伏的共模电压尖峰,直接把ADC的PGA打饱和了,造成转换结果整个飞掉。电源线上也有明显的开关噪声,虽然没影响UART,但污染了ADC的模拟参考。

解决办法有三个:

  1. 在热电偶输入线上加共模扼流圈,把共模干扰在进入ADC之前先干掉
  2. 在ADC电源引脚加第二级LC滤波,电源净化以后PGA的底噪明显下降
  3. 固件里加数据合理性检查,对超过物理合理变化速率的采样值做丢弃和重读

这个案例给我的教训是:精密测量系统的抗干扰必须从模拟前端做起,固件滤波只是最后的兜底措施,不能把宝全押在软件上。

5.3 UART通信误码和重连机制

UART虽然比SPI抗长线干扰能力强,但在工业环境下误码并非不可能。我在项目里遇到过这样的情况:系统长时间运行后偶尔出现某个温度值变成0或者变成满量程,重新初始化ADC之后恢复正常,但过几天又出现。

排查下来的根因是:PIC18LF47K42的UART接收缓冲区溢出导致按字节错位,后续所有命令都全乱了。ADC的响应帧和MCU的命令之间一旦错位,整个协议就永久性错乱,必须复位ADC模块才能恢复。

解决机制有三个要点:

  1. 每条命令后都确认ADC的响应字节,发现任何不匹配就重启该通道
  2. 在PIC端给UART数据解析设置超时,如果一个完整帧在预期时间内没接收完,就丢弃重来
  3. 系统级增加看门狗,MCU异常挂起时自动复位,上电初始化时强制对ADC发复位命令

这三板斧下去,系统在连续通电两个月的测试里没有再出现一次温度数据错误。说到底,工业现场的通信系统不能假设永远不出错,必须在协议层设计自我恢复的机制。

6. 长期运行给测量误差带来的隐形影响

最后聊一点很多人会忽略的维度:时间对精度的影响。HVAC和工业项目里的测温系统不是实验室里用几天就拆的,而是要在机柜里连续运行好几年。这时候必须考虑元件老化和环境漂移。

参考电阻是比例测量中最重要的元件,它的温漂直接变成系统误差。选型时我坚持用25ppm/℃以内的精密薄膜电阻,甚至10ppm。一个25ppm的电阻在40℃环境温升下会漂0.1%,换算到RTD测量就是约0.25℃的误差。好多人舍不得在这颗电阻上花钱,结果在现场被误差困扰到怀疑人生。

另一个隐形问题是接插件和端子排的氧化。HVAC机柜湿度大,铜端子排氧化后接触电阻会变大。三线制RTD如果有一根引线接触不良,比例测量还算能自补偿一部分,但热电偶端子氧化会导致接触电势不稳定,这个很难标定,只能靠定期巡检。我在项目里固定要求现场运维每半年重新紧固一遍传感器端子,并要求端子在选型时优先镀金或者镀镍。

还有ADS122U04内部温度传感器的问题。前面说过,如果用它做热电偶冷端补偿,它测的是芯片温度不是端子温度。芯片离冷端端子有物理距离,机柜里晒到太阳和半夜降温的两种情况,芯片温度可能和端子温度差好几度。我见过有项目把整个补偿误差归咎于ADC噪声,实际上那是热电偶接法和冷端传感器位置设计不合理造成的。真要追求精度,把NTC贴在端子排上,用隔热材料包住端子,让热梯度尽量小,才是正道。

电源LDO也有老化问题,输出电压在整个寿命期内可能漂移几十毫伏,如果系统用的是跟随电源电压的内部参考,就会引入长期漂移。解决的办法是优先使用ADS122U04的内部2.048V基准,或者外部精密基准源,不要用电源电压直接当参考。

走到这一步,ADS122U04加PIC18LF47K42这套组合从选型到运行维护的完整拼图已经齐了。如果你想在这条路上走得更远,可以在PIC上继续扩展Modbus RTU从站协议,把温度数据通过RS-485送到楼宇自控系统,或者在ADC的数据速率和数字滤波上做进一步调优。我在实际项目中最常说的一句话是:精度的上限在最初那一张原理图上就已经决定了,固件只能在它的边界内把事情做到极致。这套方案能撑起大多数HVAC和工业温度采集项目的精度要求,希望这篇分享能让你在自己的项目里少走几个我走过的弯路。

返回列表