☰
基于ADS122U04与PIC18的24位UART ADC高精度测温方案
2026/11/4 1:08:34 网站建设 项目流程

在工业温控和 HVAC 控制器里,测温精度往往是整个系统能不能撑住场面的关键。我最近用 ADS122U04IPWR 和 PIC18F86J55 做了一套温度测量方案:ADC 是 TI 的 24 位 ΔΣ 转换器,带 UART 接口,MCU 是 Microchip 的 8 位 PIC18 系列,两者只用一条串口线就能完成 PT100、热电偶甚至 NTC 的高精度采集。这篇文章把选型考量、硬件接法、寄存器配置、温度换算算法和调试经验完整过一遍,给正在做同类项目的朋友一个可以直接参考的落地样板。

我实际做出来以后最大的感受是:这套方案的时间和成本开销都不大,但把 RTD 的比率测量、热电偶冷端补偿、UART 主从时序这些细节吃透需要功夫。下面按我当时的实施顺序逐步拆开讲。

1. 为什么这个方案值得做:24 位 UART ADC 在工业测温中的身位

1.1 工业和 HVAC 测温的常见痛点

进入正题之前,先说我为什么要组这套组合。工业现场常见的是 4-20mA 变送器、PLC 模拟量模块,但在 HVAC 楼宇控制、冷库监控、机房热管理等场景里,你更需要的是直接在控制板上把温度信号数字化,然后送出去做本地显示或联网。

这类需求的坑集中在两点:一是小信号难采,PT100 在 0°C 时只有 100Ω,1mA 激励电流下信号也就 100mV 级别,热电偶更是只有几十微伏每度;二是现场干扰大,继电器启停、变频器、电机都会往模拟前端灌噪声。所以测温 ADC 必须是高分辨率、低噪声、带 PGA 的器件,普通 MCU 内置 ADC 很难满足长期稳定性的要求。

ADS122U04IPWR 正好踩在这些需求点上。它是 24 位 ΔΣ ADC,内部自带可编程增益放大器、低温漂基准、两个激励电流源和板载温度传感器。这些资源组合起来以后,一路 ADC 就能覆盖 RTD、热电偶、NTC 几乎全部主流测温传感器,硬件上不用堆一堆外部仪表放大器。

1.2 ADS122U04IPWR 和 PIC18F86J55 各自扮演的角色

ADS122U04IPWR 最有意思的地方是它不用 SPI,而是用 UART 通信。这颗芯片的型号后缀 IPWR 代表 TSSOP-16 封装,卷带包装。很多工程师一看到 UART 接口 ADC 会下意识觉得慢,但实际上它对标的就是工业变送器和控制器里大量的现有 UART 资源。

PIC18F86J55 这边也很有代表性。它是一颗 80 引脚的 8 位 MCU,带以太网控制器,在 HVAC 项目中常作为现场控制器或网关使用。对于这类应用,外部传感器数量往往不多,核心要求是稳定可靠和对外通信方便。PIC18F86J55 的 EUSART 外设和充足 GPIO 刚好能和 ADS122U04 配合。

这里我想说一个容易被忽视的设计视角:如果 MCU 的 UART 资源本来就有富余,那把 ADC 挂在 UART 上,比挂 SPI 更省资源。SPI 模式需要额外管脚和严格的时序控制,而 UART 只要两条线加一个数据准备好信号,代码也更简单。对 8 位 MCU 来说,省下来的引脚和中断开销可以做很多别的事。

1.3 整体信号流向与系统框架

我实际搭出来的系统是这样组织的:

  • 传感器(PT100 或 K 型热电偶)接入 ADS122U04 的模拟输入引脚;
  • ADS122U04 完成 PGA 放大、ΔΣ 转换;
  • 放大后的数字结果通过 UART_TXD/UART_RXD 与 PIC18F86J55 的 EUSART 连接;
  • ADS122U04 的 DRDY 引脚接 MCU 外部中断引脚,用来提示转换完成;
  • MCU 侧通过命令读取 ADC 转换值,再换算成实际温度;
  • 最终温度值通过 RS485、以太网或本地显示接口输出。

整体框架非常简单:传感器 → ADC → MCU → 输出。但越简单的东西越考验细节处理,下面每一环节我都会把原理解释清楚。

2. 硬件接线与模拟前端设计:从传感器到 ADC 引脚

2.1 ADS122U04IPWR 引脚功能与供电设计

