☰
基于ADS122U04IPWR与PIC18的双通道精密温度采集模块设计
2026/11/5 3:11:17 网站建设 项目流程

在工业现场和HVAC系统里,“把温度测准”这件事,听起来很简单,做起来全是细节。前阵子用 ADS122U04IPWR 这颗带UART接口的24位精密ADC,配合 PIC18LF45K80 单片机做了一套双通道温度采集模块,专门对接风管温度、换热器水管温度和几路模拟量输入。板子调完以后,稳定性比我之前直接用MCU内置ADC的方案高了一个量级,而且整个通信链路、寄存器配置、校准逻辑都沉淀出了一套可以复用的模板。趁还热乎,把这套方案的选型逻辑、硬件设计、固件实现和踩坑记录整理出来,给正在做工业测温或者HVAC控制器选型的朋友做个参考。

这套组合最打动我的地方,是把“精密模拟采集”和“现场总线通信”这两件原本要花大力气整合的事,拆成了两条清晰的技术路线:ADS122U04IPWR负责把毫伏级传感器信号变成可靠的数字量,PIC18LF45K80负责协议处理、逻辑控制和上位机通信。下面按设计决策、硬件细节、固件实现、调试实录几个维度逐个拆开讲。

1. 方案整体思路与选型逻辑

1.1 工业与HVAC测温场景的核心需求

做工业或者HVAC的测温模块,第一件事不是选芯片,而是把需求边界划清楚。HVAC场景的温度测量,比如楼宇自控里的回风温度、送风温度、冷水/热水管温度,量程基本集中在-40°C到150°C之间,精度要求大多是±0.5°C以内,传感器以PT1000和NTC为主,信号线长度从几米到几十米不等。工业场景就复杂的多,可能涉及电机绕组温度、变频柜内部温升、管道介质温度,量程会拉到-200°C到850°C,甚至用到热电偶,现场干扰源也多——变频器、接触器、大功率电机,电磁环境相当恶劣。

这些需求归结下来有三条硬指标:小信号分辨率要够高、抗干扰能力要够强、通信接口要适合远距离传输。MCU内置ADC在很多低成本项目里能用,但面对12位左右的有效分辨率、参考电压随温度漂移、PCB布局稍有不慎就引入噪声这些限制,做精密测温非常吃力。这也是我这次坚持要用独立ADC芯片的根本原因。

1.2 为什么选ADS122U04IPWR而不是普通SPI ADC

ADS122U04IPWR这颗芯片最特别的地方,是它把UART接口做进了24位Δ-Σ ADC里。传统的高精度ADC基本清一色是SPI或I2C接口,比如ADS1220、AD7793这类,MCU必须通过4线SPI去读数据。SPI的问题在于:线多、时序要求高、不适合直接长线传输,隔离设计也更麻烦。而UART天生就是为远距离通信设计的,在很多工业设备里,MCU本来就有一路UART空闲出来,直接接上去就行,如果现场传输距离再拉长,还可以在ADC和MCU之间加一片RS-485收发芯片,把这套采集方案直接延伸到上百米的现场。

从信号链角度来看,ADS122U04IPWR集成度也足够高。内部带了可编程增益放大器(PGA),增益从1到128倍可调;两个激励电流源(IDAC),可以直接驱动PT100/PT1000;内部参考电压和内部温度传感器也都是标配。这意味着做一路RTD测温,外部只需要传感器、几个电容电阻,不需要单独的仪表放大器、恒流源和精密基准源。BOM成本省下来的同时,故障点也少了。

1.3 PIC18LF45K80在这套系统里的角色

PIC18LF45K80是Microchip面向工业应用的一颗8位MCU,工作电压可以低到1.8V,温度范围覆盖工业级,最重要的是自带ECAN模块(CAN 2.0B),同时还集成了多个UART、I2C/SPI、EEPROM和大容量Flash。在HVAC设备里,上层控制器的通信方式往往是RS-485总线,走Modbus RTU或者BACnet MSTP协议;在工业设备里则常常直接上CAN总线。这颗MCU有硬件CAN控制器,后续只要加一个CAN收发器就能接入现场网络,这是我选它而不是其他8位MCU的一个重要原因。

它的UART模块在9600波特率下的配置很灵活,内部振荡器经过校准后也能满足UART通信要求,但对精密测温这种对长期稳定性敏感的场景,我建议还是用外部晶振,实际测试中内部振荡器在温度爬升时频率会有几十ppm级别的漂移,对ADC的UART通信虽然影响不大,但对系统定时和波特率误差的影响不可忽视。

