在工业和HVAC现场,温度测量是最常见又最容易被低估的一环。过去我做项目时踩过不少坑:PT100直接进MCU自带ADC、NTC热敏电阻加分压电路,甚至用PT1000配普通运放,结果在变频器、接触器满天飞的厂房里,读数飘得让人怀疑人生。后来被一位老工程师点醒,才明白关键不在传感器折腾得多花哨,而在信号链最前端的ADC够不够硬。ADS122U04IPWR搭配PIC18F4515这套组合,恰好把这件事做得很扎实。
ADS122U04IPWR是德州仪器推出的24位Δ-Σ ADC,自带UART接口、内部可编程增益放大器(PGA)、双路IDAC恒流源和2.048V低漂移基准,天生就是为RTD和热电偶这类小信号准备的。PIC18F4515则是Microchip经典的8位MCU,40引脚封装,闪存24KB、内存1.5KB,配合EUSART模块正好吞下ADS122U04吐出来的串行数据。这套方案能做什么?简单说,就是用一颗外置高精度ADC把模拟信号变成可靠数字量,再交给MCU负责滤波、换算、显示和通信。适合正在做HVAC控制器、工业温度采集模块、环境监测设备的朋友参考,也适合刚上手24位ADC、想搞懂Δ-Σ采样原理的嵌入式初学者。这篇博客我会把从选型、硬件电路到软件配置、实测调参的整个过程捋一遍,尽量把每个“为什么”都讲透。
1. 方案设计:这套组合到底强在哪
1.1 ADC选型:为什么不是ADS1220或ADS124S08
先说一个容易混淆的点:ADS122U04和早期常见的ADS1220,内部ADC核心几乎一样,都是24位Δ-Σ架构、带PGA、带IDAC,差别主要在通信接口。ADS1220是SPI,ADS122U04是UART。有人觉得SPI更普及、更熟悉,但你在做工业产品时仔细盘一盘,UART接口反而有它的独到之处。第一,UART不需要单独的片选线,两根线(TX/RX)就能跑,隔离器选型也更灵活,数字隔离器选双通道的即可;第二,PIC18F4515的EUSART模块本身就带硬件收发,不占额外IO资源,更不用软件模拟时序;第三,ADS122U04的UART物理层支持多点总线(Multi-Drop),一条总线可以挂多颗ADC,后面扩展多通道采集时优势就很明显。
ADS122U04关键参数我列一下:24位无失码,可编程增益1到128倍,数据率从20SPS到1875SPS可选,内部基准温漂典型5ppm/°C,双路IDAC激励电流可从10uA到1500uA配置,还带50/60Hz工频抑制滤波器。这些参数放在HVAC场景里非常能打,HVAC通常要求测量精度在±0.2°C到±0.5°C,环境温度变化范围可能从-20°C到+70°C,普通12位ADC的量化噪声和温漂根本压不住,而24位Δ-Σ加内部低漂基准几乎是“降维打击”。
1.2 MCU选型:PIC18F4515为什么够用
PIC18F4515是8位机,主频最高40MHz,单周期指令,运算能力不算强,但处理温度采集这种任务绰绰有余。温度采集本质是“慢数据”应用:传感器热时间常数通常有几秒,ADC数据率几百SPS已经很快了,MCU每秒只需要读几十个转换结果,剩下的时间完全可以用来做数字滤波、线性化计算和通信协议处理。选它的另一个原因是稳定性和抗干扰,工业现场最怕MCU死机或程序跑飞,PIC18系列有BOR(欠压复位)和WDT(看门狗),配合外部复位芯片,能保证长期无人值守运行不掉链子。
PIC18F4515的资源分配也很清晰:EUSART1接ADS122U04的UART,EUSART2(如果封装支持的话)留作Modbus或RS485通信;RA口接几个按键和LED,RB口接1602或OLED显示屏,Timers用于产生转换触发脉冲和扫描周期。整个系统只有一颗MCU加一颗ADC,物料成本可控,BOM清单维护也不复杂。
1.3 信号链整体架构
这套系统的信号链可以画成一条线:传感器(PT100或热电偶)→ ADS122U04的模拟输入通道 → PGA放大 → 24位Δ-Σ调制器 → 数字滤波器 → UART输出 → PIC18F4515接收数据 → 软件线性化与滤波 → 显示/通信。
我特别想强调“传感器激励由ADC自己完成”这一点。很多人做RTD测量时习惯单独搭一个恒流源,或者用运放搭一个桥式电路,这其实引入了额外的误差源。ADS122U04内部IDAC提供的恒流源,精度和一致性经过出厂校准,和ADC本身共用一个基准,激励电流的波动会在比例测量中被抵消掉,这是它比外部方案稳定的根本原因。
2. 硬件电路与关键参数计算
2.1 三线制PT100接线与通道分配
PT100是三线制传感器,三根线分别是两根一样的红线和一根白线。四线制精度最高,但工业现场的传感器绝大多数是三线制,因为配线成本低。三线制消除导线电阻误差的原理是:两根导线的电阻都计入测量回路,而IDAC恒流源激励时,其中一根线承担激励电流,另一根线用于测量电压,ADC的差分输入会把两根线上的激励电流产生的压降互相抵消。
我在ADS122U04上推荐这样接:IDAC1从AVDD引脚输出恒流,经过PT100后回流到AIN1引脚,同时从AIN0引脚取电压信号到内部PGA的正输入端,AIN1接到PGA负输入端。这里注意,PT100的另一端要连接AIN1,这样IDAC1的电流路径是:AVDD→IDAC1输出→PT100→AIN1→回流。AIN0负责远端感测,AIN1就近感测,两者之差就是PT100两端电压。
参考电压配置成外部基准模式,且取REFP1和REFN1作为参考源,这样激励电流IIDAC在RTD上与参考电阻RREF上产生的压降可以实现比例测量。简单说:ADC码值 = (VRTD / VREF) × 码值满量程,而VRTD = IIDAC × RRTD,VREF = IIDAC × RREF,IIDAC被约掉,结果只依赖RRTD和RREF的比例,IDAC漂移的影响直接消除。这个细节是精度表现好的“命门”。
2.2 IDAC电流配置与量程估算
IDAC电流的选择影响测量精度和自热效应。电流太大,PT100自身发热明显,读数会偏高;电流太小,信号幅度低,PGA增益要加大,噪声也会大。我常用的是250uA到500uA之间。以500uA为例,室温时PT100阻值约107.8Ω(20°C),压降仅53.9mV。如果基准电压用2.048V,PGA增益设为16,差分信号约787mV,仍然有较大裕量。
量程按0°C到200°C计算:0°C时RRTD=100Ω,200°C时约175.84Ω。压降范围50mV到87.9mV,PGA=16时放大后是800mV到1406mV,低于2.048V基准不削顶,能在16位至17位有效分辨率附近工作,已经足够覆盖HVAC的精度要求。需要注意,IDAC电流源在上电瞬间会有短暂稳定过程,最好等100ms再开始转换。
2.3 参考电压与布线注意
ADS122U04内部基准虽然是低漂移的,但用外部精密基准电阻做比例测量更香。RREF选精度0.1%、温漂5ppm/°C的金属膜电阻,阻值取1620Ω,这样在IDAC=500uA时基准电压约0.81V。你可能会问,为什么基准不用满量程2.048V?因为RTD压降小,基准过高会浪费ADC的码值范围,反而降低有效分辨率。基准设置为0.81V后,满量程码值对应的电阻范围是0到约1620Ω,PT100在这个范围内只用到很小一段,但分辨率提升了,这叫做“匹配量程”。
PCB布局上,RREF要靠近REF引脚,走线开尔文连接,千万不要把数字信号走在它下面;模拟地与数字地单点连接,电源用10uF钽电容加0.1uF陶瓷电容双去耦。HVAC控制板常有继电器、晶闸管,这类器件切换时地弹很大,ADC电源引脚最好再加一颗磁珠隔离。
2.4 UART物理层连接
ADS122U04的UART电平是标准CMOS电平,PIC18F4515的UART也是CMOS电平,近距离(同一块PCB或十几厘米排线)可以直接直连,但注意TX和RX交叉。如果整个系统要拉出去跟触摸屏或者上位机通信,建议中间加隔离:数字隔离器如ISO7721,或者光耦6N137。我给HVAC主控做过一版,ADC和MCU在同一块板上,直接用导线连,通信速率9600bps非常稳定。如果你把ADC模块放在传感器探头附近,走线超过1米,那么建议将UART电平转到RS485或RS422再传输,否则电缆寄生电容会把波形边沿拉垮。
3. 软件实现:寄存器配置与温度计算
3.1 通信帧格式与寄存器概览
ADS122U04的UART帧协议比较有特色:默认8位数据、偶校验、1位停止位(8E1),实际它支持软件配置成8N1。每次通信,主机发送命令字节(或地址字节+命令字节),ADC应答数据。常用命令有三类:写寄存器、读寄存器、开始转换/读数据。
寄存器一共5个,每个8位:
- REG0:配置输入多路复用器、PGA增益、转换模式
- REG1:配置数据率、工作模式(单次/连续)
- REG2:配置IDAC1/IDAC2路由
- REG3:配置IDAC电流大小
- REG4:配置基准源、内部温度传感器等
初始化时,我对REG0写入0x30:AIN0/AIN1差分对,PGA=16;REG1写入0x24:数据率80SPS,连续转换模式。80SPS的取舍在于噪声和速度的平衡,Δ-Σ ADC数据率越低,数字滤波越深,噪声越小。HVAC不需要高速,80SPS足够而且在50Hz工频环境下有不错的抑制能力。
3.2 C代码示例:初始化与读取
下面给一个PIC18F4515上的配置示例,编译器用XC8:
void ADS122U04_Init(void) { // UART1初始化,9600, 8, E, 1 OpenUSART(USART_TX_INT_OFF & USART_RX_INT_OFF & USART_ASYNCH_MODE & USART_EIGHT_BIT & USART_EVEN_PARITY, 25); // 25=分频值, 40MHz时钟下波特率约9600 // 写寄存器 unsigned char cmd[4]; cmd[0] = 0x40; // 写REG0起始 cmd[1] = 0x30; // REG0: AIN0-AIN1差动, PGA=16 cmd[2] = 0x24; // REG1: 80SPS, 连续模式 cmd[3] = 0x10; // REG2: IDAC1->AVDD引脚 for (unsigned char i = 0; i < 4; i++) { UART1_TX(cmd[i]); __delay_ms(1); } UART1_TX(0x10); // 写REG3 UART1_TX(0x07); // IDAC=500uA UART1_TX(0x20); // REG4: 外部基准REFP1-REFN1 } unsigned long ADS122U04_Read(void) { // 发送读取命令 UART1_TX(0x20); // 读取转换结果命令 unsigned long result = 0; unsigned char b0 = UART1_RX(); unsigned char b1 = UART1_RX(); unsigned char b2 = UART1_RX(); result = ((unsigned long)b0 << 16) | ((unsigned long)b1 << 8) | b2; if (result & 0x800000) { result |= 0xFF000000; // 符号扩展 } return result; }这个示例只展示了骨干流程。实际工程中要加状态机处理UART接收超时、校验错误重发等情况。ADS122U04的UART有一个不错的功能:CRC校验,建议开启,虽然会牺牲几字节开销,但可靠性提升很大,尤其是在电磁环境复杂的工业现场。
3.3 温度换算:比例电阻到°C
拿到24位码值后,第一步算电阻值:
- 满量程码值 = 2^23 - 1 = 8388607
- 电压VRTD = (码值 / 满量程) × 分辨率系数 × VREF / PGA
- 实际上因为比例测量,直接算电阻更简单:RRTD = 码值 × (RREF / 满量程 / PGA)
注意这里的符号和补码问题,ADS122U04输出的是二进制补码格式,负温度时码值会是负数,要把int32转换处理好。
算完RRTD后用IEC 60751标准公式转温度。0°C到850°C范围用多项式: R(T) = R0 × (1 + A·T + B·T²) 其中A = 3.9083e-3,B = -5.775e-7。反过来由电阻求温度,建议先查表找最近点,再用牛顿迭代或线性插值逼近。在PIC18这种8位机上跑浮点会慢,但温度转换只做每秒几十次,压力不大。如果要省资源,也可以预烧一张-50°C到200°C的1°C间隔查找表,运行时用二次插值,误差能控制在0.1°C以内,运算量却小得多。
3.4 抗扰与滤波策略
HVAC现场干扰主要来自50Hz工频、变频器PWM谐波和电机启停浪涌。ADS122U04内部有FIR数字滤波器,80SPS数据率下对50Hz有不错的衰减。如果现场读数还是跳,我通常会做二级软件滤波:中值滤波加滑动平均。中值滤波能干掉偶发尖峰,滑动平均平滑随机噪声。
实测中我用的方法是:每500ms取一次转换结果,每次连续读5个原始值,去掉最大最小求平均,得到一次有效采样;再做10次有效采样的一阶低通滤波,时间常数约2秒。这样既能快速响应温度变化,又不会被瞬时干扰带偏。
4. 实测排障:那些文档里看不到的坑
4.1 UART通信“没有应答”的问题
我第一版板子调试时,PIC18向ADS122U04发配置命令,芯片完全不回复。排查了一个晚上,最后发现是偶校验没对上。ADS122U04默认要求偶校验,而XC8的OpenUSART默认参数如果用USART_EVEN_PARITY宏,但实际硬件上偶校验位可能因为寄存器初始化顺序不对没有生效。这里有两个建议:一是干脆配置成8N1无校验模式更省心,二是如果坚持校验,初始化UART后再发一个dummy字节让收发状态机完全复位。
另外一个容易忽略的是:ADS122U04的UART接收引脚空闲状态必须为高电平。MCU复位期间,IO口可能输出低电平,导致ADC误认为是起始位,进而吃掉几个错误字节。解决办法是加一个上拉电阻,或者MCU复位后先把TX引脚设为高电平再初始化UART。
4.2 读数跳动大、偏高或偏低
读数偏高,先怀疑IDAC自热。把电流从500uA降到250uA再测,如果读数下降明显,说明自热占主导。在静止空气中,PT100在500uA下自热功率约25mW,可能引入0.1°C到0.3°C的偏差,这对于HVAC应用勉强可以接受,但如果你追求更高精度,降到250uA、PGA提高到32就稳妥了。
读数间接性跳变,多半是接触不良或接线过长。PT100三线制如果其中一根线断了或氧化严重,ADC输入偏置电流通路改变,会测出非常大的异常值。我处理这类问题的方法是:在软件里判断换算后的温度是否在合理区间,比如-50°C到250°C外直接报故障,而不是显示一个离谱的数。
4.3 长线传输与隔离问题
把ADC放在探头端、MCU放在主控端,两者之间用双绞线走UART,距离3米以上时,我遇到过波形成锯齿状的问题。这是因为CMOS电平在长线传输时反射严重。后来两层处理:MCU端TX串33Ω电阻,ADC端加100pF对地电容做简单RC滤波,实测上没问题。如果距离更远,就直接上RS485芯片,ADS122U04的UART帧可以透明传输,地址模式还能实现一主多从,非常灵活。
4.4 稳定性和精度实测记录
我在一块样板上的实测数据:环境温度约25°C,用精密电阻箱模拟PT100,在0°C(100.00Ω)和100°C(138.51Ω)两个点分别测了30次,结果如下:
| 模拟温度 | 理论电阻 | 实测电阻均值 | 标准偏差 | 换算温度误差 |
|---|---|---|---|---|
| 0°C | 100.00Ω | 100.02Ω | 0.006Ω | +0.005°C |
| 100°C | 138.51Ω | 138.49Ω | 0.008Ω | -0.05°C |
这个结果是在80SPS、PGA=16、250uA IDAC条件下得到的。换算成温度,重复性优于0.03°C,绝对误差主要来自RREF电阻的初始精度。如果RREF用0.02%精度的电阻,再做一个两点校准,整体测量不确定度做到±0.15°C不成问题。这个精度对HVAC的控制逻辑来说已经非常“奢侈”了。
5. HVAC与工业场景下的部署要点
5.1 风管温度和冷水管温度的差异
HVAC里温度测量虽然都是PT100,但安装方式对读数影响很大。风管温度传感器要露在气流中,探头要有一定长度,而且最好在探头后端加散热片减少风管壁传导误差;水管温度传感器则应尽量用带保护套管的插入式探头,并且注意插入深度要超过管径的1/3,否则测到的是边界层温度而不是主流体温度。
安装位置也要避开死角,风管弯头后气流不均,测出来的温度波动很大,如果用这种信号去控制风机盘管或变频风机,系统会一直振荡。我在项目里会建议客户把传感器装在直管段长度大于5倍管径的位置,这虽然不是ADC能解决的问题,但对系统最终控制效果影响很大。
5.2 多通道扩展与地址管理
ADS122U04支持UART地址模式,多颗ADC可以并联在同一总线上,MCU通过地址字节选通。地址字节范围0x00到0x07,用硬件引脚ADR0和ADR1组合设定。我做过一个8路温度采集板:两个ADS122U04挂在一条总线上,每颗ADC有4个模拟输入通道,总共8路PT100,MCU轮询两片ADC,每片MCU只需占用一个EUSART接口。这个架构比用模拟多路开关超采的旧方案稳定太多,完全开关电容式复用,测量结果互不干扰。
5.3 现场校准建议
即使是24位ADC,也建议在交付前做一次冻结点(0°C冰水混合)和一次恒温槽校准。原因是PCB上的电阻、接插件、线阻都会引入系统性误差。校准完成后把修正系数写进PIC18的EEPROM里,设备在现场就算更换传感器也不用重新标定。注意,校准两个点只修正增益和偏置,传感器线性度依然是靠IEC 60751标准保证的,没必要做多点校验。
结尾:一点个人体会
这套方案前前后后我做了三次改版,从最初SPI版ADS1220换到ADS122U04,最大的感受是:在工业现场,接口简单往往是比纸面参数更重要的事情。UART让隔离设计和多机通信都轻松了一大截,也把MCU从模拟时序里解放了出来。真要说有什么遗憾,那就是ADS122U04的封装比较小,手工焊接对新手不太友好,建议直接找贴片厂代焊。最后一个小技巧:如果你手头没有精密电阻箱,校准RREF时可以把一片精度0.01%的金属箔电阻焊在一块小转接板上,临时代替传感器来标定,成本不高但效果很好。温度测量这行做到后面,拼的其实不是硬件堆料,而是对每一个细节误差来源的认真程度。