ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

基于ADS122U04与PIC18的PT100和热电偶高精度温度采集方案

基于ADS122U04与PIC18的PT100和热电偶高精度温度采集方案

做工业温度采集的工程师,多少都会遇到这样的项目:要用 PT100 或者热电偶把温度测准,同时又不能把系统搞得太贵、太复杂。最近我在做一个 HVAC 控制器换代项目,要求把原来的 NTC 加单片机内部 ADC 方案,整体升级成支持 PT100 三线制和 K 型热电偶的高精度采集,现场探头和主控板之间还有两三米的线缆距离。选型折腾了几轮之后,定下来的组合是 TI 的 24 位 Δ-Σ ADC ADS122U04IPWR,配合 Microchip 的 PIC18LF45K40 做主控。这套方案最有意思的地方在于,ADS122U04 没有用常见的 SPI 或 I2C 接口,而是用 UART 和主机通信,放在 HVAC 这种面板与主控分离的产品结构里,天然比 SPI 耐长线、抗干扰,后续想升级成 RS-485 多机网络也很顺手。这篇就围绕这个组合,把选型逻辑、硬件接法、驱动思路、校准流程和现场排障一次讲透,给正在做类似温度变送器或采集模块的朋友做个参考。

1. 选型:为什么是 ADS122U04IPWR 配 PIC18LF45K40

1.1 一颗自带 UART 的 24 位 ADC,解决长距离采样难题

先说 ADC 选型。ADS122U04IPWR 是 TI ADS122U0x 系列里的四通道、24 位 Δ-Σ ADC,同系列还有 I2C 版本的 ADS122C04,两者内部模拟前端基本一致,区别就在数字接口。这颗芯片集成了输入多路复用器、可编程增益放大器 PGA、两个激励电流源(IDAC)、内部温度传感器,以及一个真正意义上的 UART 从机接口。为什么强调“真正意义上的 UART”?因为很多 ADC 所谓的串行接口其实是 SPI,虽然也能靠软件模拟,但 SPI 信号线上没有明确定义的起始位和停止位,对时序要求苛刻,线拉长到几十厘米以上就容易出问题。ADS122U04 直接支持 UART 协议、从机地址匹配和多从机级联,这意味着采集板和主控板之间可以走普通的两根信号线,距离拉到两米、五米,甚至通过电平转换芯片接入 RS-485 总线,都不需要额外做协议转换。HVAC 项目里传感器探头经常要装到风管、冷冻水管、机房角落这些离控制器很远的位置,光这一点就值得换掉 SPI ADC。

1.2 PIC18LF45K40 做主控:工业级、低功耗、外设刚好够用

主控选 PIC18LF45K40 的原因简单直接:成本低、供货稳、工业级温度范围,外设数量对我们这个产品来说刚好够用,不用为了一个温度采集模块去上一颗带浮点单元的 ARM 或者 DSP。PIC18(L)F45K40 属于 Microchip 的 8 位增强型内核系列,后缀里的 LF 意味着额定工作电压可以到 1.8V~3.6V,适合两线制变送器或电池供电场景。它内部有 32KB Flash、2048 字节 RAM,对于 RTD 线性化查表、热电偶分度表存储来说不算宽裕,但规划好完全够用。更重要的是它有两路 EUSART,一路专门给 ADS122U04 通信,另一路可以接 RS-485 收发器或者调试串口,互不想干扰。再加上内部的 64MHz 振荡器、硬件 CRC、窗口看门狗这些外设,外围电路可以做得非常精简,PCB 面积比用一颗 STM32 小不少。这个项目的核心是“测量温度并把数据交出去”,不是跑复杂的控制算法,8 位 MCU 反而是最合适的。

1.3 和常见方案的差距:SPI 采集、模拟运放、热电阻变送模块怎么比

