前阵子做一台 HVAC 控制柜的改造,原来的 NTC 热敏电阻方案在夏季工况下偏差超过 2℃,客户又要求把管道温度信号并入楼宇自控系统。折腾了一圈,最后落地的方案是用 ADS122U04IPWR 这颗 24 位 Δ-Σ ADC 配合 PIC18LF45K22 做主控。整套系统跑下来,温度测量的稳定性和精度都比之前上了个台阶,工业传感器接口和 HVAC 场景里的那些坑也基本摸了一遍。这篇就把我从选型、硬件连接、固件协议到现场排障的完整过程写出来,给正在做温度采集、尤其是准备用串口型 ADC 做工业或 HVAC 测温的朋友一个可以直接参考的路径。
这套方案的核心思路其实不复杂:ADS122U04 负责把 PT100 / PT1000 / 热电偶的微弱信号转成 24 位数字量,并通过 UART 接口直接把结果送给 PIC18LF45K22;单片机负责发命令、读数据、做线性化和温度换算,再通过 RS-485 或者以太网把结果上传。适合那些对精度有要求、但又不希望引入 FPGA 或 ARM 复杂体系的嵌入式项目。
1. 为什么是 ADS122U04 + PIC18LF45K22:从"0.1℃"这个刚需说起
1.1 温度信号到底有多微弱,ADC 分辨率不是参数竞赛
很多人看到"24 位 ADC"第一反应是堆参数,但做温度测量的人会告诉你:这玩意儿是刚需,不是因为好看。
拿最常用的 PT100 来说,0℃ 时阻值 100Ω,温度系数大约是 0.385Ω/℃。如果用一个 500µA 的恒流源去激励它,那么在 0~100℃ 范围内,电压变化量只有约 19mV。换算一下,每 1℃ 才对应约 0.19mV 的电压变化。想要分辨到 0.1℃,至少要能分辨约 19µV。
如果用 16 位 ADC,参考电压 2.048V,PGA 增益 8 倍,那么 LSB 大约 7.8µV,理论分辨率勉强够到 0.04℃,但这是理想值。实际上了系统,噪声、参考源漂移、PCB 漏电流一叠加,16 位方案要稳定做到 0.1℃ 就很吃力了。而 ADS122U04 是真正的 24 位 Δ-Σ 架构,即便只算有效位数(ENOB)而不是标称位数,配合合理的 PGA 设置和数据速率,0.01℃ 级别的原始分辨率也绰绰有余。也就是说,后端的误差瓶颈可以完全转移到传感器本身和标定环节,而不是被 ADC 卡住。
1.2 UART 接口的 ADC 在工业布线里的价值被低估了
ADS122U04 和同系列的 ADS122C04 最大的区别就是数字接口:一个是 UART,一个是 I2C。我特意选了 UART 版本,原因在于工业现场的真实约束。
第一是布线距离。I2C 和 SPI 在 1.8V 电平下,超过 30~50cm 就开始出现各种信号完整性问题,而 UART 在几米范围内仍然稳定。HVAC 项目里,传感器探头和主控板之间的线缆长度通常以米计算,UART 明显更合适。
第二是隔离难度。工业设备基本都要求信号隔离。SPI 需要隔离时钟、片选、数据三到四根线,I2C 是开漏结构还要处理上拉电平。而 UART 只有 TX 和 RX 两根线,用数字隔离器或光耦非常方便,成本也低。后续如果想做 RS-485 远传,直接对接即可,不需要额外转换。
第三是抗干扰。UART 的异步协议对时序要求比 SPI 宽松得多,不太容易因为时钟抖动导致数据错位。加上 ADC 侧本身有 CRC 校验,链路可靠性比想象中高很多。这套组合在变频器、电磁阀频繁启停的环境下实测,误码率完全可接受。
1.3 PIC18LF45K22 在这个系统里扮演什么角色
选 PIC18LF45K22 不是因为它有多强,而是因为它"刚刚好"。
ADS122U04 是一个 ADC,它不做计算、不做逻辑判断,只会按命令完成转换并通过 UART 把数据吐出来。温度换算需要查表、插值、线性化,这些活儿交给 8 位单片机完全够用。PIC18LF45K22 有多个 UART 外设、足够的 GPIO、丰富的定时器资源,而且 LF 版本支持 1.8V~3.6V 宽压供电,在低功耗 HVAC 控制器里长期运行很合适。
我实际用它的时候,只占用了一个 UART 和两个 GPIO(分别接 DRDY 和 RESET),剩余的 UART 还能再接 RS-485 模块或者调试串口。对于温度采集这种单任务量级的应用,8 位机不仅够用,而且开发速度快、成本低、供应链也稳妥。
2. 硬件连接:先把激励、基准和电平转换这三件事钉死
2.1 传感器选型:PT100 还是 PT1000、NTC 还是热电偶
ADS122U04 是通用型 ADC,不是专用的 RTD 前端,所以传感器选型直接决定后续配置方式。我按应用场景整理了对比:
| 传感器类型 | 典型量程 | 灵敏度 | 线性度 | 激励方式 | 适用场景 |
|---|---|---|---|---|---|
| PT100 | -200~850℃ | 0.385Ω/℃ | 较好 | 恒流源 | 管道/水系统/高精度 |
| PT1000 | -200~850℃ | 3.85Ω/℃ | 较好 | 恒流源 | 低功耗/长线场景 |
| NTC | -40~150℃ | 高但非线性 | 差 | 恒流或分压 | 低成本 HVAC 风管 |
| K 型热电偶 | -200~1370℃ | 约 40µV/℃ | 中等 | 无激励,需冷端补偿 | 燃烧设备/高温烟道 |
HVAC 项目里,冷冻水、冷却水、热水管道温度测量我首选 PT100;风管这种对成本敏感的场合可以用 NTC,但需要在软件里做多项式拟合;燃烧机、锅炉烟气场景才需要热电偶。本文后续以 PT100 为例展开,因为它在工业 HVAC 里覆盖率最高。
2.2 IDAC 恒流激励:电流值不是拍脑袋定的
ADS122U04 内部集成了两个匹配的恒流源 IDAC1 和 IDAC2,这是它做电阻类传感器测量最顺手的地方。
激励电流的选择要权衡两个因素:信噪比和自热误差。电流越大,RTD 上的压降越大,信噪比越高;但电流流过传感器会产生 I²R 热功率。以 PT100 为例,500µA 电流在 100Ω 上产生 50mV 压降,功耗只有 25µW。PT100 的自热系数典型值约 0.4℃/mW 量级,此时自热温升约 0.01℃,完全可以忽略;而如果把电流调到 1mA,功耗变成 100µW,自热误差会放大到 0.04℃ 左右,在精密测量里就不可忽视了。
所以我的配置原则是:0~200℃ 量程内,PT100 用 500µA;如果探头是细长封装、安装在静止空气中,散热差,就降到 250µA,分辨率依然够。
2.3 外部参考电阻与比例式测量:这是整个精度体系的基石
这里是我认为 ADS122U04 测温方案里最核心、也最容易被忽略的一步:外部参考电压 + 比例式测量。
很多人一上来就用芯片内部 2.048V 基准,然后把 RTD 电压经 PGA 放大后去和内部基准比较。这种做法不是不行,但有一个隐患:IDAC 电流的温漂和基准电压的温漂是独立的,两者没有抵消关系,最终精度取决于这两个参数的稳定性。
正确的做法是把恒流源的电流同时引到 RTD 和一个精密参考电阻上,用参考电阻的压降作为 ADC 的参考电压。电路上就是:IDAC1 电流流过 RTD,在 AINP/AINN 上产生 Vsensor;同一路电流(或匹配的 IDAC2)流过外部参考电阻 Rref,在 REFP/REFN 上产生 Vref。ADC 的转换结果本质上是 Vsensor 与 Vref 的比值。
推导过程很直观:
- Vsensor = I × Rrtd
- Vref = I × Rref
- Code比例 = Vsensor / Vref = Rrtd / Rref
电流 I 在分子分母中同时出现,直接约掉。也就是说,即使 IDAC 电流随温度漂移了 10%,ADC 输出码几乎不受影响。系统精度最终只取决于参考电阻 Rref 的精度和温漂,而不取决于电流源的绝对精度。这也是为什么推荐用低温漂(25ppm/℃ 或更好)、高精度(0.1%)的金属膜电阻做 Rref 的原因——它是整个链条里少数几个需要花钱的元件。
注意:参考电压 Vref 的幅值不能超过 ADC 的模拟输入范围和电源轨。例如用 500µA 电流配 2kΩ 参考电阻,Vref = 1V,完全在常见功耗预算内。如果打算扩展量程到 800℃,要考虑 RTD 电阻变大后 Vsensor 是否超过 Vref 的测量范围,必要时降低增益或换更小的 Rref。
2.4 1.8V 数字电平和 3.3V 主控之间的电平转换:必踩的坑
ADS122U04 的数字接口电平不是 3.3V,而是 1.8V。它的 DVDD 需要单独提供 1.8V 电源,DOUT/DIN 引脚的高电平也是 1.8V 量级。PIC18LF45K22 如果工作在 3.3V,两者直接相连会有两个问题:
- PIC 的 TX(3.3V 高电平)接到 ADS 的 DIN(1.8V 供电的逻辑输入),3.3V 可能超出 ADS 引脚的绝对最大额定值,长期运行有损坏风险。
- ADS 的 DOUT 高电平只有 1.8V,而 3.3V 供电的 PIC 的 VIH 阈值通常是 0.8 × VDD ≈ 2.64V,1.8V 根本拉不高,读不到正确的 1。
解决方案我建议直接用双向电平转换芯片,比如 TXB0104 一级搞定,两路通信刚好够用。想省成本也可以用两个电阻分压把 3.3V 降到 1.8V 附近,但这只解决 PIC→ADS 方向,反方向仍然需要一级电平抬升。千万别在只做单方向处理之后就拿示波器戳,大概率看到的是杂乱波形。
还有两个硬件细节容易被首次使用的人忽略:
- CLK 引脚绝不是悬空的。ADS122U04 需要外部提供 1MHz~5MHz 左右的时钟信号,常见做法是用有源晶振或者从 MCU 的 PWM/定时器引脚输出一路时钟。我第一次点亮时片子纹丝不动,查了半天才发现 CLK 没有接,芯片内部没有振荡器。
- DVDD 上电次序和去耦要留意,电源引脚旁边放 100nF 陶瓷电容,AVDD 和 DVDD 之间别共享同一根细长走线。
3. 固件层:UART 命令帧、寄存器配置与 PIC 侧轮询代码
3.1 先把 ADS122U04 的命令协议摸清楚
ADS122U04 的命令帧和 I2C 那种"地址+数据"的直观风格不一样,它是一串字节按固定格式拼在一起,而且每条命令最后可以附一个 CRC 字节做校验。常用命令其实就几个:
| 命令字节 | 功能 | 说明 |
|---|---|---|
| 0x20 | RDATA | 读取一次转换结果,返回 3 字节数据 + CRC |
| 0x22 | RREG | 读寄存器,第二字节指定起始地址和数量 |
| 0x23 | WREG | 写寄存器,后续跟寄存器值和数据 |
| 0x24~0x27 | RDATA 连续模式 | 连续读转换结果,适合高吞吐 |
如果启用了 CRC,报文里的每一个字节,包括命令字节本身,都要参与 CRC 计算。这个设计非常适合长线传输,因为 UART 本身不提供任何错误检测,全靠应用层补上。
经验:写寄存器前先读一次 REG0~REG3,确认芯片处于正常通信状态。上电后芯片默认配置可能不是你想要的,直接写配置前最好发一个复位命令(或拉 RESET 引脚)确保寄存器回到已知状态。
3.2 寄存器配置:PT100 比例式测量的一组参考值
ADS122U04 的寄存器不多,核心是 REG0~REG3 四个。下面这组配置是我在项目里验证过、可以直接抄作业的组合,但位域的具体排列请务必对照数据手册的 Register Map 过一遍,不同批次手册描述可能有细微差异。
配置目标如下:
- 输入通道:AIN0 与 AIN1 组成差分对,PT100 接在两者之间
- PGA 增益:8 倍,把 500µA × 100Ω ≈ 50mV 的信号放大到合理范围
- 数据速率:20SPS,这个档位对工频 50Hz 干扰有较好的抑制,适合工业环境
- IDAC:500µA,IDAC1 输出到 AIN0,电流从 RTD 流过并经 AIN1 回流
- 参考电压:外部参考输入,Rref 接在 REFP/REFN
对应的示例数组如下,代码里的宏值我已经标注了大致含义:
// 寄存器值对应含义以手册为准,这里给出的是工程参考值 uint8_t regs[4] = {0x18, 0x62, 0x54, 0x20}; // REG0: AIN0-AIN1 差分,PGA=8,正常模式 // REG1: 20SPS,连续转换 // REG2: IDAC=500uA,路由到 AIN0/AIN1 // REG3: 选择外部参考输入 REFP/REFN实际配置时我不会一次性写四个寄存器,而是先写一个读一个,确认芯片返回的数据和预期一致,再继续下一个。
3.3 PIC18LF45K22 侧代码:UART 初始化、CRC8 与读取流程
PIC18LF45K22 的 UART 用标准 EUSART 模块即可,波特率我建议 9600 或 19200,因为 ADS122U04 的命令帧很短,9600 波特率下每秒也能完成几十次轮询,远够 HVAC 温度采集的需求。更高波特率在长线上的误码率会上升,没必要。
核心初始化与读取代码如下:
// PIC18LF45K22 + ADS122U04,UART1 19200 8-N-1 void UART1_Init(void) { TRISCbits.RC7 = 0; // RX 输入 TRISCbits.RC6 = 1; // TX 输出 BAUDCON1bits.BRG16 = 1; SPBRGH1 = 0; SPBRG1 = 25; // 16MHz FOSC,19200 波特率 TXSTA1bits.TXEN = 1; // 使能发送 RCSTA1bits.SPEN = 1; // 使能串口 RCSTA1bits.CREN = 1; // 使能接收 } // CRC-8:多项式 0x07,初值 0xFF,MSB 先行 uint8_t ads_crc8(const uint8_t *data, uint8_t len) { uint8_t crc = 0xFF; for (uint8_t i = 0; i < len; i++) { crc ^= data[i]; for (uint8_t bit = 0; bit < 8; bit++) { if (crc & 0x80) crc = (uint8_t)((crc << 1) ^ 0x07); else crc <<= 1; } } return crc; } // 写寄存器,带 CRC void ADS_WriteRegs(uint8_t start_reg, const uint8_t *values, uint8_t count) { uint8_t tx[10]; uint8_t idx = 0; tx[idx++] = 0x23; // WREG 命令 tx[idx++] = (uint8_t)((start_reg << 4) | (count - 1)); // 起始地址 + 数量-1 for (uint8_t i = 0; i < count; i++) tx[idx++] = values[i]; tx[idx++] = ads_crc8(tx, idx); // 校验覆盖整帧 for (uint8_t i = 0; i < idx; i++) UART1_Write(tx[i]); } // 等待 DRDY 拉低后,读取一次转换结果 int32_t ADS_ReadData(void) { uint8_t cmd = 0x20; uint8_t buf[4]; UART1_Write(cmd); // RDATA,CRC 已通过 DREQ? 此处按需求忽略 for (uint8_t i = 0; i < 4; i++) // 3 字节数据 + 1 字节 CRC buf[i] = UART1_Read(); uint32_t raw = ((uint32_t)buf[0] << 16) | ((uint32_t)buf[1] << 8) | buf[2]; if (raw & 0x800000UL) raw |= 0xFF000000UL; // 扩展符号位,转成有符号数 return (int32_t)raw; }说明一下,ADS122U04 的输出是 24 位二进制补码格式,正满量程对应 0x7FFFFF,负满量程对应 0x800000。上位机拿到原始码后要先做符号扩展再参与计算。上面代码把 CRC 的判断略掉了,实际工程中要比较收到的 CRC 字节和本地计算结果,不一致就丢弃本轮数据,连续 N 次失败则重新初始化通信。
3.4 DRDY 引脚的使用:GPIO 查询比中断更省心
ADS122U04 每次完成一次转换后会拉低 DRDY,持续到下一次读取或下一次转换开始。在 HVAC 这种慢速传感器场景里,用 GPIO 查询的方式就够了,没有必要上外部中断。
我的轮询框架是这样的:
- 配置好寄存器后,进入主循环
- 等待 DRDY 拉低(超时计数器保护,防止死等)
- 发 RDATA 命令读取 3 字节数据
- 校验 CRC,计算温度
- 回到第 2 步
单次转换模式下也可以采用"发 START 命令 → 等 DRDY → 读数据"的方式,比连续模式更省电,适合电池供电的设备。连续模式的优点是时序简单、吞吐稳定,项目里我默认用连续模式。
坑:DRDY 是推挽还是开漏要看清。如果板子上同时挂了多个设备,开漏输出需要外部上拉;推挽则不要画蛇添足加上拉,否则可能出现电平冲突。
4. 从原始码到温度:比例换算、查表线性化与现场校准
4.1 三步换算:ADC Code 先转电阻,电阻再转温度
拿到 24 位补码之后,第一步是把码值换算成 RTD 的电阻值。利用前面推导的比例关系:
- Rrtd = (Code × Rref) / (PGA × 2^23)
这里分母用 2^23 而不是 2^24,是因为 24 位补码表示的满量程范围是 -2^23 到 +2^23-1,也就是说 LSB 对应的电压是 Vref / (PGA × 2^23)。如果配置中启用了 PGA 且倍数为 8,那么实际换算公式记得除以增益。
举个例子:Rref 用 2kΩ,PGA=8,读到的 Code 是 134217(约满量程的 1/64),那么 Rrtd ≈ 134217 × 2000 / (8 × 8388608) ≈ 4.0Ω。当然这个例子的 Code 对应温度很低,真实的 PT100 在 0℃ 时应该读到约 100Ω。
第二步是把电阻值转成温度。PT100 遵循 IEC 60751 标准:
- 0~850℃:Rt = R0 × (1 + A·t + B·t²)
- -200~0℃:Rt = R0 × (1 + A·t + B·t² + C·(t-100)·t³)
其中 R0 = 100Ω,A = 3.9083e-3,B = -5.775e-7,C = -4.183e-12。
从电阻反算温度时如果直接套公式,会得到一个关于 t 的高次方程,解起来麻烦。工程上更常见的做法是查表加线性插值,表格按 1℃ 间隔预生成,插值误差可控制在 0.05℃ 以内,比反复迭代求解高效且稳定。
4.2 查表插值代码:简单可靠,还方便现场调试
以 -50℃ 到 150℃ 为例,生成一张 201 点的 PT100 电阻-温度表,编译时用 const 数组放好。查找时先从表格里找出电阻值所在的区间,再按比例插值:
#define TEMP_MIN (-50) #define TEMP_MAX (150) #define TEMP_STEP (1) // 假设 Rtable[i] 对应 TEMP_MIN + i 的温度 float Rtd_To_Temp(float rtd) { int low = 0, high = 200; if (rtd <= Rtable[0]) return TEMP_MIN; if (rtd >= Rtable[200]) return TEMP_MAX; while (high - low > 1) { int mid = (low + high) / 2; if (Rtable[mid] <= rtd) low = mid; else high = mid; } float r0 = Rtable[low], r1 = Rtable[high]; float frac = (rtd - r0) / (r1 - r0); return (TEMP_MIN + low) + frac; }这个函数的计算量在 8 位单片机上也是毫秒级,完全够用。查表法的另一个好处是方便现场核对:拿标准电阻箱给入已知阻值,直接看温度输出就能判断标定是否正确,而用多项式拟合就很难这样直观调试。
4.3 现场校准:两点校准怎么做,三线制补偿又该注意什么
即使有外部参考电阻和比例式测量,系统里还有 PGA 增益误差、板级放大器的温漂、连接器接触电阻等残余误差。出厂前做一次两点校准是必要的:
- 零点校准:用精密 100Ω 标准电阻替代 PT100,记录 ADC 输出码,计算出偏移量。
- 增益校准:用高精度电阻箱设置一个量程点,比如 138.5Ω(对应 100℃),记录输出码,计算增益修正系数。
校准系数可以存入非易失性存储区,每次上电加载。工业项目里我还会留一个"校准模式",现场用经过计量的标准铂电阻温度计比对一下,只调整增益系数就能完成现场修正,不用回厂。
三线制接法在工业 HVAC 里非常普遍,目的是消除引线电阻的影响。原理是:两根引线分别承载 IDAC 电流回路,第三根线提供电压采样参考,两个 IDAC 电流设置成相同值,只要匹配良好,引线电阻上的压降在采样路径上自动抵消。ADS122U04 的两个 IDAC 电流共享同一配置寄存器,天然相等,这点很省事。但要注意,如果只用单 IDAC + 二线制接法,每米引线电阻大约 0.1Ω 量级,长了之后对 0.1℃ 精度的影响是实打实的,务必评估。
5. HVAC 现场实测:干扰、自热与被忽略的物理细节
5.1 干扰排查链路:从"读数跳变"到锁定元凶
HVAC 控制柜里的干扰源比实验室多得多:变频器、电动阀、接触器、开关电源,全是潜在噪声源。如果现场温度读数出现跳变,我的排查顺序如下:
| 步骤 | 操作 | 判断依据 |
|---|---|---|
| 1 | 断开传感器,接入精密电阻 | 若读数稳定,问题在传感器侧 |
| 2 | 接入传感器,观察原始码峰峰值 | 统计 500 个点,正常应 < 20 LSB |
| 3 | 示波器测量 REFP/REFN 电压 | 纹波应 < 1mV,否则检查参考电阻和滤波 |
| 4 | 检查 UART 线缆与动力线是否同槽 | 同槽会引入共模干扰,CRC 错误率上升 |
| 5 | 测量 AVDD 电源纹波 | 高频纹波会造成 ADC 有效位数下降 |
几乎每次排查到最后,干扰源无非三类:电源纹波没滤干净、参考电压回路布局不好、UART 线缆与动力线平行走线过长。要么是配置问题,要么是结构问题,芯片本身的抗扰能力其实比想象中好。
5.2 软件滤波:20SPS 是起点,滑动平均才是保底
ADS122U04 在 20SPS 数据速率下,内部数字滤波器对工频及其谐波已经有比较好的抑制,但这不意味着软件层可以躺平。工业现场偶发脉冲干扰、雷击浪涌、设备启停尖峰,还是会通过传感器线耦合进来,表现为单点毛刺。
我在固件里做的是先去掉最大最小值的中值滤波,再做滑动平均。具体做法:每 8 个原始码做一个窗口,去掉一个最大、一个最小,剩余 6 个取平均,作为这一轮的测量值。实测效果非常理想,既保留了传感器自身的响应速度,又滤掉了偶发脉冲。温度场的惯性很大,水流和空气的热时间常数以秒计,所以温度响应慢几十毫秒完全无感。
5.3 HVAC 特有的几个隐藏坑:冷凝水、自热和长线缆
第一坑是冷凝水。空调箱、冷冻水管的温度探头,表面温度可能低于露点,长期运行会有凝露甚至积水。一旦接线端子受潮,绝缘电阻下降,相当于在 RTD 两端并联了一个可变电阻,温度读数会莫名其妙偏高。这个问题只能从工艺上解决:探头选用防水密封型,接线盒灌胶,线缆进线口做滴水弯。
第二坑是自热误差的"隐身"。PT100 的标称自热系数是在特定散热条件下给出的,实际安装在静止空气的风管里,散热条件差,自热误差可能比官方数据翻几倍。对策有两个:一是把 IDAC 电流从 500µA 降到 250µA;二是在标定时尽量模拟实际安装环境。低速风管和不通风的测温套管里,这一步尤其关键。
第三坑是长线缆的分布电容影响。UART 线如果超过 5 米而且没有屏蔽,波形边沿会被电容拖圆,波特率稍高就出现字节错误。解决方法是降低波特率或加 TVS 管和共模电感,别盲目追求 115200。
5.4 一个典型的现场调试案例:AHU 回风温度"恒高 0.6℃"
做某栋楼 AHU 机组改造时碰到一个案例:回风温度探头装在风管内部,读数始终比水银温度计高 0.6℃,而且长期稳定,不像干扰。排查过程很有意思。
先排除 ADC 链路:把探头从风管拆出,放在实验室环境测量,读数恢复正常。说明 ADC 和配置没问题,问题在安装环境。再测安装位置附近的风速,发现探头正好装在送回风混流区,气流经过探头时摩擦生热,再加上套管导热不良,探头自身温度比真实风温高出一截。最终调整探头位置,并给探头加了一层隔热护套,误差降到 0.1℃ 以内。
这个案例说明温度测量在很多情况下不是电的问题,而是热的问题。RTD 测的是自身感温元件的温度,不是空气温度。热通路、辐射换热、风速影响,每一项都可能造成系统误差,而且这种误差靠软件校准是校不掉的。
6. 一些可以少走弯路的调试建议
ADS122U04 用 UART 接口这件事,在给项目带来便利的同时,也要求开发者比用 SPI 时更注意应用层协议。有三条经验我觉得值得单独拎出来说。
第一条:先把 CRC 通路上电验证,再做任何高级功能。方法很简单,发一条 RREG 命令读回 REG0,核对返回的 CRC 是否正确。这一步能同时验证 UART 波特率、接线方向、逻辑电平、CLK 配置是否正确。如果 CRC 一直错,别急着改代码,用示波器看 DOUT 引脚的波形,确认高电平确实到 1.8V、低电平确实到地,很多时候问题出在电平转换电路上。
第二条:温度系统的精度是一个"链条",不是芯片参数的功劳。外部参考电阻、PGA 增益漂移、传感器安装工艺、线缆端子接触电阻,每一环都可能贡献误差。我把系统设计成了"比例式测量 + 查表 + 两点校准"三段式,每一段都有明确的可调试抓手,出了问题能快速定位。那些把精度完全寄托在 ADC 位数上的项目,最后基本都在标定环节来回折腾。
第三条:批量生产时一定要考虑标准电阻校验工装。项目进入量产阶段后,每块板子通电后自动进入"校准模式",由产测程序依次切入标准电阻 100Ω 和 138.5Ω,固件自动把偏移和增益系数写入 EEPROM。这样一块板子的标定时间不超过 10 秒,而且避免了人工记录数据的低级错误。成本上只增加了两个精密电阻和一对测试端子,回报率非常高。
目前这套方案在多个 HVAC 项目里持续运行,有冷冻站的水温监测、有洁净厂房的温湿度采集、也有锅炉房的烟气温度测量。我最直观的感受是,ADS122U04IPWR 和 PIC18LF45K22 的组合在"中等精度、高可靠、低成本、易隔离"这个区间里抓得相当准。如果你手头正在做类似的需求,关键就是把激励、基准、CRC、线性化这几件事理顺,测量结果自然就立住了。