ARTICLE · INTELLIGENCE

战地情报 · 详情页

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

基于ADS122U04与PIC24EP的高精度温度采集系统设计解析

基于ADS122U04与PIC24EP的高精度温度采集系统设计解析

不少搞工业测控和暖通空调(HVAC)项目的人,一听到“温度采集”,第一反应往往是“接个热电偶、读个 ADC、换算一下,完事”。但实际上真正把精度做到设备级,你会发现每一步都有坑。我最近做的这块温控板,需求很直接:支持多路热电偶和铂电阻输入,覆盖 -40℃ 到 85℃ 的工业环境,整机精度控制在 ±0.5℃ 以内,还要在强干扰、长走线的现场稳定跑。折腾一圈之后最终锁定了 ADS122U04IPWR 这颗带 UART 接口的 24 位 ADC,搭配 PIC24EP512GU814 这颗 16 位 MCU。整套组合做下来,通信链路简洁、精度余量够用,调试和量产都还算顺利。

这篇文章就把我整个项目的选型逻辑、硬件接线、固件框架和现场调试经验完整展开。凡是做工业传感器板、HVAC 控制器,或者在嵌入式里折腾过高精度温度采集的,应该都能从里面找到点参考价值。哪怕你之前没碰过这两颗芯片,看完也能摸清一个完整的温度采集链路该怎么设计和落地。

1. 整体设计与方案拆解:为什么偏偏是这两颗芯片

1.1 先把需求定死:精度、通道、通信距离

项目起步阶段,我先没急着选型,而是把测温需求一条条列了出来,这些参数决定了后面的所有技术路线。

第一是精度。热电偶信号本身就弱,K 型热电偶的灵敏度大约 41μV/℃,也就是说要分辨 0.5℃ 就得能测到 20μV 左右的电压变化。如果用单片机内置 12 位 ADC,参考电压 2.048V 时一个 LSB 就是 1mV,换算成温度直接误差超过 12℃,这显然不可能达标。所以外置高分辨率 ADC 是必然选项,而且还得带可编程增益放大器(PGA),先把热电偶的微弱信号放大到 ADC 量程范围内。

第二是通道数量。板上要支持至少 6 到 8 路温度输入,覆盖冷冻水进出、风管温度、室外环境温度等多个测点。每路如果都塞一个独立 ADC,成本直接爆表,我更倾向于一颗 ADC 加输入多路复用器,轮流扫描各路传感器。

第三是传感器种类。工业现场既有热电偶,也有三线制铂电阻(Pt100/Pt1000),两种传感器原理不同,ADC 最好能同时支持高增益差分输入和恒流激励。

第四是通信距离。传感器信号不能指望 MCU 离得很近,ADC 和 MCU 之间会有几十厘米甚至一两米的走线。如果用 SPI,至少 4 根线(SCLK、MOSI、MISO、CS),在长走线下时钟容易受干扰,而且每个 ADC 都要单独占用 CS 引脚。I2C 虽然线少,但速度受限,地址冲突也是个麻烦。看到 ADS122U04IPWR 支持 UART 通信的时候,我几乎没怎么犹豫,两根线搞定,抗干扰也好做。

1.2 ADS122U04IPWR:UART ADC 到底香在哪

ADS122U04IPWR 是 TI 的 24 位 Δ-Σ 型 ADC,核心分辨率和 ADS1220 属于同一代产品,但接口换成了 UART。这在当时选型时确实是个加分项,因为传统精密 ADC 清一色是 SPI 接口,SPI 在低速高精度场景下没什么问题,但遇到“ADC 和 MCU 分板设计”的架构时,UART 的布线简洁优势就体现出来了。