对比一个典型的传统方案:运放放大 PT100 信号,接一颗 16 位 SAR ADC,再用单片机做换算。这个思路不是不行,问题是器件多、温漂大、校准麻烦。运放的失调电压和温漂会直接叠加到传感器信号上,16 位 SAR ADC 对电源噪声也很敏感,实测下来要把系统精度做到 ±0.2°C 以内,调试成本非常高。另一种做法是直接用现成的 RTD 变送模块,比如 4~20mA 输出的温度变送器,精度不错,但这类模块通常是固定传感器类型、固定量程,产品要同时支持 PT100 和 K 型热电偶就得挂两个模块,成本翻倍。ADS122U04 这种“多通道输入 + PGA + 激励电流 + UART”的四合一结构,恰好把传感器前端、放大、采样、数字传输全塞进一颗芯片里,外围只要配参考电阻、滤波电容和电源,主控端的代码也只负责协议和换算。这个集成度对一个多传感器输入的产品来说,省下的不只是 BOM,还有整个硬件调试周期。

2. 系统框架与硬件电路设计

整块板子的结构可以这样理解:PIC18LF45K40 是系统的大脑,负责启动配置、定时发起采样、读取数据、换算温度、对外通信;ADS122U04 是传感器信号的前端,负责把 PT100、热电偶这类微弱信号放大并转换成数字码;传感器接口分为两路,一路接三线制 PT100,另一路接 K 型热电偶。两块芯片之间用 UART 连接,中间不经过任何隔离器件,因为在这个原型阶段主控和 ADC 在同一块板上,距离只有几厘米。后续如果做分布式采集,再把 UART 信号接上 RS-485 收发器即可。

2.1 PT100 三线制比例式接法怎么搭

PT100 的测量精度很大程度上取决于接线方式。两线制虽然省线,但导线电阻会直接叠加到传感器阻抗上;四线制最准,可是工业现场和 HVAC 探头很少提供四根引线;三线制是工程上最常见的折中方案,前提是 ADC 要能提供两个匹配的恒流源来抵消引线电阻。ADS122U04 刚好有两个可编程 IDAC 电流源,可以配置成同样的电流,一个流经 RTD 和一根引线,另一个流经另一根引线作为补偿通道。参考电阻 RREF 接在 REFP0 和 REFN0 之间,IDAC 电流同时流经 RREF,ADC 最终输出的数字码是 RTD 电阻与 RREF 电阻的比值乘以固定系数。这种比例式测量的好处在于,激励电流的绝对值漂移、ADC 参考电压的缓慢变化都会被自动抵消,因为电流变化同时影响分子和分母。

具体接法上,我给几个建议值:IDAC 电流设置为 500µA 或 1mA,500µA 功耗低、自热小,适合长期测量;1mA 信噪比更高,但 PT100 上会有约 0.1°C 的自热,需要配合功耗要求权衡。RREF 选择精度 0.1%、温漂系数 25ppm/°C 以内的精密电阻,阻值取 430Ω 或 2.4kΩ 要看量程。测量 0°C~200°C 这段常用工业区间时,PT100 阻值范围是 100Ω 到约 175.8Ω,RREF 取 200Ω 到 430Ω 都可以让 ADC 输入信号落在 PGA 适合的范围内。输入引脚上各串一个 1kΩ 电阻、对地接一个 10nF 电容,组成差分低通滤波,能抑制现场的工频干扰和射频噪声,这个 RC 滤波的拐点大约在 16kHz,不会影响几十 Hz 的采样速率。

2.2 热电偶通道和冷端补偿电路

K 型热电偶的信号电平比 PT100 小得多,每度大约只有 41µV,所以 PGA 增益要放到 32 或 64,否则 24 位 ADC 的分辨率优势也无法体现出来。热电偶的正负极分别接入一个差分输入通道,比如 AIN2 和 AIN3,信号线上同样做 RC 滤波,电容值不要选太大,否则会有明显的建立时间问题。由于热电偶本身没有激励电流需求,这个通道可以把 IDAC 关掉,或者利用 IDAC 给冷端补偿用的 NTC 供电。冷端补偿是热电偶测量最容易被忽略的地方。K 型热电偶测到的是热端和冷端的温差,如果 ADC 板上的接线端子温度一直在变,又不做补偿,输出温度就会整体偏离。我建议优先用 ADS122U04 的内部温度传感器做冷端补偿,因为它直接读 ADC 的结温,不需要额外接 NTC,也不用再占一个模拟输入通道。前提是 ADC 芯片本身要尽量靠近热电偶端子,并远离发热器件。如果产品结构不允许,那就改用外部 NTC,贴在热电偶端子旁边,定期读取后做软件补偿,精度会比内部补偿更稳定,但电路上要多一路输入。