1.4 三种测温方案横向对比

我把几类常见方案放在一起做了个对比,方便理解这次选型的出发点:

对比维度MCU内置ADC外置SPI接口ADC(如ADS1220)ADS122U04IPWR UART ADC
典型分辨率10~12位24位24位
通信线数量无,内部直连4线(SCLK/MOSI/MISO/CS)2线(TX/RX)
远距离传输不适合需要额外处理可直接接RS-485
集成激励电流源基本没有部分有有,双IDAC
内部PGA通常没有有有
隔离方案复杂度简单但精度受限需要SPI隔离,成本高加数字隔离器即可
适合场景消费级、精度要求不高板级高精度采集工业/HVAC分布式测温

结论很直接:如果只是单板内部采集,SPI ADC够用;如果传感器分布在几十米范围、现场干扰又严重,UART接口的ADS122U04IPWR在系统层面优势非常明显。

2. 硬件连接设计与关键参数

2.1 传感器接线:PT100三线制与热电偶差分接入

温度传感器这块,我这次做了两路输入,一路给PT100(风管温度),另一路预留了热电偶输入(工业管道表面温度)。PT100必须用三线制接法,核心目的是消除导线电阻引起的误差。原理不复杂:激励电流从一条线流入传感器,另一条独立的线负责把传感器上的电压引回ADC的测量端,而第三条线则用来补偿引线电阻。这样即使线缆有10欧姆的电阻,只要激励电流没有流过测量回路,读数就不受影响。

ADS122U04IPWR有两个IDAC输出,用来搭三线制非常方便:IDAC1接到PT100的一端,IDAC2接在测量回路的地基准端,而采集电压的差分正端和负端分别接在传感器两端。对于热电偶,接法更简单,K型热电偶的两根引线直接差分接入AIN0和AIN1,因为热电偶输出的是毫伏级电压,完全不需要激励电流。需要注意的是热电偶引线极性不能反,接反了读出来的温度会随着真实温度升高而反向漂移,这个在调试现场特别容易坑人。

2.2 激励电流与比例式测量的计算逻辑

用RTD测温,激励电流的选择是第一个关键参数。电流越大,传感器上的压降越大,信噪比越好,但自热效应也越严重。PT100在1mA激励下,自身发热造成的温升大约是0.03°C,如果把电流加到2mA,温升按平方关系涨到0.12°C以上,这在精度要求±0.3°C的场合已经不容忽视了。所以我的选择是1mA,这几乎是精密测温场景的默认值。

比例式测量是这套方案的精髓。把外部精密参考电阻Rref串在激励电流回路上,让ADS122U04IPWR的参考电压直接取Rref两端的压降,这样ADC输出码值变成:

Code ∝ (Iexc × Rrtd) / (Iexc × Rref × PGA) = Rrtd / (Rref × PGA)

激励电流Iexc在分子分母里完全抵消了,这意味着即使电流源随温度漂移了0.5%,对最终读数也几乎没有影响。这就是比例式测量的优势——不再需要一个独立的精密电压基准,参考电阻的温度稳定性决定了最终精度。我选了25ppm/°C的金属箔电阻,温度系数对系统的影响可以忽略。

PGA增益的选择是基于满量程计算的:PT100在0°C时阻值100Ω,1mA激励下压降0.1V;在300°C时阻值约212Ω,压降0.212V。如果PGA设为4,ADC输入端最大电压约0.85V,而内部参考是2.048V,能覆盖整个量程还有足够余量。增益选太低会浪费分辨率,选太高则会过早饱和,这个要在定方案时根据实际量程算一次,不能照抄别人的配置。

2.3 MCU与ADC之间的UART通信接线

ADS122U04IPWR的UART接口需要接三根线到PIC18LF45K80:ADC的TXD接MCU的RX1、ADC的RXD接MCU的TX1、再加上公地。我另外把ADC的DRDY(数据就绪)引脚接到了PIC18的外部中断引脚INT0上,这样每次转换完成MCU都会立刻收到中断,比轮询省心得多,也方便控制采样节奏。

在电路板上这两颗芯片距离很近,直接TTL电平互连没问题。但如果这套方案要延伸到工业现场,比如把ADC放在管道旁、把MCU放在控制柜里,中间最好加一级RS-485或RS-422总线。ADS122U04IPWR的核心优势在这里就体现出来了:UART本身就是差分收发器天然友好的接口,不像SPI那样需要额外处理片选和时钟同步问题。

2.4 电源、去耦与PCB布局的实战建议