除了接口,这颗芯片的模拟前端也相当齐全。内部带了可编程增益放大器,增益从 1 倍到 128 倍可选,热电偶那点毫伏级信号完全可以靠内部 PGA 做放大,不用外扩仪表放大器。两个独立激励电流源(IDAC)可以配置 10μA 到 1500μA 的电流输出,专给铂电阻温度检测设计的,测 Pt100 或者 Pt1000 都不需要额外加恒流源电路。芯片内部还有一个温度传感器,用来做热电偶冷端补偿,省掉了一颗外置的 NTC 或者数字温度传感器。

更关键的是内部电压基准,2.048V 的基准电压温漂做到了很低,工业温度范围内整体漂移可控。外部基准输入引脚也留了,做 RTD 比率测量时可以绕开内部基准,从而消除激励电流源温漂带来的误差,这个细节后面固件部分再细说。

ADS122U04IPWR 型号里的“U”就是 UART 接口的标识,“IPWR”后缀代表 TSSOP 封装,工业温度等级。TSSOP 这块很小巧,PCB 布局上不占地方,适合做紧凑的工业变送板或者温控板。

1.3 PIC24EP512GU814:主控为什么不用 STM32 或国产 ARM

主控选择上,我特意避开了热门的 ARM 系列,选了 Microchip 的 PIC24EP512GU814。不是说 ARM 不行,而是在这个项目里 PIC24 有几个很实际的优点。

这颗 MCU 属于 PIC24EP 系列的高端型号,512KB 闪存、64KB RAM,对温度采集这种任务来说绰绰有余。它有两个独立的 UART 模块,一个用来和 ADS122U04 通信,另一个专门做 RS485/Modbus 和上位机联动,互不干扰。PIC24EP 的抗干扰和电源管理做得比较老道,3.3V 供电模式下功耗控制很灵活,现场长期 7×24 小时跑也不会漂。

还有一点是采购供应链的考虑。这款 MCU 在暖通、楼宇自控和工业仪表行业里用量不算小,属于长期供货型号,生命周期文档齐全,Microchip 的生态工具链(MPLAB X + XC16)也稳定,至少不会出现“芯片换版导致固件推倒重来”的幺蛾子。

1.4 系统拓扑与通信链路

最终的系统结构是这样的:

外部传感器(热电偶/三线制铂电阻)接入 ADS122U04 的模拟输入通道,ADS122U04 通过 UART 把转换好的数字量发给 PIC24EP512GU814,主控收到数据后做线性化、冷端补偿、滤波和量程换算,最后再通过另一路 UART 转 RS485,走 Modbus 协议把温度值送到上位机或者 HVAC 集中控制器。

这种两级结构的最大好处是模拟信号处理的边界非常清晰。传感器、ADC 和主控之间只走数字信号,模拟前端被限制在 ADC 内部和输入滤波电路上,这样即使现场出现电机启停、变频器开关引起的电磁干扰,也很难通过长距离的传感器线路直接干扰主控。

2. 硬件电路设计:热电偶和铂电阻的接入细节

2.1 热电偶接入:差分输入阶段必须保持高阻抗

热电偶输出的是毫伏级微弱直流电压,内阻很小但引线可能很长。我用的是 K 型热电偶,电压范围 -6mV 到 +55mV(对应 -200℃ 到 1300℃ 左右)。接线的时候,我把热电偶的正负极分别接到 ADS122U04 的 AIN0 和 AIN1 两个通道,以差分方式输入。

差分方式和单端输入最本质的区别是,差分输入将两线之间的噪声视为共模信号,靠 ADC 的共模抑制比减去。ADS122U04 在低频下共模抑制比很高,这对于长线缆拖出来的工频共模干扰特别有用。

ADC 输入引脚内部有高输入阻抗缓冲,但外部不能掉以轻心。我在 AIN0 和 AIN1 之间并联了一个 1nF 的差模电容,然后再在两线对地各并一个 10nF 电容,组成 π 型滤波。这个容值的选取是我实际测试后确定的:太大(比如 100nF)会明显增加 ADC 输入端的建立时间,导致每次通道切换后需要等更久才能读数;太小(比如 100pF)对射频干扰的抑制又不够,现场高频噪声会耦合进来,造成数据在个位 LSB 之间反复跳动。