2.3 电源、参考与接口保护:现场稳定性的关键

ADS122U04 的 AVDD 和 DVDD 可以共用一个 3.3V LDO,但布局上必须分开走线:模拟电源先经过磁珠,再接一个 10µF 钽电容和一个 100nF 陶瓷电容;数字电源单独接滤波电容。PGA 对电源噪声很敏感,数字信号线不要从 ADC 的模拟输入走线下面穿过,这一点在 PCB Layout 时一定要卡住。如果产品会用到 RS-485 长线通信,UART 到主控之间虽然只有几厘米,但为了将来扩展到远距离,我会在连接器附近预留对地的 TVS 二极管和串在信号线上的 100Ω 电阻。ADC 的参考电压可以选择内部 2.048V 参考,也可以使用外部精密参考。我在原型里直接用外部参考电压输入,因为温度变送器可以允许每通道校准,而外部参考的一致性更好,后续批量生产时不用每片单独调。如果做单点校准就够的场景,内部参考更省事,这点要看产品的精度目标来定。

3. 软件协议与驱动实现

硬件调通只是第一步,真正花时间的是驱动软件。ADS122U04 的 UART 接口虽然好用,但也有一堆细节要处理:从机地址、波特率、寄存器读写命令、数据就绪状态,以及和 PIC18 的 EUSART 配合时的时序问题。下面把我在项目里整理的驱动逻辑拆开来写。

3.1 ADS122U04 的 UART 从机协议要点

ADS122U04 作为 UART 从机,需要主机给它发带地址的命令帧,从机收到匹配地址后才会响应。这意味着在初始化阶段,要先通过硬件引脚或配置设置一个从机地址,然后主机发送的所有命令都要包含这个地址字节。常见的操作命令包括写配置寄存器、读配置寄存器、启动转换、读取转换数据等。我的经验是,在上电后先做一次软件复位,等芯片稳定个几十毫秒,再依次写配置寄存器,但不要一口气把所有寄存器都写完,最好每写完一个就回读校验一次。UART 波特率设置要参考芯片手册的额定范围,并在 PIC 侧用同一个波特率;如果以后要挂多从机,从机地址要避免使用 0x00 这类容易产生歧义的地址。还有一个容易踩坑的点:ADS122U04 的数据输出是 24 位,读取时要把三个字节按顺序拼装成一个 int32_t,然后按二进制补码解释才能得到正确的 ADC 码。我见过有人把 24 位数据直接塞进 int16_t 里,结果负温度全变成乱码。

3.2 PIC18 侧 EUSART 驱动与命令封装

PIC18LF45K40 的 EUSART 配置相对直观:设置波特率发生器 BRG 的值、8 位数据、无校验、1 位停止位。由于我们要同时跑 ADC 通信和外部通信,建议把 ADC 用的 UART 放在中断接收模式,用环形缓冲区存收到的字节,主循环按状态机解析;发送命令时则用轮询方式,因为命令帧很短,阻塞几百微秒完全可接受。下面是一段简化的初始化示意,具体寄存器名和位定义以数据手册为准,但结构可以照搬:

void ads122u04_uart_init(void) { // PIC18LF45K40 EUSART1 初始化,波特率 115200 TX1STAbits.BRGH = 1; // 高速模式 BAUD1CONbits.BRG16 = 1; SPBRGH1 = (unsigned char)(BRG_VAL >> 8); SPBRGL1 = (unsigned char)(BRG_VAL & 0xFF); RC1STAbits.CREN = 1; // 使能接收 RC1STAbits.SPEN = 1; // 使能串口 PIR1bits.RC1IF = 0; PIE1bits.RC1IE = 1; // 使能接收中断 }

封装命令时,我习惯把“写单寄存器”和“读转换数据”做成独立函数,方便上层调用。写寄存器函数先组帧,再调用 UART 发送,发送完等待一小段字节间隔,保证命令完整送到从机;读数据函数则发送读命令后,等待数据就绪信号,再把三个字节取回。ADS122U04 有数据就绪引脚(DRDY),硬件上我把它接到了 PIC18 的 INT 引脚,这样主循环不需要一直轮询,数据一好就触发中断,再把读取流程交给主循环处理。这套结构跑下来,CPU 占用率很低,留出的时间足够做温度换算和通信协议。

3.3 数据线性化与温度换算的工程处理

拿到 ADC 码后,如何换成温度才是真正见功夫的地方。PT100 的电阻-温度关系可以查 IEC 60751 分度表,也可以用 Callendar-Van Dusen 方程做高精度计算。对于 8 位 MCU,我建议不要在主控上做复杂浮点多项式计算,而是把分度表压缩成查找表,配合线性插值。PT100 在 0°C 到 200°C 范围内的非线性不算严重,每隔 10°C 存一个点,插值误差远小于 0.1°C,Flash 占用也只有几十个字节。热电偶的电压-温度关系更复杂,K 型热电偶在 0°C 到 1000°C 范围内的曲线有明显弯曲,如果只做线性化,误差会有好几度。稳妥的做法是使用标准分度表,按 0.5mV 或 1°C 的间隔存储查找表,结合热电偶输出电压和冷端温度查表得到真实温度。PIC18 的乘法指令虽然不能一次完成 32 位乘法,但线性插值中的乘法用几个周期就能算完,整体速度完全够用。

4. 校准流程与精度优化

光有正确的硬件电路和软件驱动还不够,温度采样的精度最终要靠校准来兜底。温度传感器本身的离散性、RREF 电阻的误差、PGA 的零点偏移,这三项即使器件选得再好,也会让系统误差落在正负一两度甚至更大。校准的目的就是把这些固定误差消除掉,让系统进入 0.2°C 级别的精度区间。

4.1 两点校准怎么做才靠谱

最直接的校准方法是使用高精度恒温槽,把探头分别放入 0°C 冰点和 100°C 沸点,记录每个温度点对应的 ADC 原始码,然后计算增益和偏置系数。计算公式非常简单:设 T0 温度下的 ADC 码为 C0,T1 温度下的 ADC 码为 C1,那么实际温度 T 可以近似为:

T = T0 + (T1 - T0) * (C - C0) / (C1 - C0)

这个线性近似在 PT100 的 0°C 到 100°C 范围内误差很小,因为 RTD 曲线的非线性经过电路比例测量后已经被大幅压缩。但热电偶不能这么简单处理,因为它的输出电压随温度不是线性关系,校准后的换算还是要走查找表,只是需要修正冷端补偿的偏移量。如果实验室没有恒温槽,也可以用精密电阻箱代替传感器:在 ADC 输入端接一个电阻箱,把阻值调到 PT100 在 0°C 和 100°C 时的标称值,分别记录 ADC 码,效果和真实温度点校准一致,而且排除了探头自身误差,更稳定。完成两点校准后,建议在 50°C 附近加测一个中点,用来验证线性度。如果中点误差超过 0.1°C,就要检查 RREF 的温漂系数和传感器连接是否可靠了。

4.2 精度上不去,先查硬件还是先查软件

我的排查顺序永远是:先确认硬件参考,再怀疑软件算法。所谓硬件参考,第一是 RREF 电阻,它是比例式测量的基准,如果它本身偏差 0.5%,等效温度误差就可能接近 1°C;第二是输入滤波电容,电容漏电流会引起差分输入不对称,这个问题在老化板上最隐蔽;第三是热电偶的冷端补偿温度,内部温度传感器虽然方便,但芯片发热会带来额外的冷端误差,如果板子上有隔离电源或者 MCU 满载运行,结温可能比端子温度高好几度。硬件排查完,再回头检查软件:滤波算法是否真的生效、单次采样和均值采样的差异是否过大、查找表的数据是否按正确温度单位存储。还有一个高频问题:采样码值稳定但温度换算后整体偏高或偏低,这通常是校准系数里的 T0 或者 C0 取错了,比如冰水混合物没有充分搅拌导致实际温度不是 0°C。

5. 现场调试问题与排查速查表

这个项目从打板到现场试运行,大概花了两周时间,其中一半时间花在调试和排除各种环境因素上。说实话,芯片本身的驱动没有想象中难,难的是现场干扰和长线带来的模拟信号劣化,以及一些看起来像是硬件问题的软件配置错误。下面把实际踩过的几个坑和对应的排查方法整理成速查表,希望对大家有用。

5.1 我踩过的几个坑

第一个坑是 UART 命令的第二字节经常丢弃。原因是上电后 PIC18 的 EUSART 和 ADS122U04 的波特率还没有完全同步,芯片还没准备好就发了第一个命令。解决方法是上电后先延时 100ms,再发送一个复位命令,并等待从机返回确认字节,如果没收到确认就重试三次。

第二个坑是 PT100 探头线拉长后读数波动明显加大。现场探头线有两米多,虽然没有直接短路,但线缆本身变成了天线,把变频器的共模干扰带了进来。单纯增加输入 RC 滤波电容只能压住高频噪声,对工频干扰帮助不大。最终解决办法是在软件里把采样速率降到 20SPS,并开启 ADC 内置的 50Hz/60Hz 抑制滤波,波动一下从十几个 LSB 降到了两三个 LSB。

第三个坑是热电偶读数在室温附近反复漂移。最初用 ADC 内部温度传感器做冷端补偿,但测试时发现芯片温度比端子温度高了好几度,导致补偿量不准。后来把冷端补偿改成了外部 NTC,贴在热电偶端子旁边,每隔 500ms 读一次 NTC 做补偿源,问题就解决了。这个案例说明,选型时图省事用内部温度传感器没问题,但产品结构和发热设计必须配合,否则补偿精度反而更差。

5.2 故障现象速查表

故障现象可能原因排查方法
UART 完全无响应接线接反、从机地址不匹配、PIC 未使能串口示波器看 TX/RX 波形,先发 NOP 命令确认回包
第二字节偶尔丢失上电时序问题、波特率误差超过 2%延长上电延时,用晶振而非内部 RC 振荡器生成波特率
读数固定为全 1 或全 0传感器断线或短路、PGA 增益配置错误断开传感器量引脚电压,用电阻箱模拟传感器验证
读数波动大电源滤波不足、线缆干扰、采样速率过高检查电源纹波,降低采样速率,开启工频抑制
温度整体偏高/偏低RREF 阻值偏差、校准系数错误、IDAC 电流设置不对先量 RREF 实际阻值,再复查校准系数
热电偶温度漂移冷端补偿不准、端子温度受环境热影响换外部 NTC 做冷端补偿,并做热隔离
只有一路传感器读数正常,另一路乱跳通道复用配置错误、输入悬空检查 MUX 配置,未用输入通道要接偏置电阻

最后说一个我在项目里养成的小习惯:调试时把 ADC 原始码和换算后的温度同时通过调试串口打出来,固定格式一行一条。这样在判断问题是硬件还是软件时,一眼就能分清——原始码稳定但温度跳,是换算和校准的问题;原始码本身跳,才是模拟前端和干扰的问题。顺着这条线排查,很多看起来玄学的故障,最后会发现都只是某个寄存器位或者校准参数没设对。这个组合里,ADS122U04IPWR 加上 PIC18LF45K40 的代码量和外设开销都不大,真正拉开差距的,从来都是对这些细节的把握。

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进