工程上打温度点,很多时候不是“读个ADC”那么简单,而是要把微伏级的信号、工频干扰、传感器非线性和现场通信统统处理好。这个项目用 TI 的 ADS122U04IPWR 这颗 24 位 Δ-Σ ADC,搭配 Microchip 的 PIC18F96J65 做主控,实现了 HVAC 楼宇自控和工业过程测温都能用的完整温度采集链路。今天就把这套方案从器件选型、硬件电路到固件算法完整拆一遍,顺便把我在调试里踩过的坑也一并写出来。做温度采集的工程师、正在选型测温 ADC 的硬件攻城狮、以及想了解 UART 接口精密 ADC 怎么用的朋友,都可以从这篇文章里拿到能直接落地的思路。
1. 项目背景:为什么不能用单片机自带的ADC直接测温
1.1 温度信号的“真实尺寸”和想象的完全不一样
很多人觉得温度测量就是把传感器接上,读个数字,换算出温度。但真到了现场你会发现,传感器输出的信号比你想象中小得多。
拿最常见的 K 型热电偶来说,它每摄氏度只产生大约 41µV 的输出电压。这是什么概念?一个满量程 5V、12 位的单片机 ADC,1 个 LSB 大约是 1.22mV。K 型热电偶在这个 ADC 上要变化 30 个 LSB 才代表 1℃。也就是说,单片机内部 ADC 的量化台阶本身就比温度信号大了将近 30 倍,这还没算芯片自身噪声和参考电压漂移。你直接读,结果就是温度值在几个度之间乱跳,或者早上的读数和下午差出一大截。
就算你用 16 位、24 位的外置 ADC,信号链路里还有噪声、失调、增益误差、冷端补偿、传感器非线性这些坑等着你。搞温度测量,本质上是在处理一个“低电平、低带宽、但要求高精度”的弱信号系统。焊接不良引起的几毫欧接触电阻、PCB 走线上的一小段地环路、电源纹波里的高次谐波,都可能变成最终误差的重要来源。
1.2 12位、16位ADC到底哪里不够用
MCU 自带的 ADC 普遍是 10 位到 12 位,少数 16 位。12 位分辨率听起来好像“够用”,实际计算一下就知道差距有多大。
以 3.3V 基准、12 位 ADC 为例,一个 LSB 约 0.8mV。PT100 铂电阻的灵敏度约 0.385Ω/℃,如果激励电流取 1mA,那么温度对应的电压变化只有 0.385mV/℃。也就是说 12 位 ADC 每变化 1~2 个 LSB 才差不多对应 1℃。加上本身的 INL、增益误差和温漂,整机想做 ±0.2℃ 的 HVAC 精度目标,基本不可能。
16 位 ADC 好一些,但有效位数往往只有 13~15 位,而且多数片上 ADC 没有可编程增益放大器(PGA),热电偶这种微伏级信号进来,直接就被底噪淹没了。你或许可以外加仪表放大器把信号放大再送给 ADC,但这样一来,BOM 成本、PCB 面积、失调电压、偏置电流都成了新问题。与其在后端东拼西凑,不如直接选一颗前端集成度高的精密 ADC。
1.3 方案的整体思路:一个ADC和MCU各干各的
这个项目采用的架构是“精密 ADC 做前端、MCU 做后端”。ADS122U04IPWR 负责把传感器模拟信号变成数字量,PIC18F96J65 负责配置 ADC、读取结果、做数字滤波和线性化,然后通过 RS-485、4-20mA 或者其他总线把温度值送出去。
这样的好处一目了然:模拟链路的性能由一颗规范的 ADC 芯片来保证,MCU 不再需要关心模拟信号处理;同时,MCU 本身的并行能力和接口资源就可以专心处理协议、逻辑和用户界面。更妙的是,ADS122U04 用的是 UART 接口,这意味着 MCU 的任何一组串口都能和它对接,甚至可以用 RS-485 电平把 ADC 放到离传感器更近的位置,再用一根双绞线把数据传回主控板。这种“本地数字化”在工业现场是非常实用的招数。
2. 核心器件解析:ADS122U04IPWR 这颗 ADC 到底好在哪
2.1 24位 Delta-Sigma ADC 和 PGA 的组合拳
ADS122U04 是一颗 24 位 Δ-Σ(Delta-Sigma)ADC。Δ-Σ 架构本身依赖过采样和噪声整形,把量化噪声推到高频段,再用数字滤波器压掉,从而换来极高的有效分辨率。它不像逐次逼近型(SAR)ADC 那样一次比较一个 bit,而是靠大量采样和数字处理“磨”出精度。代价是转换速率相对较慢,但对温度这种缓慢变化的信号来说,20SPS 到几百 SPS 的数据率不仅够用,反而更有利于压低噪声。
这颗芯片内部还集成了可编程增益放大器,增益档位从 1 到 128 可调。这个 PGA 的作用是让 ADC 满量程范围跟着信号走:热电偶 40µV/℃ 级别的小信号,可以用 32 或 64 倍增益放大到 ADC 量程的合适位置;PT100 电阻在 1mA 激励下产生 0.1V 到 0.4V 左右的电压,用 1 倍或 2 倍增益即可。有了 PGA,就不需要再外接运放,失调和温漂问题也少了一截。
2.2 UART 接口:长距离、易隔离、还支持多设备寻址
ADS122U04 的特别之处在于它的数字接口是 UART,对于习惯用 SPI/I2C 的人来说,可能会觉得奇怪。实际上,UART 接口在工业温度测量里反而有不少好处理。
第一,UART 是异步串行,只需要 TX 和 RX 两根线,而且天生适合转换成 RS-485 差分信号。把 ADC 板和单片机板分开布置,传感器信号在源头转换成数字量,再通过 RS-485 传回主机,可以有效避免模拟信号长距离传输带来的干扰和衰减。第二,UART 收发端之间加数字隔离器非常方便。HVAC 现场温度探头和主控之间常常存在地电位差,加一个隔离器就能切断地环路,这比在模拟端做隔离要简单得多。第三,ADS122U04 支持在一个 UART 总线上通过地址寻址挂接多颗器件,相当于用一颗 MCU 就可以扩展出几十个温度采集通道,对楼宇自控这类通道数较多的场景很有价值。
2.3 温度测量专属外设:IDAC、内部温度传感器和烧断检测
ADC 芯片本身分辨率高不算稀奇,真正让 ADS122U04 适合温度测量的是它片上集成的一堆“周边设备”。
首先是可编程激励电流源 IDAC。PT100、PT1000 这类电阻型传感器需要恒流源或者恒压源驱动,IDAC 可以直接由寄存器配置输出 50µA 到 1mA 不等的激励电流,不需要外部恒流源电路。更重要的是,这个电流可以同时流过 PT100 和一个外部精密参考电阻,ADC 对两个电压做比例测量。这样一来,即使 IDAC 本身温漂或者随时间漂移,影响也会被完全抵消掉,这就是常说的“比例式(ratiometric)”测量。
其次是片内温度传感器。热电偶测量必须做冷端补偿,这个传感器可以直接用来测量 PCB 上冷端连接处的温度,精度足以完成常规补偿。当然,如果要求更高,可以在端子位置外接 PT100,用同一颗 ADC 的另一个通道单独测量冷端温度。
还有断线检测(burnout)功能。工业现场热电偶线断了是常有的事,如果系统不能及时发现断线,会把一个错误的温度值当真,甚至引发误动作。ADS122U04 可以通过内部电流源在输入端产生明显的偏移电压,让断线监控变得非常明确——开路时 ADC 读值会朝量程上端或下端靠,固件据此判断传感器状态。
2.4 封装选型和使用注意
ADS122U04IPWR 后缀里的 PW 是 TSSOP 封装,R 代表卷带包装。这颗芯片本身的工作温度范围足够覆盖 -40℃ 到 125℃,用在 HVAC 的户外温度探头和工业机柜里都没问题。
有一点要提醒:这颗 ADC 虽然是 24 位,但实际有效分辨率受噪声影响,不会真的到 24 位。数据手册里会给出不同数据率下的有效分辨率,比如在 20SPS 接近满增益时,有效位数可能接近 20 位甚至更高;把数据率拉高到 1000SPS,噪声会明显变大。做设计时不要只盯着 24 位的标记,要看手册里的 RMS 噪声和有效分辨率表格,不然会以为“24 位 ADC 怎么才跳几十个数”,其实是没理解有效位数的概念。
3. PIC18F96J65 在系统中的角色和软件分工
3.1 主控干的事情比你想的多
PIC18F96J65 是 Microchip 的 8 位 MCU,属于 PIC18 高端系列。选择它不是因为算力有多强,而是因为在这个任务里,主控要做的事情很明确,8 位机足够了。
主控的工作包括:上电时初始化 UART,向 ADS122U04 写入配置;在采样周期里发送数据读取命令,把 3 字节的转换结果接收回来;对原始数据进行均值滤波、中值滤波或者更复杂的滑动平均;把 ADC 码值换算成电阻值,再通过线性化算法换算成温度;最后把温度值送给上位机或触摸屏。此外,24 位有符号数在 8 位机上处理要多留意符号扩展和左移运算,避免计算出错。
3.2 双UART:一个测温度,一个聊协议
PIC18F96J65 的串口资源比较充足,这个方案里正好物尽其用。一路 UART 连 ADS122U04,用于 ADC 的命令和数据交互;另一路 UART 接 RS-485 收发器,对外跑 MODBUS RTU 协议。这样一来,ADC 的数据交互和对外通信完全分开,不会出现“正在读数时又得响应主机命令”的时序冲突。
在 HVAC 系统里,上位机通常是楼宇自控系统的 DDC 控制器或者 BA 系统网关,MODBUS RTU 是最保险的对接方式。在对 BACnet 有要求的场合,也可以把这颗 PIC 当作一个从站节点,跑 BACnet MS/TP。不过就实现成本来说,先把 MODBUS RTU 做好,逻辑和应用层再往上叠,是最稳的做法。
3.3 软件层的划分逻辑
实际开发时,我把软件分成三层:驱动层、算法层、应用层。
驱动层负责和 ADS122U04 打交道,封装成“读电压”“读寄存器”“配置通道”这样的函数,上层不需要关心 UART 命令细节。算法层负责把 ADC 码值变成温度,包括比例换算、PT100 线性化、热电偶冷端补偿、滤波等,输出统一的温度值。应用层只负责获取温度、判断限值、响应 MODBUS 请求。
分层的价值在于:换传感器类型时,只需要改算法层和驱动层的配置;换通信协议时,只需要改应用层。哪怕以后把 ADS122U04 换成别的 ADC,驱动层重写一遍,上层代码几乎不用动。做嵌入式项目,这种“模块之间不要互相捅”的习惯越早建立,后期维护越省事。
4. 传感器接口与硬件设计:精度是“铺”出来的
4.1 PT100/PT1000 测量:三线制接线和比例式测量的优势
RTD 是 HVAC 系统里最常用的温度传感器,PT100 和 PT1000 都有大量应用。RTD 的测量本质是测电阻,但导线的电阻会串进测量结果。
两线制最简单,但导线电阻误差直接叠加。比如 100 米长的 0.5mm² 铜导线,电阻大约 3~4Ω,折合到 PT100 的温度误差就是 10℃ 左右,完全不可接受。所以工程上至少要用三线制,把激励电流的回路和电压测量回路分开,让导线电阻的压降不进入 ADC 的差分测量范围。四线制自然更精确,但线缆成本高。HVAC 现场通常三线制就够,工业上要求高或者线长的话再上四线制。
前面提到的比例式测量是实现高精度 RTD 的关键。原理是让同一个 IDAC 电流同时流过 PT100 和外部参考电阻 RREF,然后 ADC 分别测量 V_PT100 和 V_RREF,用比值算出 PT100 的电阻:
R_PT100 = RREF * V_PT100 / V_RREF
因为 V_PT100 和 V_RREF 是从同一电流源产生的,IDAC 的温度漂移和长期漂移都被抵消掉了。整个测量链路的稳定性,就转移到 RREF 这颗参考电阻上,选温漂小于 5ppm/℃ 的精密电阻就能保证整个温度量程内都稳定。
4.2 热电偶测量:冷端补偿不是可选项
工业场景里测高温,热电偶比 RTD 合适。热电偶测的是两端温差,输出的是热电动势,不是绝对温度,因此必须知道冷端温度才能算出测量端温度。
冷端补偿的关键是“冷端”的位置要固定、要能测准。实际板子上,冷端就是热电偶线缆接到 PCB 端子的那一点。如果把冷端补偿传感器放在距端子很远的地方,那么连接点之间 PCB 铜箔的温度梯度就会被当作补偿误差,最后体现在读数里。
方案一:直接用 ADS122U04 内部温度传感器。优点是零成本,缺点是传感器的温度和端子实际的温度可能有差异,要做好热耦合,比如把 ADC 芯片和端子放在同一个铜铺地区域,减小温差。
方案二:用一颗 PT100 或 NTC 贴片传感器贴在端子旁边,用同一个 ADC 的另一个通道去测它。这里要注意 NTC 的非线性,最好选用高精度薄膜电阻,或者用 PT1000。实际工程中,如果要求整机误差小于 0.5℃,我一般会推荐外置 PT100/PT1000 做冷端补偿,内部传感器只做粗测或者开机自检。
热电偶信号本身只有几十 µV/℃,所以 PGA 增益通常在 32 到 64 之间。增益太高,满量程范围太窄,测不了 1000℃ 以上;增益太低,小信号又体现不出 ADC 精度优势。以 K 型热电偶为例,41µV/℃ 的灵敏度,在 2.5V 参考电压、增益 32 的条件下,量程约 ±78mV,折算成温度大约是 ±1900℃,完全够覆盖 K 型热电偶的典型量程,同时 LSB 的理论分辨率在 0.1℃ 以下。
4.3 供电、地回路的处理和 PCB 保护
精密 ADC 对电源质量是很敏感的。ADS122U04 的 AVDD 和 DVDD,最好严格按手册来设计,模拟供电建议用低噪声 LDO,并加足够的去耦电容。我习惯在 AVDD 引脚附近放 10µF 钽电容加 0.1µF 陶瓷电容,数字供电那边用 1µF 加 0.1µF。
在 PCB 布局上,模拟地和数字地要分开,然后单点连接。ADC 的正下方不要走数字信号线,尤其是 UART 的 TX 数据线和 ADC 的模拟输入,哪怕只是平行走了 1cm,高速翻转的数字信号都有可能通过耦合变成模拟链路的噪声。
输入端口的保护也必不可少。工业现场经常会遇到传感器线被拉拽、雷击浪涌、静电放电等情况。我的经验是在模拟输入引脚上加串联电阻限制电流,然后用双向 TVS 管对地钳位。串联电阻的阻值会影响 ADC 的输入阻抗匹配和滤波带宽,要结合信号源的输出阻抗一起来选,不能随意加大。
RS-485 一侧同样需要保护,加 TVS 和共模电感是常规做法。如果现场有强干扰源,比如变频器、大接触器,建议在 UART 到 RS-485 之间使用数字隔离器,把主控和外部总线完全隔开。HVAC 项目里做了隔离之后,通信异常的几率会明显下降。
4.4 传感器类型对比和选型表
实际项目里,传感器类型从没定死过。下面这张表是我经常用来做选型对照的,列的都是工程级的关键参数。
| 传感器类型 | 输出信号量级 | 典型测温范围 | 特点 | 主要应用场景 |
|---|---|---|---|---|
| PT100 | 0.385Ω/℃ | -200~850℃ | 线性度好、精度高,需要恒流激励 | HVAC 水管/风管温度、工业过程 |
| PT1000 | 约3.85Ω/℃ | -50~500℃ | 灵敏度比 PT100 高,线阻影响小 | 楼宇室温、设备表面测温 |
| K 型热电偶 | 约41µV/℃ | -200~1372℃ | 测量范围宽,需冷端补偿 | 工业炉温、烟气温度 |
| NTC 热敏电阻 | 阻值变化率大 | -40~150℃ | 便宜、灵敏度高,严重非线性 | 低成本室温、家电控制 |
这张表的作用不是告诉你哪种传感器最好,而是提醒你选型时把信号范围、激励方式和精度目标放在一起算。先算出传感器在所需温度范围内的最小和最大输出,再回头配置 ADC 的 PGA 和参考电压,这样才能避免“传感器选完发现 ADC 量程不匹配”的尴尬。
5. 固件实现的关键环节:配置、读取、线性化
5.1 初始化 ADC:不是写一次寄存器就完事
ADS122U04 的寄存器数量不多,但每位的含义都直接影响测量结果。初始化时我习惯按这样的顺序来:
- 先用复位命令让 ADC 回到默认状态,避免上电前残留的配置影响初始化。
- 配置输入多路开关,选定当前通道对应的模拟输入引脚。
- 设置 PGA 增益,根据传感器信号范围算好增益。
- 设置数据速率,20SPS 或 45SPS 这类低速率通常能获得更好的噪声表现,也方便和 50Hz/60Hz 陷波对齐。
- 设置参考电压来源。RTD 比例式测量时,选外部参考电阻两端电压作为参考;热电偶测量时,用内部参考或外部精密参考。
- 设置 IDAC 激励电流值和流向。
代码示例只写逻辑,不填具体字节,因为不同版本的芯片数据手册对位定义可能有出入,直接抄固定值风险最大。我在项目里会把寄存器定义全部做成宏或常量数组,写清楚每个配置字节是什么含义,换批次芯片时只需查一次手册就可以更新。
#define ADS_CMD_RESET 0x01 // 这里用宏占位,请以手册Command Table为准 #define ADS_CMD_RDATA 0x02 #define ADS_CMD_WREG 0x03 void ADS_Init(void) { uint8_t regs[6]; ADS_SendCommand(ADS_CMD_RESET); delay(10); regs[0] = MUX_SELECT_AIN0_AIN1 | IDAC_ROUTING; // 通道选择 regs[1] = 0x00; // 低阈值 regs[2] = 0x00; // 高阈值 regs[3] = DATA_RATE_20SPS | PGA_GAIN_32; // 数据率和增益 regs[4] = REF_EXTERNAL | IDAC_CURRENT_500uA; // 参考和电流 regs[5] = FIR_FILTER_ENABLE | BURNOUT_OFF; // 滤波和断线检测 ADS_WriteReg(0x00, regs, 6); }关键的一点:写配置之后,要给 ADC 留出建立时间,尤其是改增益、改多路开关后,前几个转换结果不能直接用,我会在固件里做“丢前 N 个样本”的机制。这个细节很容易被忽略,但实测下来,不丢样本直接滤波会引入明显的阶跃响应偏差。
5.2 读取 24 位数据和换算电压
读取转换结果的核心是搞清 ADC 输出的格式。ADS122U04 输出的 24 位数据是二进制补码,正满量程对应一个接近 0x7FFFFF 的值,负满量程对应 0x800000。换算电压之前,一定要先做符号扩展,否则把 0x800000 当作正数解释,你会得到一个大得离谱的错误电压。
如果满量程范围是 ±FS,那么 LSB 大小为 FS 除以 2^23。这里的推导要说明一下:24 位补码范围共 2^24 个码值,覆盖 2 倍满量程,所以 1LSB = 2FS/2^24 = FS/2^23。程序里拿“码值 × FS / 8388608”即可。
PIC18 这样的 8 位机做 32 位整数运算并不高效,但 24 位数据的长整形乘除法还是可以接受。如果对性能敏感,可以考虑用查表法做标定系数,或者把乘除改成移位和加法。温度采样本身是慢速任务,实际跑下来 CPU 占用率很低,不用太担心。
5.3 温度线性化:PT100 和热电偶两种玩法
PT100 的线性化最常用的是 IEC 60751 标准的 Callendar-Van Dusen 方程。
在 0~850℃ 范围:
R(T) = R0 × [1 + A×T + B×T²]
在 -200~0℃ 范围,需要额外增加一个三次修正项:
R(T) = R0 × [1 + A×T + B×T² + C×(T-100)×T³]
其中 A=3.9083×10⁻³,B=-5.775×10⁻⁷,C=-4.183×10⁻¹²。工程应用时通常从 ADC 读回电阻值,反解温度。因为方程是多项式的形式,最方便的办法就是用牛顿迭代法,迭代 3 到 10 次就能收敛到 0.001℃ 级别。
// 根据 Pt100 电阻值求温度,选取合适的初始值后牛顿迭代 float Pt100_ResToTemp(float R) { const float R0 = 100.0f; const float A = 3.9083e-3f; const float B = -5.775e-7f; const float C = -4.183e-12f; float t, f, df; t = (R / R0 - 1.0f) / A; // 线性近似作为初始值 for (int i = 0; i < 10; i++) { if (t < 0.0f) { f = R0 * (1.0f + A*t + B*t*t + C*(t - 100.0f)*t*t*t) - R; df = R0 * (A + 2.0f*B*t + C*(4.0f*t*t*t - 300.0f*t*t)); } else { f = R0 * (1.0f + A*t + B*t*t) - R; df = R0 * (A + 2.0f*B*t); } t -= f / df; } return t; }热电偶的线性化则是另一套逻辑。热电偶的输出电压和温度之间关系复杂,NIST 提供了 ITS-90 的多项式系数,工业上建议直接把系数做成 const 数组存进 Flash,或者上电时生成一张热电偶分度表,然后做查表加线性插值。HVAC 室温范围内的应用,温度范围窄,用一个二次或三次多项式拟合也足够。但不管是哪种方式,都要先处理冷端补偿。
冷端补偿的流程是:先测量冷端温度,根据热电偶类型反推出冷端温度对应的热电动势,加上 ADC 测得的电动势,再反推测量端温度。这个流程不复杂,但很多人会漏掉“反推补偿电动势”这一步,直接用冷端温度做简单加减,误差在 1℃ 以上。想做好冷端补偿,必须用正反两条曲线:一是“电压→温度”,二是“温度→电压”。
5.4 数字滤波和标定:精度最后还是要靠“校准”落地
ADS122U04 本身在低数据率下已经提供不错的滤波性能,但固件里再加一道数字滤波,效果会更稳。我在项目中常用的组合是:
- 第一步,用中值滤波去掉偶发的尖峰脉冲,窗口取 5 或 7。
- 第二步,对中值滤波后的数据进行滑动平均,窗口长度按更新时间要求来定。
- 同时,利用 ADC 的低速模式和数字滤波器的陷波特性,把 50Hz/60Hz 工频干扰压下去。20SPS 的数据率和 50Hz 陷波对齐,对 HVAC 现场这种动力线密集的环境非常实用。
不过,滤波会引入响应延迟。比如 20SPS 数据率下,一个 16 点的滑动平均相当于引入 0.8 秒的延迟。对 HVAC 恒温控制来说可以接受,但如果要做快速温度报警或者工业炉温保护,延迟就大了,需要根据现场要求平衡。
硬件和算法都到位之后,真正的精度还是要通过标定来保证。最简单的标定是两点标定:用标准电阻箱或冰点、沸点等基准温度源标出偏移和增益两个系数,写进 EEPROM,在换算公式里补偿。对于多通道系统,每个通道、每个量程单独标定,不会因为某个通道共用了一个基准就认为误差都一样的。标定操作最好做成一个“自检模式”,固件里预留命令接口,产线上通过上位机自动完成。
6. 实测踩坑记录与排查速查表
6.1 读数跳得厉害,噪声比预期大很多
这是我最常遇到的问题,尤其第一次用这颗 ADC 时。检测下来,通常并不是 ADC 芯片本身噪声大,而是信号链路里混入了不该有的干扰。
排查顺序一般这样:先用短接线把 ADC 输入端短路到模拟地,读几个样本,看输出码值的分布宽度。如果此时噪声依然很大,那就是电源或者参考电压有问题;如果此时读数很稳,再把传感器接回去,问题就出在传感器线缆或接线电路。
另外,要检查 PGA 增益旁边的小信号走线是不是和数字线交叉了。UART TX 引脚到 MCU 的这根线,如果离模拟输入太近,每发一条命令都会在 ADC 输入端引入一个噪声尖峰。PCB 改版后,这类问题通常能明显改善。
6.2 温度读数有一个固定的偏差,而且跟线长有关
测 PT100 时出现固定偏差,最常见的原因就是测量方式和线阻问题。两线制接线不把导线电阻去掉,几十欧姆的线阻直接叠加到 PT100 上,温度读数自然偏高。
解决办法就是把接线改成三线制或四线制。如果硬件已经定型只能用两线制,那么可以在固件里做线阻补偿,但线阻会随温度变化,补偿并不可靠。另外,如果输入端口的串联保护电阻太大,比如接了几百欧姆,这个电阻也会叠加进测量结果,影响同样不小。
再有就是参考电阻 RREF 的精度。比例式测量里 RREF 的误差直接等于温度误差。RREF 用 1% 精度的电阻,温度就可能偏好几度,必须选 0.1% 甚至 0.05% 精度的低温漂电阻。
6.3 热电偶冷端补偿误差很大
热电偶测出来的温度,在室温附近总有明显的偏差,而且和实际环境温度的变化趋势相反,十有八九是冷端补偿没有做对。要么是没启用 ADC 内部温度传感器,要么是补偿公式里少了“温度—反推电动势”步骤。
我处理过一个工程,室内装了好几路 K 型热电偶,读数和水银温度计差 2℃。排查发现放大器的参考端根本没接冷端温度传感器,而是用了固定 0℃ 做补偿,这在恒温室里可能影响不大,但在南方夏季的机房里就完全失效。把补偿逻辑改对之后,误差回到 0.3℃ 以内。
6.4 UART 通信时好时坏、首字节丢失
PIC 和 ADC 之间的 UART 通信出问题,通常有三个原因。一是波特率没有配准,尤其当 PLL 分频设置和外部晶振频率不匹配时,误差会超出 UART 容限。建议直接用芯片内部振荡器校准或者选一个整数分频的波特率。二是 ADC 的 UART 引脚上缺失上拉电阻,空闲电平不确定,首字节丢失概率很大。加一个 10kΩ 上拉就能改善。三是长线传输时没有做终端电阻和隔离,产生振铃和误码,这在 RS-485 场景里尤其要留意。
6.5 排查对照表
| 现象 | 可能原因 | 检查与对策 |
|---|---|---|
| 输出码值乱跳 | 电源噪声、地环路、数字线干扰 | 输入端短接测试,LDO 去耦,单点接地,PCB 布局调整 |
| 温度固定偏高 | 两线制线阻、RREF 精度差、保护电阻叠加 | 改三/四线制,换 0.1% 电阻,软件补偿 |
| 温度读数波动大 | 数据率太高、滤波强度不足 | 降低数据率到 20SPS,加滑动平均 |
| 热电偶误差大 | 冷端补偿缺失或补偿温度不准 | 正确启用内部/外部冷端补偿 |
| 首字节丢失 | 波特率不准、缺上拉 | 校准时钟,加 10kΩ 上拉 |
| 传感器断线不能发现 | 未启用断线检测电流 | 配置烧断电流,并设置正确的断线判据 |
7. 一些项目体会
这个方案做完之后,我最大的感受是:温度测量的瓶颈往往不在 ADC 芯片本身,而在使用它的“大局观”。传感器选型、激励方式、参考电阻、PCB 布局、冷端补偿、线性化算法、滤波延迟、现场保护和校准流程,每一步都像木桶上的一块板,任何一块太短,最终精度都会从那里漏掉。ADS122U04IPWR 把很多模拟链路的麻烦挡在了芯片内部,PIC18F96J65 又把协议和计算的杂活接了过去,两颗芯片配合得好,才能腾出精力去处理真正影响精度的细节。
如果你也打算做类似的测温板,建议第一版不要急着堆功能,先把一路 PT100 三线制测量和一路 K 型热电偶测量彻底调通,把硬件噪声底和软件滤波逻辑摸清楚,再考虑多通道扩展。通道数增加之后,ADC 配置切换、通道轮询和标定管理会带来新的一轮挑战,但底层的基础则是可以在早期就夯实。这套 ADC+MCU 的架构,后续不管往 BACnet、MODBUS 还是 4-20mA 环路方向走,迁移成本都相对可控,值得在这个方向上多投入一些精力。