2.2 铂电阻接入:三线制配合 IDAC 电流源

铂电阻的测量比热电偶多一个环节,就是需要给传感器提供一个稳定激励电流,然后测铂电阻两端压降。我选了 Pt1000 作为风管测温用的传感器,0℃ 时电阻 1000Ω,灵敏度大约 0.385Ω/℃,激励电流如果取 250μA,那么在 0℃ 时输出压降只有 0.25V,多路复用扫描时这个信号水平很好处理。

三线制接法是这样的:IDAC1 从 ADC 的 AIN3 引脚输出恒流,经过导线 1 流到铂电阻一端;铂电阻另一端引两条线,一条接回 ADC 的 AINN(输入负端),一条接到公共地或者低侧基准。这样做的目的是消除导线电阻误差,两条回流线上的电流是相等的,压降也会相互抵消,最终 ADC 测到的差分电压只和铂电阻本体阻值相关。

电流源选择上有讲究。IDAC 太小,比如 10μA,虽然自身功耗低,但铂电阻上的压降只有 10mV 量级,这时导线接触电阻和热电势噪声都会变得相对显著。IDAC 太大,比如 1mA,铂电阻自身发热会比较明显,自热误差会直接影响测温结果。综合功耗、分辨率和自热三者,我在 Pt1000 上用了 250μA,在 Pt100 上用了 500μA,这是工程上比较稳妥的中间档。

还需要留意的是,两个 IDAC 电流源虽然名字一样,但可以分别配置电流大小,也可以分别指定路由到任意模拟输入引脚。这个灵活性在调试时很省事,比如临时调整通道顺序,只需要改寄存器位,不用改 PCB。

2.3 电源分配和 PCB 布局经验

整个板子的电源是统一的 3.3V 供给 PIC24EP512GU814 和 ADS122U04IPWR,模拟部分和数字部分共用一路 LDO 输出,但 PCB 布局上做了分割。

这里有个关键经验:ADS122U04 的模拟电源 AVDD 和数字电源 DVDD 虽然可以短接,但滤波一定要分开。我用了一个磁珠把 AVDD 和 DVDD 隔离,AVDD 处放 1μF 陶瓷电容和 0.1μF 高频电容并联。DVDD 相对可以粗糙点,但也要保持足够的去耦电容靠近引脚。

ADC 的参考电压是比率测量的核心。对于热电偶,我用的是芯片内部 2.048V 基准;对于铂电阻,我把外部参考电阻 RREF 接在 VREF 和 VREFN 引脚之间,IDAC 电流流经 RREF,产生一个和激励电流完全同步变化的参考电压。这样当 IDAC 电流随温度漂移时,信号电压和参考电压等比例变化,测量结果不变。这就是比率测量的精髓,也是工业设备能把精度做稳的基础。

PCB 走线方面,模拟输入线和参考电压走线一定要远离 MCU 的晶振引脚、UART 线和电源开关节点。我在实际板子上吃过亏,一开始晶振靠近模拟输入走线,导致 ADC 输出数据里出现了和晶振频率相关的尖刺噪声,后来把晶振移到板边、模拟输入走内层并用地包围,问题才消失。

2.4 保护电路:输入浪涌和反接

工业现场有一个没法回避的问题,就是传感器线缆可能被接错、被雷击感应或者被大功率设备干扰。我在每路模拟输入端都加了一对反并联二极管到电源轨,配合一个 100Ω 的输入串联电阻做限流。正常工作时,二极管不导通,不影响测量;一旦外部出现过压或接错线,二极管会把电压钳位到安全范围,串联电阻限制住流过芯片的电流。

我也碰到过一些设计,输入端只加了一颗共模电感就上板,结果现场一打雷或者大电机一启动,ADC 就死机。保护电路看似不起眼,但在长线缆的暖通空调项目里是必须有的保命设计。