精密ADC对电源纹波和地噪声非常敏感。我在这块板子上的做法是:模拟电源和数字电源完全分开走线,ADS122U04IPWR的AVDD引脚上放了1µF陶瓷电容并联0.1µF高频电容,参考电压引脚上的去耦电容还额外串了一个4.7Ω电阻组成低通滤波。PIC18的数字电源虽然离得很近,但地平面在ADC下面做了局部切割,避免数字开关噪声直接窜进模拟地回路。

PCB布局上有一条重要经验:UART的TX和RX走线尽量远离模拟输入走线,尤其是PT100的差分信号线,哪怕只是几厘米的平行走线,UART上3.3V的边沿跳变也可能耦合到毫伏级的热电偶信号里。实测中发现,把UART走线从模拟输入旁边挪开之后,热电偶通道的底噪从十几个码降到了三四个码。这类细节手册上不会写,但现场做出来差别特别明显。

3. 固件实现:从寄存器到真实温度

3.1 UART通信链路初始化

固件开发的第一步是把PIC18LF45K80的UART模块配置好。我用的是UART1,外部晶振16MHz,波特率9600。配置的关键是波特率发生器的计算,这里把它记下来给PIC18用户参考:

// Fosc = 16MHz,目标波特率 9600,BRGH=1,BRG16=1 // Baud = Fosc / (4 * (SPBRGH:SPBRG + 1)) // SPBRGH:SPBRG = 16000000 / (4 * 9600) - 1 = 416.67 -> 取 416 void UART1_Init(void) { TRISCbits.TRISC6 = 1; // TX1 设为输入,由外设控制 TRISCbits.TRISC7 = 1; // RX1 设为输入 BAUDCON1bits.BRG16 = 1; // 16位波特率发生器 TXSTA1bits.BRGH = 1; // 高速模式 SPBRGH1 = 0x01; // 416 = 0x01A0 SPBRG1 = 0xA0; RCSTA1bits.SPEN = 1; // 使能串口 TXSTA1bits.TXEN = 1; // 使能发送 RCSTA1bits.CREN = 1; // 使能连续接收 }

416和理论值417差了接近1,实际波特率约9592,误差0.08%,远小于UART通信通常要求的2%误差门限。这个参数在数据手册的波特率表格里也可以直接查到,不过自己算一遍更放心。

3.2 ADS122U04IPWR的寄存器配置详解

ADS122U04IPWR的配置核心是四个寄存器,功能分别对应输入多路开关、PGA增益、数据速率与滤波方式、激励电流与参考电压设置。我按PT100三线制+比例式测量的方案做了一个典型的配置组合:

寄存器功能本次配置值(功能描述)
配置寄存器0输入多路选择选择AIN0-AIN1作为差分输入对
配置寄存器1PGA增益设置增益=4倍
配置寄存器2数据速率与滤波20SPS,增强50Hz工频抑制
配置寄存器3IDAC与参考内部参考使能,IDAC电流1mA,从IDAC1输出

写寄存器的命令帧按“写命令字+寄存器地址+数据字节”的格式发送,这个命令字的具体定义要对着最新版数据手册的操作章节来填。我封装了一个通用函数,开发时直接调用:

void ADS122U04_WriteReg(uint8_t reg_addr, uint8_t reg_data) { uint8_t cmd[3]; cmd[0] = ADS122U04_CMD_WREG; // 写寄存器命令字,按手册定义填写 cmd[1] = reg_addr; cmd[2] = reg_data; UART1_SendBlock(cmd, 3); __delay_ms(1); // 给ADC留出处理时间 }

数据速率选20SPS是我刻意为之的。ADS122U04IPWR内部数字滤波器在20SPS附近对50Hz工频有很强的陷波衰减,这对直接现场供电的设备来说等于免费送了一层抗混叠保护。如果采样率选成1000SPS,噪声会明显变大,后续软件滤波的压力也就上来了。

3.3 转换数据读取与软件滤波策略

转换完成后,PIC18收到DRDY中断,在主循环里发读取命令把24位转换结果取回来。ADS122U04IPWR输出的是二进制补码格式的24位有符号数,满量程对应±VREF/Gain。

int32_t ADS122U04_ReadData(void) { uint8_t buf[3]; UART1_SendByte(ADS122U04_CMD_RDATA); // 读取数据命令字,按手册定义 UART1_ReceiveBlock(buf, 3); int32_t raw = ((int32_t)buf[0] << 16) | ((int32_t)buf[1] << 8) | buf[2]; if (raw & 0x800000) { raw |= 0xFF000000; // 符号位扩展,转成32位有符号数 } return raw; }

软件滤波我用的是递推平均滤波,队列长度16,每采到一个新值就抛掉最旧的,对16个值求平均。这个长度在20SPS下对应0.8秒的时间常数,既能压掉随机噪声,又不会让温度响应显得太迟钝。在干扰特别强的工况下,还可以叠加一个限幅滤波,把相邻两次采样偏差超过5°C的突变值直接剔除,防止变频器启停瞬间的尖峰干扰把滤波队列污染掉。

3.4 温度计算:RTD线性化与热电偶冷端补偿

从ADC码值到电阻值,再到真实温度,这个数学过程最容易被低估。ADS122U04IPWR输出的是电压比例,先按下面公式换算成PT100电阻:

float RTD_Resistance(int32_t adc_code, float vref_mv, float pga_gain, float iexc_ma) { // 码值满量程为 2^23(24位有符号) float vin_mv = ((float)adc_code / 8388608.0f) * vref_mv / pga_gain; return vin_mv / iexc_ma; // 单位:欧姆 }

拿到电阻值之后,用IEC 60751标准里的Callendar-Van Dusen公式做线性化。0°C以上用两阶多项式:Rt = R0 × (1 + A×t + B×t²),其中A=3.9083×10⁻³,B=-5.775×10⁻⁷;0°C以下需要追加一个C系数修正项:Rt = R0 × [1 + A×t + B×t² + C×(t-100)×t³],C=-4.183×10⁻¹²。在实际固件里,直接把电阻值代入反函数的迭代算法(牛顿法迭代求解t)会非常方便,收敛三次就能达到0.01°C级别精度。

热电偶的处理完全是另一条路。K型热电偶输出大约41µV/°C,ADS122U04IPWR在PGA=128增益下分辨率足够,但热电偶必须做冷端补偿。我的做法是把接线端子处的环境温度用ADC内部温度传感器读出来,然后在热电偶的NIST多项式计算结果上加上冷端温度。实测下来,用ADC内部传感器做冷端补偿会带来±1°C左右的误差,因为芯片自身发热会让内部温度传感器读数比接线端子实际温度高一点。对精度要求高的场合,更推荐在端子排附近贴一颗NTC,把冷端温度单独标定。

4. 调试实录与常见问题排查

4.1 底噪偏大:采样率与滤波器选型的连锁反应

第一次上电调试热电偶通道时,PGA=128增益下我看到的输出码值在±15个码左右跳,折合温度约±1°C,这个结果完全没法用。排查过程分了几步:先短接ADC输入端确认噪声源不在后端,然后检查电源纹波,最后发现问题根本出在采样率上。当时调试时把数据速率暂设为1000SPS,看到读数更新快很爽,但Δ-ΣADC的内置数字滤波器在高速率下对带外噪声的抑制明显变弱。把采样率降到20SPS之后,同样的前端条件下底噪立刻压到了±2个码以内。所以遇到声称ADC噪声大的问题,先看一眼采样率是不是远高于实际需求。

4.2 UART通信间歇性乱码:波特率误差与振荡器漂移

调试中期出现过一个很诡异的现象:模块冷启动后通信正常,运行半小时后开始间歇性读到0x00或0xFF这样的异常字节。用示波器抓UART波形发现,停止位的边沿明显偏移,这是典型的波特率失配。原因是我最初图省事用了PIC18LF45K80的内部振荡器,虽然出厂校准过,但芯片温度从室温升到70°C左右时,内部振荡器频率漂了将近1.5%,累积起来就超过了UART的容错门限。

解决方法是两个:一是把通信速率降回9600,波特率越低,相同频率误差下积累的位偏移越小;二是改用外部16MHz晶振,并配合OSCTUNE寄存器做精细校准。从那以后,模块在高低温箱里往返跑了几轮,再没有出现过通信字节错位的问题。这个教训对任何UART通信的设计都适用——长周期运行的设备,振荡器温漂是一个必须提前考虑的工程问题,而不是理论问题。

4.3 零点读数和温漂:参考电阻的隐藏影响

还有一次调试RTD通道时,0°C环境下读数一直在0.4°C附近来回摆,怎么校准都下不去。排查到最后,问题出在比例式测量的参考电阻上。那块参考电阻用的是普通贴片电阻,温度系数大约±100ppm/°C,虽然不想金属箔电阻那么夸张,但在板子局部温升十几度的情况下,阻值变化已经把参考电压拉偏了。换上25ppm/°C的精密电阻后,零点读数稳定到了0.05°C以内,彻底解决了这个漂移问题。

这件事给我提了个醒:比例式测量虽然说激励电流漂移不影响精度,但参考电阻的温度稳定性是绕不开的瓶颈。省什么都不能省参考电阻的钱。

4.4 热电偶冷端补偿误差的现场修正

在第一版固件里,冷端温度用的是ADS122U04IPWR内部温度传感器,但实际测试发现,ADC芯片和接线端子在机箱里的热梯度很明显。芯片附近温度比端子排高出2°C以上,直接把内部温度值当冷端温度用,测温结果就偏低了大约2°C。解决办法是在接线端子排下方加了一颗10kΩ NTC,用MCU的ADC独立采集端子温度,再把冷端温度值通过参数结构体传给热电偶计算函数。这个改动既不增加多少成本,又能把冷端补偿误差修正到±0.3°C以内。

4.5 常见问题速查表

故障现象可能原因排查与解决
读数跳变、±10码以上波动PGA增益下噪声过大降低采样率到20SPS,检查电源去耦电容
UART乱码或通信超时振荡器温漂/波特率失配换外部晶振,降低波特率,校准OSCTUNE
温度读数整体偏高或偏低参考电阻温漂换低温漂精密电阻,重新标定
热电偶读数反向移动热电偶极性接反核对红(正)蓝(负)引线,建议加极性保护
读数长时间不变DRDY中断丢失或UART阻塞检查MCU中断配置,增大UART接收缓冲区
上电偶发0°C以下跳变上电瞬间激励电流未稳定上电后延时200ms再启动转换

5. 从Demo到量产:必须要补的功课

5.1 接口保护与EMC设计

实验室里跑通的板子和能装进现场设备的板子还有一段距离。最重要的差距在接口保护上。传感器线缆是暴露在工业环境里的,雷击感应、电机启动浪涌都可能顺着线缆灌进ADC引脚。给每一路模拟输入端加上ESD保护二极管、串联1kΩ限流电阻、并联到地的100nF电容,这是最基本的防护组合。UART的对外通信线在延伸出板外的时候,也必须加TVS管,否则板级TTL电平在长线缆上就是一根天线。

ADS122U04IPWR的数据手册里还专门提到了输入引脚的保护结构,但芯片内部的保护能力有限,来自外部的浪涌能量最终还是要靠板级防护器件吸收。这一点上不能因为追求省料而省略。

5.2 产线标定与校准策略

即使元器件选得再精,批量生产也逃不过逐台标定这一关。我的做法是每个模块出厂前做两点校准:0°C基准点(用冰点槽或精密电阻箱模拟)和100°C基准点(用精密电阻箱设置PT100对应的138.51Ω),把每个通道的增益误差和偏移量写进PIC18LF45K80的EEPROM里。运行时的温度计算会在拿到电阻值之后做一次两点线性修正,这个流程能把批量模块之间的个体差异压到±0.1°C以内。

校准数据建议按通道独立存储,并且加一个简单的校验和。我做产测时遇到过EEPROM写入中断导致校准参数损坏、模块输出完全走样的案例,加了校验和并在上电时做合法性检查之后,这类返修基本消失了。

5.3 运行状态上报与故障预判

量产版本还有一个经验值得分享:不要只上报温度值,要让模块周期性上报自检状态。比如参考电压是否正常、激励电流是否存在、ADC是否持续输出有效码值、UART是否长时间没有收到上位机指令。这些状态位用两个字节的组织方式挂在Modbus寄存器里,上位机周期读取。传感器断线这种最常见的故障,在现场往往表现为读数为巨大负值或者满量程,如果提前在固件里做诊断,直接上报“传感器故障”而不是一个离谱的温度数字,对现场维护人员友好得多。

最后聊几句实际感受

这套方案做完之后,我最大的体会是:精密测温的项目,真正决定成败的往往不是ADC的分辨率参数,而是系统层面的细节选择。UART接口让ADC能离传感器更近、离干扰更远;比例式测量把激励电流漂移这个通常很头痛的问题化解于无形;PIC18LF45K80的工业级可靠性和CAN接口又让后续接入现场总线变得顺理成章。回头再看,ADS122U04IPWR这颗芯片不是参数上最顶尖的,但它的接口形态恰好解决了工业分布式测温里最难缠的通信问题。如果你也在做类似的风管测温、水管测温、机组状态监测这类项目,这套方案里的硬件骨架、寄存器配置和调试思路都可以直接拿过去参考,希望这篇记录能帮你少走我走过的那些弯路。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询