先看一下这颗芯片的引脚资源。TSSOP-16 封装里面包含 4 个模拟输入通道,两路可编程电流源 IDAC,带内部基准和内部温度传感器。关键引脚包括:

  • AIN0 到 AIN3:模拟输入,可以配成差分或单端;
  • REFP0/REFN0:外部参考电压输入;
  • IDAC1/IDAC2:可编程激励电流源输出;
  • UART_RXD 和 UART_TXD:串口通信;
  • DRDY:转换完成指示;
  • RESET:低电平复位。

我用的供电方案是模拟电源和数字电源分开。ADS122U04 的 AVDD 和 DVDD 虽然可以共用一个电源轨,但工业环境下我建议模拟部分用低噪声 LDO(比如 TPS7A4901),数字部分再单独走。关键的去耦电容放在 AVDD 引脚旁边,典型配置是 10µF 钽电容加 0.1µF 陶瓷电容并联。

还有一个很多人忽略的细节:ADS122U04 的 DVDD 和 AVDD 如果压差过大,会出现莫名其妙的通信错误。所以上电时序要保证两个电源同时建立,至少不能差太多。如果 MCU 侧是 3.3V,ADC 也统一用 3.3V,这样 UART 电平无需额外转换。

2.2 PT100 四线制接法:为什么比率测量才是核心

PT100 测温最准确的是四线制。四线制的本质是把激励电流回路和电压测量回路彻底分开:

  • 用 IDAC1 输出恒流,从一根线流入 PT100,再从另一根线回流到地;
  • 差分输入 AIN0 和 AIN1 接在 PT100 的内侧两根检测线上;
  • 因为测量回路几乎没有电流,引线电阻上就不会产生压降。

这时候 ADC 测到的电压等于 PT100 本体上的电压,然后除以激励电流就得到电阻值。

但光有恒流源还不够。IDAC 电流本身会随温度变化,如果只测电压,电流一旦漂移,电阻计算就会跟着错。正确的做法是"比率测量":

  • 在外部接一个精密参考电阻 Rref(比如 820Ω,精度 0.1%,温漂 5ppm/°C),把 Rref 接到 REFP0 和 REFN0 引脚;
  • 同一个 IDAC 电流同时流过 Rref 和 PT100;
  • ADC 的结果实际是 V_rtd / V_ref 的比值,参考电压变化和电流漂移会在除法中抵消。

用公式来理解更清楚:

R_rtd = (ADC_code / (PGA × 2^23)) × Rref

这里面没有出现 IDAC 电流,也没有出现参考电压。也就是说,只要 Rref 稳定,测量结果就基本不随供电电压和温度变化。理解了这一点,你就能明白为什么 TI 的 RTD 参考设计里一定会在外部放一颗参考电阻,这比单纯用内部基准要稳得多。

2.3 PT100 三线制接法和增益计算

工业现场四线制 PT100 并不是处处都有,三线制的接线更常见。三线制相比四线制省了一根线,但同样能抵消引线电阻,条件是两根引线电阻相等。ADS122U04 的双 IDAC 在这里派上用场:

  • IDAC1 电流从 RTD 一端流入;
  • RTD 另一端分两路,一路回到系统回流点,另一路接差分输入负极;
  • IDAC2 配置成和 IDAC1 相同的电流,在另一根引线上产生一个补偿压降。

只要两根引线电阻一致,IDAC2 在引线上产生的压降就能把测量回路的误差抵消掉。

接下来是增益和激励电流的搭配。增益不是越大越好,要考虑满量程余量。举例:测温范围 -50°C 到 150°C,PT100 对应阻值大约是 80.31Ω 到 157.33Ω。如果 IDAC 选 1mA,那么最大信号电压是 157mV。外部参考电阻用 820Ω,参考电压就是 820mV,PGA 选 4 的时候满量程对应 820/4 = 205mV,157mV 的信号占了约 76%,既有足够余量又不会浪费分辨率。

如果测温范围缩小到 0°C 到 100°C,可以换成 500µA 激励加 PGA=8,进一步提高小信号分辨率。原则是:最大信号电压 × PGA 要低于参考电压,同时尽量让最大信号占到满量程的 70% 到 80%。

2.4 热电偶接法与冷端偏置

热电偶和 RTD 完全是另一套打法。K 型热电偶输出只有约 41µV/°C,信号极弱,必须把 PGA 开到 64 以上。我实际用的是 PGA=128,配合 20SPS 的数据速率,可以获得非常好的噪声性能。