3. 固件实现:从初始化到最后输出温度

3.1 通信接口初始化和底层读写

固件我用的 Microchip 官方 XC16 编译器,C 语言开发。第一步是初始化 UART1,用来和 ADS122U04 通信。ADS122U04 的 UART 底层只支持最高 115200 波特率,当年在设计时我稳妥起见过用了 9600 波特率,长线缆 1 米多一点时通信依然可靠。

波特率选低的另一个原因是,ADC 数据本身输出速率只有每秒 20 次,9600 波特率完全够用,不会成为瓶颈。而低速 UART 对布线寄生电容不敏感,现场哪怕线缆质量差一点也能正常收发。

ADS122U04 的协议是标准 UART 帧格式,8 位数据、无校验、1 个停止位。主机发送命令字节,从机根据命令返回对应数据。核心命令包括:写入寄存器(WREG)、读取寄存器(RREG)、启动转换(START)、读取转换结果(RDATA)。

我封装了一个底层函数,专门处理单字节收发和超时判断。这里尤其要注意超时处理,一旦 ADC 没有响应,绝不能死等,否则整个 MCU 会卡死。我设了 10ms 超时,超时后把通信错误标志位置位,主循环里会自动重新复位 ADC 并重新初始化。

3.2 ADS122U04 寄存器配置逐条讲解

ADS122U04 一共有 7 个配置寄存器(寄存器 0 到 寄存器 6)。上电后我首先执行一次 RESET 命令,让器件回到默认状态,然后逐条写入配置。

寄存器 0 是输入多路复用器配置,选择哪两个引脚构成差分输入对。我把它配成 AIN0/AIN1 作为热电偶输入,AIN2/AIN3 作为铂电阻输入。

寄存器 1 是 PGA 增益和单双极性配置。热电偶我用单极性模式、增益 32 倍,因为 K 型热电偶满量程电压大约 55mV,2.048V 参考电压除以 32 倍增益后,满量程范围是 ±64mV,正好可以覆盖热电偶的量程又不浪费 ADC 动态范围。铂电阻增益设成 2 倍,因为 250μA 激励下 Pt1000 在 100℃ 时压降大约 0.347V,2 倍增益后信号幅度接近但不超过量程。

寄存器 2 是数据速率和滤波器模式。我选了 20SPS,这是工频抑制最稳的档位。20SPS 的含义是 ADC 内部数字滤波器对 50Hz 和 60Hz 的工频干扰有阶跃衰减,现场不用额外加硬件陷阱滤波。代价是转换速率慢,但温度本身是慢变量,1 秒能扫完 6 路传感器,完全没问题。

寄存器 3 是参考电压选择和转换模式。热电偶通道用内部 2.048V 基准,铂电阻通道则要改成外部基准,因为我们在 VREF 引脚上接了 RREF 电阻,采用比率测量方式。转换模式我用的连续转换,配合 ADC 的 DRDY(数据就绪)信号引脚。

寄存器 4 专门配置激励电流源。我在这里打开 IDAC1,电流设为 250μA,并指定它流出到 AIN3 引脚,这样铂电阻回路就被激活了。热电偶通道不需要激励电流,所以不配置第二个 IDAC。

寄存器 5 和寄存器 6 主要涉及报警比较器、低侧开关等,我这个项目暂未使用,保持默认值。

3.3 数据读取状态机:DRDY 信号配合 UART

ADS122U04 有一个硬件引脚 DRDY,转换完成后会拉低,表示可以读取数据了。我把 DRDY 接到 PIC24 的一个普通 IO 口,用轮询方式检测。

读取流程是:主循环里判断 DRDY 是否为低,为低然后发送 RDATA 命令,接收 3 个字节,这就是 24 位 ADC 转换结果。三个字节拼接成一个 int32 类型数据,之后根据配置的极性做符号扩展。

关键细节是,DRDY 拉低之后数据在内部 FIFO 里只保存一小段时间,如果 MCU 响应不及时,数据可能被新转换结果覆盖。所以我不用中断嵌套,直接在主循环里优先处理 DRDY。实测下来,9600 波特率下读完整帧需要约 3ms,而 20SPS 下数据间隔是 50ms,时间余量非常充足。

3.4 电压换算和温度线性化

ADC 拿到的原始数是无符号或者有符号二进制补码,要换算成实际电压,公式如下:

[ V_{in} = \frac{Code}{2^{23}-1} \times \frac{V_{REF}}{GAIN} ]

例如热电偶通道,Code 是 ADC 原始读数,VREF 取 2.048V,GAIN 是 32,就能得到热电偶的实际热电势毫伏值。得到热电势之后,还不能直接当温度,因为热电偶是非线性输出,必须查分度表或者用多项式拟合。

我的做法是把 K 型热电偶的 -200℃ 到 1300℃ 量程分成 10℃ 一个节点,把每个节点的电压值做成常量表,然后做线性插值。这种查表插值法比纯多项式拟合更稳,在现场不同温度段都能保持精度。

铂电阻的换算稍微不一样。因为用的是比率测量,ADC 读数直接代表铂电阻阻值和参考电阻的比值,不需要关心 VREF 具体是多少伏。我先把 ADC 读数换算成电阻值,然后用 Callendar-Van Dusen 方程把电阻值反算成温度,这个方程在 0 到 850℃ 范围内精度很高,HVAC 场景完全够用。

4. 工业与 HVAC 现场实战:精度优化、校准与稳定性

4.1 工频干扰和数字滤波双重抑制

ADS122U04 的数据速率选 20SPS 后,芯片自带滤波器对 50Hz 和 60Hz 干扰能产生陷波效果。但在实际配电柜附近,电机启停引起的电磁干扰波形可能不是纯净正弦波,而是带大量谐波的尖峰。所以我还在软件层加了一级简单的滑动平均滤波,对采样序列每 4 次取一次平均值,既不会像中值滤波那样在温度变化时明显滞后,又能把随机噪声再压掉一半。

这里提醒一点:不要盲目做长窗口平均。温度变化虽然有惯性,但如果平均值窗口太长,比如取 32 次(将近 1.6 秒),在暖通系统的排水温度控制中就会明显滞后,调节器反应过来时实际温度已经超调了。我最终调在 4 到 8 次之间,温度响应速度和噪声抑制达到平衡。

4.2 现场校准流程:两点校准和偏移修正

再好的 ADC 芯片,装到 PCB 上以后都会因为焊接应力、PCB 热阻、装配公差等因素产生微小偏移。所以量产之前必须做整机校准,而不是依赖芯片出厂精度。

我的校准流程分两步。第一步是零点校准:把热电偶探头放进冰水混合物(0℃),读取 ADC 的原始电压,记为偏移量。第二步是斜率校准:把探头放进 100℃ 沸水或者恒温槽中,读取实际电压,计算实际增益和理论增益的偏差。最终软件换算时乘上校准系数并减去偏移量。

对于铂电阻通道,校准要分两个温度点,一般用 0℃ 和 100℃ 恒温槽做两点阻值校准。校准得到的系数会存到 PIC24 的 Flash 高位地址中,每台设备出厂时单独写入。这一套流程虽然增加了产线工时,但换来了 ±0.2℃ 以内的最终精度,这在大批量设备中是很有价值的。

4.3 长期运行稳定性测试

我做完样机后,把它放进恒温箱,设定 85℃ 连续跑了 72 小时。整个过程中监测数据发现,冷端补偿通道的温度读数会随板温升高而变化,但热电偶测量通道的数据相对稳定,最大漂移不超过 ±0.3℃。这说明内部温度传感器用于冷端补偿是有效的,而且内部基准电压的温漂控制得不错。