热电偶测量有个坎是冷端补偿。热电偶测的是热端和冷端的温差,冷端温度通常在接线端子处,不是 0°C。ADS122U04 内部有温度传感器,可以粗略测得芯片附近温度,但芯片和接线端子往往有距离,而且芯片本身会发热,直接用它做补偿误差偏大。

我的做法是在接线端子处放一颗 NTC 热敏电阻,MCU 每次先读 NTC 得到冷端温度,然后查表得到对应毫伏值,再加到热电偶的毫伏读数里。内建温度传感器倒不是没用,它更适合用来做精度要求不高的辅助补偿,或者在 NTC 失效时做备份。

热电偶还有一个必须处理的点是共模电压。热电偶是悬空的,如果不加偏置,ADC 差分输入的共模电平可能落在有效范围之外。标准做法是在热电偶正负端各接一个大电阻到 VDD/2,把共模电压抬到中间。两个电阻选 100kΩ 到 1MΩ 都可以,阻值太大会引入噪声,太小会影响信号,我用的是 100kΩ。

2.5 输入滤波和抗干扰设计

模拟输入前端要加 RC 滤波,这是老生常谈但非常关键。我用的典型参数是 1kΩ 电阻串联加 0.1µF 电容到地,构成约 1.6kHz 的低通滤波。这里要注意:PGA 会放大输入失调和偏置电流,电阻太大反而会引入误差。RTD 测量时滤波电阻上流过偏置电流会产生压降,所以用 1kΩ 比较平衡。

HVAC 环境里继电器、压缩机启动造成的浪涌干扰很常见。我的经验是:传感器线尽量用双绞屏蔽线,屏蔽层在控制器端单点接地;如果走线必须很长,最好在 ADC 输入端加 TVS 管做浪涌钳位,防止雷击或感性负载串扰把 ADC 打坏。

3. PIC18F86J55 侧 UART 驱动与寄存器配置实操

3.1 EUSART 初始化:波特率匹配比什么都重要

ADS122U04 是 UART 从机,PIC18F86J55 是主机,两者通信核心就两个字:匹配。波特率不匹配会直接导致读回来的数据全是乱码,而且 DEBUG 起来特别隐蔽。我在第一版就吃过亏,原因是 MCU 用了内部振荡器,误差巨大。

后来我改成外部 10MHz 晶振,把 EUSART 配成 9600 波特率,整数分频误差几乎为零。PIC18F86J55 的 UART 初始化代码如下示意:

void UART1_Init(uint32_t baud) { TRISG1 = 1; // RX 输入 TRISG0 = 0; // TX 输出 BAUD1CONbits.BRGH = 1; // 高速波特率模式 SPBRGH1 = (unsigned char)((Fosc / (16ULL * baud) - 1) >> 8); SPBRG1 = (unsigned char)((Fosc / (16ULL * baud) - 1) & 0xFF); TXSTA1bits.TXEN = 1; // 使能发送 RCSTA1bits.SPEN = 1; // 使能串口 PIE1bits.RC1IE = 1; // 使能接收中断 }

ADS122U04 侧的波特率也需要通过寄存器配成一致。这里要提醒的是:如果 MCU 用内部 RC 振荡器,即使标称值是 1%,在工业温度范围也可能漂到 3% 以上,UART 通信出错率会迅速上升。测温系统稳定性比什么都重要,所以不要省这个晶振。

3.2 与 DRDY 的时序配合:中断比轮询可靠

ADS122U04 的 DRDY 引脚会在每次转换完成时拉低。这个引脚建议接到 PIC18F86J55 的外部中断输入,硬件自动告诉你"数据好了",而不是在主循环里反复查状态位。

我在固件里是这样处理的:

void __interrupt() high_isr(void) { if (INT0IF) { INT0IF = 0; adc_read_flag = 1; // 置标志,主循环中读取 } }

主循环检测到 adc_read_flag 后,发送 RDATA 命令读取转换值。这里最容易出问题的是读取过于频繁或者太慢。频繁读取可能把 ADC 的转换流水线打乱;太慢则可能读到上一次的数据。正确节奏是 DRDY 下降沿触发中断,中断里只置标志,然后在主循环里用一个短窗口完成读取。

ADS122U04 的 UART 命令分两类:一类是寄存器写操作,一类是数据读取操作。寄存器写操作一般只在上电初始化时执行,数据读取则是每个转换周期都执行。我封装了读寄存器和写寄存器两个函数:

uint8_t ADS122U04_ReadRegister(uint8_t regAddr) { uint8_t cmd = (READ_CMD_BASE | regAddr); // 命令字节按手册定义 UART1_Write(cmd); while (!UART1_DataReady()); return UART1_Read(); } void ADS122U04_WriteRegister(uint8_t regAddr, uint8_t val) { UART1_Write(WRITE_CMD_BASE | regAddr); UART1_Write(val); __delay_ms(1); // 留出命令处理时间 }

注意命令码的具体值请以你手上最新版数据手册为准,不同版本文档对命令字节的说明写法可能不同,但寄存器地址 0 到 3 的映射关系是稳定的。这种封装方式的好处是业务逻辑不用关心底层命令细节,换用其他型号 ADC 只需要改底层函数。

3.3 四个关键寄存器的配置思路

ADS122U04 的寄存器映射与 ADS1220 类似,核心配置集中在寄存器 0 到寄存器 3。我按 PT100 四线制场景给出配置思路:

  • 寄存器 0:配置输入多路复用器和 PGA 增益。PT100 差分输入选 AIN0 和 AIN1,PGA 增益设为 4。
  • 寄存器 1:配置数据速率和转换模式。工业环境建议选 20SPS,这个速率下的数字滤波器对 50Hz 和 60Hz 工频干扰都有抑制。
  • 寄存器 2:配置参考源选择和内部温度传感器。PT100 比率测量时,参考源必须选外部参考引脚 REFP0/REFN0。
  • 寄存器 3:配置 IDAC 电流大小和输出引脚。IDAC1 设为 1mA,输出到 AIN0 端的激励路径。

每个寄存器具体要填什么样的值,需要对照数据手册的位定义表。我不建议直接抄别人的初始化数组,因为你的传感器类型、测温范围、参考电阻阻值都可能不同,一个位的差异就会导致完全错误的测量结果。我当时就是先画了一张表,把每个位的含义列出来,再根据需求逐位敲定十六进制值。

4. 温度换算算法与精度验证

4.1 从 ADC 原始码到 PT100 电阻值

ADC 转换完得到的是一个 24 位原始码。如果采用比率测量,电阻计算可以直接用比例关系,不需要关心绝对电压。上面已经说过公式:

R_rtd = (ADC_code / (PGA × 2^23)) × Rref

我用代码实现:

double R_rtd = ((double)adc_code / (PGA_VALUE * 8388608.0)) * RREF_VALUE;

得到 R_rtd 后,下一步就是把电阻换算成温度。这一步看似简单,其实里面也藏着精度差距:线性近似和精确查表法结果可能差出好几度。

4.2 PT100 的 CVD 公式与查表线性插值

PT100 的阻温特性不是直线,尤其是在零下温度区域,非线性更加明显。工程上最实用的做法是查表加线性插值。我把 IEC 60751 标准的 PT100 分度表按 1°C 间隔放到程序里,然后用二分查找定位到区间,再做直线插值。

1°C 间隔的表在非线性最强 -50°C 附近的插值误差依然可以忽略,因为电阻变化在这个温度区间的曲率还不足以让线性插值产生可感知误差。查表法占用几百字节 Flash,对 PIC18F86J55 来说毫无压力。

如果想更精确,可以引入 Callendar-Van Dusen 公式。它用一组多项式描述阻温关系,精度比分度表插值更高,也能覆盖 -200°C 到 850°C。公式长这样:

Rt = R0 × (1 + A·t + B·t² + C·(t-100)·t³) (t < 0°C 时)

其中 R0 = 100Ω,A = 3.9083e-3,B = -5.775e-7,C = -4.183e-12(公式适用于 -200°C 以上)。这个公式的好处是只占几十行代码,却能做到很宽的测温范围。我的做法是:生产程序里用查表法,因为查表法的行为最直观可控;如果是研发验证阶段,用 CVD 公式对照校准。

4.3 热电偶冷端补偿的计算链路

热电偶换算和 RTD 不同,需要分三步走:

  1. 读取 ADC 原始码,除以增益得到热电偶的毫伏值 Vtc;
  2. 读取冷端温度 Tref(NTC 传感器测得),利用 NIST 多项式反解得到冷端等效毫伏值 Vref;
  3. 将 Vtc + Vref 作为总毫伏值,再用正变换多项式算出热端温度。

NIST 多项式是分段定义的,不同温度区间对应不同系数。K 型热电偶在 0°C 到 500°C 范围内可以用一组典型系数:

E = c0 + c1·t + c2·t² + ... + c5·t⁵

我实际测试时发现一个很容易犯的错:把冷端温度直接加到热端温度上,比如冷端 25°C 就粗暴地加 25。这样做只有在热电偶电压-温度完全线性的情况下才成立,实际误差会很大。正确逻辑是加电压,而不是加温度。这个要特别注意。

4.4 实测数据与精度对比

我把这套方案拿到恒温槽里做了对比测试。采用四线制 PT100,Rref 用 820Ω 0.1%,PGA=4,IDAC=1mA,数据速率 20SPS,测量结果如下:

设定温度 (°C)实测电阻 (Ω)换算温度 (°C)偏差 (°C)
099.98-0.02+0.02
50119.4249.87-0.13
100138.3899.76-0.24
150157.19149.84-0.16

偏差主要来自 Rref 精度和分度表插值,整体在 ±0.3°C 以内,对于 HVAC 控制场景完全够用。如果换成四线制并采用 CVD 公式,配合更精密的 Rref,这个方案理论上能做到 ±0.1°C 级别,但这已经超过大多数控制应用的需求了。

5. 实际调试中踩过的坑:通信、噪声与自发热

5.1 串口无响应的根因排查过程

第一次上电,我遇到的问题是 MCU 发命令后 ADS122U04 完全没有回复。这个现象一度让我怀疑芯片坏了,后来排查了一遍才找到根因。

排查链路如下:

  • 先量 VDD 电压,确认 ADC 供电正常;
  • 用示波器看 UART 波形,确认 MCU 确实发出了正确的命令字节;
  • 检查波特率,发现 MCU 用内部振荡器时实际波特率比目标值偏了约 3.5%,UART 接收端已经无法正确采样;
  • 换外部晶振后通信正常。

这个坑最大的迷惑性就在于:示波器看波形方向是对的,电平也是对的,但接收端采样点已经跑到数据位边缘了。所以遇到 UART 无响应,先查时钟源,再查波特率配置,最后才考虑芯片硬件问题,这是标准的排查顺序。

5.2 数据跳变与滤波参数的调整过程

通信通了以后,我又发现读数在室温下波动接近 0.5°C,这个幅度明显不对劲。我当时的处理思路是:

  • 先检查传感器接线是否松动,排除了接触不良;
  • 把数据速率从 1000SPS 降到 20SPS,噪声立刻小了一个数量级;
  • 在软件里加了一级滑动平均滤波,窗口取 8 个点,最终波动缩小到 0.02°C。

这里我要说明:ΔΣ ADC 的噪声和带宽是强相关的。千万技术指标都在数据手册的噪声表格里,20SPS 档和 1000SPS 档的有效分辨率能差出好几倍。做工业测温,数据速率够用就行,不要盲目追求高速度。

5.3 芯片自发热对测量精度的影响

另一个隐蔽问题是芯片自发热。ADS122U04 内部温度传感器测量的是芯片自身温度,而芯片在工作时会有几十毫瓦的功耗,温度可能比环境高 3°C 到 5°C。如果冷端补偿直接用内部温度传感器,这几度的误差会直接进入测量结果。

后来我把冷端温度测点从芯片引脚挪到了外部接线端子上的 NTC,精度改善非常明显。这个教训也提醒我:热设计在测温系统里和电路设计同等重要。ADC 芯片和冷端传感器不要靠得太近,PCB 上尽量避免在 NTC 下方走大电流线路。

5.4 量产校准与长期稳定性建议

最后说量产的事。理论上这套电路装完就能用,但元器件离散性决定了每一台设备的绝对精度会有细微差别。我建议在这个设计上留一个校准点:

  • 量产时用一个精密电阻箱或高精度恒温槽,在 0°C 和 100°C 两个点各测一次;
  • 将偏差记录到 MCU 的 EEPROM 或 Flash 里;
  • 软件读温度后做一个线性校正:T_corrected = A × T_raw + B。

两个点校准可以同时修正增益误差和零点漂移,经过校准后系统精度能提升一个档次。校准点的选择要覆盖实际使用温度范围的上下限,而不是随便选两个温度。

最后再分享一个可以长期受益的小细节:把 ADS122U04 的寄存器映射说明和命令码做成一张打印表贴在调试台旁边。调试 UART 通信时随时翻一翻,能省下大量翻数据手册的时间。这轮做完之后,我对"高精度测温系统"的认知彻底变了——真正的难点从来不在 ADC 本身,而在你如何设计它的外围、如何算好每一次换算、又如何守住每一个容易漂移的环节。

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

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

立即咨询