另外一个注意点是,长时间运行后 ADC 芯片自身温度会略高于环境温度,如果冷端补偿直接读芯片内部温度,会带来一点固定偏差。解决方法是把 ADC 贴放在 PCB 边缘,远离 MCU 和大功率电源器件,让芯片温度尽量接近热电偶接线端子温度,或者干脆把热电偶端子贴到芯片附近,让冷端和芯片处于同一等温体。

5. 调试中发现的问题与排查方法

5.1 UART 通信不稳定,读回来的数据全 0xFF

这个坑几乎每个用 UART ADC 的人都会踩一次。排查思路从硬到软。先用示波器看 MCU TX 引脚波形,确认波特率是否正确。我遇到过一次配置文件把 U1BRG 算错导致波特率偏了 20%,ADC 那边识别失败,返回的全是 0xFF。UART 的波特率误差要在 ±2% 以内,否则长数据帧就会丢字节。

还有一个容易忽视的细节是接地。ADC 和 MCU 虽然是同一块板供电,但长线缆连接时地电位可能存在压差,必须保证 UART 两端共地。如果信号线走得很远,建议在 UART 两端加个小共模磁环。

5.2 热电偶温度跳变,单个 LSB 抖动许多

数据出现随机跳变时,我首先怀疑的是模拟输入滤波电容失效或者虚焊。后来发现是 Python 环境里用了劣质的 USB 电源适配器,现场板子和调试电脑共用一个电源排插,适配器的高频开关噪声直接通过地线耦合进了 ADC。把调试电脑改用电池供电或者加隔离 USB 之后,数据立刻恢复正常。

这说明实验室调试时的“电源洁净度”和现场环境相差甚远。以后调试高精度 ADC 系统时,模拟前端的供电滤波和参考电压稳定性要放到第一优先级,而不是一上来就调算法。

5.3 铂电阻读数整体偏高

铂电阻读数偏高,最常见原因是接线端子接触电阻或者导线电阻没有被完全消除。三线制只对等长、同材质的导线有效,如果二线制的回流线比信号线长,或者接线端子老化,就会引入额外电阻。

我处理这个问题的方法是软件补偿:在产线校准时专门记录短接端子测试的阻值偏移,把这个偏移量作为一个校准参数存入 Flash。硬件上则要求线缆供应商提供三线等长的成品探头线,并在接线端子选型时选用低接触电阻的弹簧端子,而不是普通螺丝端子。

5.4 调试经验速查表

现象可能原因排查方法
UART 无响应波特率配置错误、TX/RX 接反、未共地示波器看波形,确认电平,核对 BRG 寄存器
温度数据抖个不停模拟供电噪声大、滤波电容缺失检查 AVDD 去耦,加设软件平均
热电偶冷端补偿不准芯片温度不等于冷端温度调整 PCB 布局,让冷端和 ADC 同温
铂电阻读数偏高线电阻未完全消除检查三线制接线质量,做短路零位校准
数据出现周期性尖刺数字干扰耦合进模拟走线加屏蔽地,分隔数字和模拟走线
上电后读不到正确寄存器复位时序不足上电后延时 100ms,再发送 RESET

个人经验里最值得说的一点是,调试高精度温度系统,手上一定要有能稳定输出 0.1℃ 分辨率的恒温槽,而不是只靠沸水和冰水混合物。沸水在不同海拔下温度差异很大,冰水混合物也容易受到环境温度干扰,这都会导致校准本身引入误差。

另外多提一句,这套方案后续想扩展通道数,不需要换主控,ADS122U04 支持多片级联,每片通过不同的地址在 UART 总线上区分,PIC24EP512GU814 的 UART 资源足够挂载多片 ADC。如果现场还想同时采集压力或者湿度模拟量,这颗 ADC 的多路复用和 PGA 配置也能应对,只需在寄存器配置里增加对应通道即可。

RELATED READING

延伸阅读

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