ADS122U04IPWR与PIC18LF4515高精度测温方案:UART接口24位ADC搭配8位MCU实战 去年帮客户做一个 HVAC 控制器的测温模块对方第一句话就把方案定死了不能再用单片机内置 ADC 凑合精度必须上去主控直接用 8 位单片机成本要压住。当时第一反应就是 TI 的 ADS122U04IPWR 和 Microchip 的 PIC18LF4515 这对组合。ADS122U04IPWR 是 24 位 Δ-Σ ADC自带 PGA、电压基准和电流源最有意思的是它不走 SPI而是走 UART这让它在工业现场长线传输和电气隔离场景里特别省事。PIC18LF4515 是一颗 3.3V 供电的 8 位 MCU虽然内部也有 ADC但那种 10 位分辨率拿来测温度基本就是自己给自己挖坑它在这套方案里的真正职责是跟 ADS122U04IPWR 通信、做数据解析、跑温度换算和上层控制逻辑。这篇东西是给正在做工业温度采集或者 HVAC 控制器的工程师看的我会从方案选型、硬件接法、固件流程、校准优化一路讲到实际踩坑。你如果手头正好有这两颗芯片或者想找一颗带 UART 接口的高精度 ADC 搭配 MCU可以直接照着抄。全文不讲空话只讲我在实际项目里怎么用、为什么这么用、哪里容易翻车。1. 项目定位为什么用这两颗芯片做工业和 HVAC 测温1.1 需求拆解工业与 HVAC 场景的测温核心指标先看工业和 HVAC 的测温需求到底卡在哪里。工业现场最常见的是热电偶和 RTD热电偶输出的是微伏到毫伏级的微弱信号一个 K 型热电偶在 0℃ 附近大约只有 40μV 的灵敏度稍微有点噪声就没法看。PT100 的情况稍好但温度变化 1℃ 对应的电阻变化只有大约 0.385Ω如果是两线制接法导线电阻引入的误差轻轻松松就是几摄氏度。这就决定了前端必须要有高分辨率 ADC、可配置增益放大器和稳定的基准源。HVAC 侧的核心要求不太一样它更看重系统级的稳定和成本。一套楼宇空调控制器可能要同时采集室外温度、回风温度、供水温度、盘管温度等多个点位这些传感器往往分布在十几米甚至几十米的线缆末端走线路径又会经过变频器、继电器和电源模块。所以除了精度还要求 ADC 有一定的共模抑制能力和数字滤波能力。另外这类产品通常 7x24 小时运行还要求低功耗、器件长寿命、长期漂移可控。结合这两类需求可以整理出三条硬性指标。第一测量分辨率必须高于 16 位热电偶信号的毫伏级变化在 12 位或者 10 位 ADC 面前完全不够看。第二前端必须能够对微弱信号做可编程增益放大否则像热电偶这种信号要再搭一级运放电路复杂度和成本都会超出控制。第三通信接口最好能支持一定距离的抗干扰传输UART 比 SPI 在这类场景里更有优势随便加一对 RS-485 收发器就能跑很长的线。1.2 选型分析ADS122U04IPWR 与 PIC18LF4515 的分工逻辑为什么最终落到 ADS122U04IPWR 上看一圈市面上主流的 24 位 ADC带 UART 接口的本来就少。ADS122U04IPWR 内部集成度高得离谱一个 24 位 Δ-Σ 调制器、可编程增益放大器、内部基准、两个可编程电流源、内部温度传感器全塞在一个 TSSOP-16 封装里。这意味着外部只需要加几个电阻电容就能完成信号链路的搭建这在工业现场算是一个很实在的优势板子面积小、失效点少、调试简单。更关键的是它的 UART 接口。传统 ADC 比如 ADS1220 走的是 SPI 四线SCLK、DIN、DOUT、CS 一个都不能少时序还必须跟 MCU 严格对上。ADS122U04IPWR 直接把这个痛点绕过去了用两线串口跟 MCU 通信数据帧自带 CRC 校验。工程上讲两件事被大大简化一是 MCU 端不需要 GPIO 模拟 SPI 时序直接用 EUSART 模块就行二是如果系统要做隔离光耦或者数字隔离器只需要两路成本比隔离 SPI 省一半。PIC18LF4515 在这套方案里承担的职责很清楚它不做模拟采样只负责跟 ADS122U04IPWR 通信、解析数据帧、跑温度算法和控制逻辑。选择它的原因有几个。LF 后缀代表低电压版本1.8V 到 3.6V 供电范围跟 ADS122U04IPWR 的数字 IO 电平天然匹配不需要额外做电平转换。Flash 空间足够塞下一套完整的 PID 控制逻辑和温度查表程序而且 Microchip 的 8 位单片机在工业环境里的抗干扰口碑一直不错货源稳定、价格也压得下来。另外注意一下型号里的 IPWR 后缀这是 TI 的标准封装标识。I 代表工业温度范围PWR 表示 TSSOP-16 封装加卷带包装。打样采购的时候别买错了如果你只要几颗样品应该找带 TAPE 或者管子包装的渠道卷带包装一般 2500 颗一盘量少反而不好分装。2. 硬件电路设计与连接方案2.1 PIC18LF4515 与 ADS122U04IPWR 的接口连线从电路连接上看这套方案真正需要关心的线并不多。PIC18LF4515 的 EUSART 模块两根线直接接过去即可控制器的发送脚 TX 接 ADC 的 DIN控制器的接收脚 RX 接 ADC 的 DOUT共地之后就能通信。ADS122U04IPWR 的电源可以跟单片机共用一组 3.3V但模拟电源引脚和数字电源引脚最好分别经过磁珠或者小电阻隔离避免数字开关噪声窜进模拟链路。RESET 引脚不要悬空建议用一个 10kΩ 电阻上拉到电源。CS 引脚在 UART 模式下一般可以直接接地但实际项目中我更推荐用一个 GPIO 控制这样可以在需要的时候把 ADC 置于硬件复位或片选无效状态方便做异常恢复。如果你看到数据手册里提到 MODE 引脚这决定了芯片工作在 UART 模式还是 SPI 模式硬件上一定要按 UART 模式的要求接好焊反了或者悬空会导致芯片完全不应答。供电部分需要注意一个细节ADS122U04IPWR 的模拟电源对纹波很敏感建议用低噪声 LDO 供电而不是直接拿 DC-DC 的输出怼上去。如果板上空间有限必须用 DC-DC那就把输出滤波电容加大并在 ADC 电源引脚附近加一个 10μF 钽电容和一个 0.1μF 陶瓷电容组成两级去耦。我实测下来电源纹波在 20mV 左右时ADC 输出噪声会明显增加尤其在 PGA 增益设置为 128 倍的时候读数跳动可以从几个 LSB 飙到几十个 LSB。2.2 传感器接入PT100、热电偶与热敏电阻的典型接法先讲 RTD 的比例测量接法。这是 ADS122U04IPWR 最好用的工作模式之一芯片内部提供两路恒流源用一路电流流过精密参考电阻 Rref 产生基准电压同时用另一路电流流过 PT100ADC 的输入电压和基准电压来自同一个电流源理论上电流波动不会影响测量结果这叫比例测量。实际接法是电流源 IOUT1 流过 Rref再流过 PT100 到地ADC 的正负输入端分别采样 PT100 两端的电压。如果 PT100 离板子比较远建议用三线制接法从 PT100 的端点引一根第三线到 ADC 的负输入端这样可以消除导线电阻带来的误差。对于热电偶事情稍有不同。热电偶输出电压太微弱必须把 PGA 增益开到最大比如 128 倍。输入可以直接接到 ADC 的差分输入端但要注意加一个简单的 RC 低通滤波通常取 10kΩ 电阻串联加 100nF 电容到地既能滤掉高频噪声又能提供一定的 ESD 保护。热电偶还需要冷端补偿ADS122U04IPWR 内部自带的温度传感器可以读芯片附近的环境温度精度大约 ±0.5℃在很多 HVAC 场景已经够用如果要求更高可以外接一颗 NTC 并做标定。热敏电阻是另一种低成本方案在 HVAC 消费级控制器里非常常见。NTC 一般接成电阻分压形式把分压点接到 ADC 输入。这种接法不需要恒流源节省两个引脚成本也更低。缺点是线性度差需要 MCU 端做查表或者多项式拟合补偿。一个实践经验是NTC 分压电路里的上拉电阻最好用 1% 精度否则误差会直接叠加到温度读数上。2.3 电源与 PCB 布局的实战注意事项布局这件事本着急用先用的原则提几个重点。第一模拟地和数字地不要混着走。最好的做法是在 PCB 上划分出模拟区域和数字区域RTD 分压网络、参考电阻、ADC 输入引脚全部放在模拟区域EUSART 走线和电源走线放在数字区域最后在 ADC 芯片下方用一颗 0Ω 电阻或者磁珠做单点汇接。第二参考电阻 Rref 的位置要紧挨着 ADC 的基准输入引脚而且要选低温漂的精密电阻25ppm/℃ 起步最好做到 5ppm/℃。Rref 的精度直接决定最终测量精度因为比例测量的基准就是它。第三点是个非常隐蔽但杀伤力极大的坑PCB 漏电。在高湿度的 HVAC 环境里PCB 表面如果没有良好的阻焊覆盖和足够的走线间距相邻焊盘之间的微小泄漏电流足以让高阻输入场景下的 ADC 读数漂移几十个码。解决办法是 ADC 输入引脚和走线周围尽量铺地铜箔保护环走线间距拉到 0.3mm 以上并且做完板子后涂一层三防漆。对于 24 位 ADC 这种级别的系统这层保护比多花几块钱买好电阻还管用。Sensor 线缆的选择也不能马虎。RTD 和热电偶的延长线最好用屏蔽双绞线屏蔽层在控制板端单点接地不要在传感器端同时接地否则会形成地环路反而引入共模噪声。我见过一个案例客户把屏蔽层两头都接地结果 50Hz 工频干扰直接灌进 ADC 输入读数在 ±2℃ 之间狂跳后来把传感器端屏蔽层断开才恢复正常。3. 固件实现从 UART 通信到温度换算3.1 初始化 EUSART 与基础读写函数固件这块我用 C 语言配合 MPLAB XC8 编译器来写PIC18LF4515 的 EUSART 初始化比较简单。先确定波特率ADS122U04IPWR 的 UART 接口波特率可以通过寄存器配置默认一般是 9600也可以配置成 19200 或者更高。实际项目里如果不是对采集速率有苛刻要求9600 或者 19200 就够用了波特率越低长线传输越稳定。下面是初始化代码示例// 配置 PIC18LF4515 EUSART8 位数据、无校验、1 位停止位高速模式 void uart_init(unsigned long baud) { unsigned int spbrg_val; spbrg_val (unsigned int)((unsigned long)_XTAL_FREQ / (16UL * baud) - 1UL); SPBRGH (unsigned char)(spbrg_val 8); SPBRG (unsigned char)(spbrg_val 0xFF); TXSTA 0x24; // 开启发送BRGH1 高速模式 RCSTA 0x90; // 开启接收SPEN1CREN1 连续接收 } // 发送一个字节 void uart_send_byte(unsigned char byte) { while (!PIR1bits.TXIF) ; TXREG byte; } // 接收一个字节 unsigned char uart_receive_byte(void) { while (!PIR1bits.RCIF) ; return RCREG; }这里要强调一下PIC 的 EUSART 初始化细节跟具体型号有关上面的代码针对 PIC18LF4515 验证过但如果你换到其他 PIC18 型号寄存器名字和位定义可能存在差异移植时一定翻一下对应数据手册的寄存器章节。调用的 _XTAL_FREQ 宏要在工程里提前定义成实际系统时钟频率比如 32MHz 或 40MHz波特率计算才能对上。我一开始忘了定义这个宏结果 SPBRG 算出来全是错的UART 完全收不到数据排查了半天才发现是这里的问题。3.2 ADS122U04 寄存器配置与数据帧解析ADS122U04IPWR 的 UART 帧结构并不复杂但必须严格按照手册来组帧和解析。大致结构是命令帧包含命令字节、寄存器地址或数据字节以及一个 CRC 校验字节。芯片收到命令后会返回对应的状态字节和数据字节同样带 CRC。调试阶段可以先把 CRC 校验关掉或者只看数据部分但正式产品里强烈建议留校验逻辑因为工业现场噪声干扰很容易让一两个字节翻转没有校验的话温度数据会出现毛刺值。写寄存器时发送里带上要写的寄存器地址和数据。比如要把通道选择配置为 AIN0-AIN1并设置 PGA 增益可以通过写 MUX 寄存器和 PGA 寄存器完成。下面是一个通用的写入函数模板// 计算 CRC 的函数具体多项式与初值参考数据手册 unsigned char adc_calc_crc(unsigned char *buf, unsigned char len); void adc_write_reg(unsigned char reg_addr, unsigned char reg_data) { unsigned char frame[4]; frame[0] 0x40; // 写寄存器命令码具体值以手册为准 frame[1] reg_addr; frame[2] reg_data; frame[3] adc_calc_crc(frame, 3); for (unsigned char i 0; i 4; i) uart_send_byte(frame[i]); } void adc_read_data(unsigned long *result) { unsigned char rx[5]; unsigned char tx[1] {0x20}; // 读转换结果命令码 uart_send_byte(tx[0]); for (unsigned char i 0; i 5; i) rx[i] uart_receive_byte(); // 按手册帧格式组装 24 位数据一般是从 rx[1] 开始取 3 字节 *result ((unsigned long)rx[1] 16) | ((unsigned long)rx[2] 8) | ((unsigned long)rx[3]); }配置寄存器这件事最关键的几个参数是通道多路复用器、PGA 增益、数据速率和电流源开关状态。数据速率的选择会影响噪声性能速率越低Δ-Σ 调制器内部的数字滤波越充分噪声越小。我一般在工业现场用 20SPS 或 45SPS既能滤掉 50Hz 工频干扰又满足温度变化速度的采样需求。如果你需要更快响应比如做温度保护快速切断可以提到 640SPS但要做好读数变噪的心理准备。3.3 温度计算流程比例法、查表与冷端补偿拿到 ADC 原始码之后下一步才是真正的温度换算。以 PT100 比例测量为例满量程对应的转换结果大约是 0x7FFFFF也就是 2 的 23 次方减一。如果参考电阻 Rref 已知PT100 的实测电阻 Rrtd 可以按下面的公式算Rrtd (raw_code / 0x7FFFFF) * Rref注意这个公式默认 PGA 增益为 1如果开了增益还需要除回增益系数。算到 Rrtd 之后再用查表法或者 Callendar-Van Dusen 方程换算成实际温度。最省事的做法是程序里放一张 PT100 分度表每隔 10℃ 存一个阻值中间用线性插值来逼近。在 0℃ 到 100℃ 范围内线性插值配合表中数据产生的误差很小完全足够 HVAC 的 ±0.5℃ 要求。热电偶的换算是另一套逻辑。先用 PGA 乘以原始码换算出实测的毫伏电压然后查热电偶分度表得到“表观温度”但这个温度是相对冷端而言的还要做冷端补偿。如果使用 ADS122U04IPWR 内置温度传感器可以先读内部温度值再根据冷端温度换算成对应的毫伏值加到实测毫伏上最后再查一次分度表才能得到真实温度。这个细节也是最容易写漏的我见过不少半路出家的方案直接把查表结果当成最终温度冬天和夏天能差出好几度。4. 校准、滤波与长期稳定性调优4.1 零点校准与增益校准再好的 ADC 芯片放到实际电路里也会引入额外的失调和增益误差。零点校准的方法很朴素把 ADC 的差分输入两个引脚短接在一起理论上输入电压为 0此时读到的码值就是系统零偏。把这个零偏码存到 PIC 的 EEPROM 里以后每次测量都先减掉这个值。注意不同 PGA 增益下的零偏不同所以最好针对常用的几档增益各做一次校准分别存值。增益校准的做法稍微繁琐一点。用一个精度很高的标准电阻替代传感器比如接一个 100.00Ω 的 0.01% 精密电阻读出码值之后反推实际增益系数。也可以用两只标准电阻一只在量程低点一只在量程高点算出一条两点校正直线的斜率和截距。校准系数同样存进 EEPROM。实际操作中有个经验校准时机最好选在系统上电稳定后进行至少等 ADC 通电 5 分钟内部基准完全稳定之后再做零点校准否则校准完的零偏值本身就不准。如果你做的是更高精度的工业仪表可以考虑多温度点标定。也就是在恒温箱里设置几个温度点比如 0℃、25℃、50℃、75℃、100℃每个点记录实际读数和参考温度计读数拟合一条多项式校正曲线。这个方法费时间但对于热电偶这类非线性传感器效果是立竿见影的能把整个量程内的误差压到很小的范围。4.2 数字滤波与抗干扰手段硬件 RC 滤波可以滤掉高频噪声但对工频干扰和低频随机噪声帮助有限固件里还要加一档数字滤波。最常见的就是滑动平均滤波维护一个长度为 N 的缓冲区每次取最新样本去掉最旧样本然后求平均。窗口长度 N 怎么选要看数据速率和要求的响应时间。比如数据速率 45SPS窗口取 16 次等效响应时间约 350ms对 HVAC 温度控制足够了。如果采样速率是 640SPS窗口可以取 64 次平滑效果很好响应时间也只要 100ms。另一种更激进的滤波是中值滤波专门对付脉冲型干扰比如继电器动作瞬间引起的跳变。中值滤波的原理是把连续 N 个采样值排序取中间值作为输出这样孤立的毛刺会被直接丢弃。缺点是计算量稍大8 位单片机跑排序要注意耗时窗口取 5 到 9 个点比较合适。我实际项目里的做法是两种叠加先做中值滤波剔除毛刺再做滑动平均平滑输出效果比单一滤波稳定得多。如果你遇到的是 50Hz 工频干扰最硬核的办法是把 ADC 数据速率配置成 20SPS 或者 45SPS。Δ-Σ ADC 的数字滤波器在特定数据速率下会对工频及其谐波有很深的陷波直接在源头上把干扰干掉了比在软件里费劲滤波高效得多。这也是为什么前期选型时不能只看分辨率数据速率档位的设计同样重要。4.3 低功耗与长期稳定性细节PIC18LF4515 运行在 3.3V、主频 8MHz 左右时功耗很低ADS122U04IPWR 正常模式功耗也只有几百微安这个量级整套系统做电池供电完全可行。但我发现很多人在用的时候忽略了一个细节ADS122U04IPWR 的恒流源在测量间隙应该及时关掉否则它会一直往外输出电流。PT100 比例测量里的恒流源电流一般设置成 500μA 或者 1mA虽然每路电流不大但长时间累积也是电池功耗的大头。固件里可以设计成测量时打开电流源测完立刻关闭功耗能降下一大截。长期稳定性方面定期自校准很有效。在系统不忙的时候比如每小时跑一次自检把 ADC 输入端切换到内部短接或者已知基准电压读取当前偏移量如果跟初始校准值的偏差超过设定阈值就自动更新零偏校准系数。这样即使电路老化或者环境温度变化引起漂移系统也能自我修正不至于越跑越偏。另外PCB 清洁度对长期稳定性影响非常大。前面提过三防漆这里再强调一下高湿高尘的 HVAC 环境里不做三防处理的板子过不了三个月就会开始出现湿度相关的漏电漂移。涂三防漆的时候注意避开传感器连接器和校准电位器区域否则会影响后续测试和校准。5. 常见故障与排查整理5.1 UART 通信异常怎么办整套系统最常见的故障就是 UART 完全不通PIC 发命令ADS122U04IPWR 没有任何响应。这个问题排查起来有个固定套路按顺序查。先用示波器或者逻辑分析仪量 PIC 的 TX 引脚看发送命令时有没有正确的波形如果 TX 有波形但 RX 完全安静那就查 ADC 的电源和复位引脚RESET 有没有被拉在一个不定电平上。UART 模式下 CS 和 MODE 的接法也要再确认一遍尤其是 MODE 如果被接成 SPI 模式芯片会死死等 SCLK 而忽略串口命令。波特率不匹配是最隐蔽的坑。ADS122U04IPWR 上电后的默认波特率可能跟你 MCU 配置不一样必须通过写寄存器切换过去。如果 MCU 端用的是 19200ADC 还停在 9600收到的全是乱码。调试时建议把波特率相关的配置写在固件最前面上电后立刻配置 ADC并且留一组可以反复发送的握手命令比如读 ID 寄存器确认链路通了再往下走。关于 CRC 值得多说一句。如果固件里的 CRC 算法跟芯片手册不一致会出现能收到数据但校验一直失败的情况看起来就像 UART 坏了。调试阶段可以先打印原始帧和 CRC跟手册里的示例对一遍确认生成多项式和初始值没有搞错。我踩过一次坑把 8 位 CRC 的初值写成了 0xFF实际上是 0x00结果总线上的数据帧被全部误判为损坏。5.2 读回数据跳动或者漂移如果通信正常了但数据跳动要分几个方向排查。先看 PGA 增益增益越高信号放大越多噪声也同样被放大所以做好屏蔽和滤波之前别急着把增益开到 128 倍。再看数据速率高速率下噪声底明显更高适当降低速率往往立竿见影。如果这些都没问题把电源纹波和参考电压也测一下基准不稳会让所有读数随着电源波动。数据漂移的问题大多出在参考电阻和传感器导线上。参考电阻温度系数太差温度一变阻值就变读数自然跟着飘。传感器使用两线制接法时导线电阻会串入测量回路导线随温度变化读数也会漂。解决办法就是前面说的RTD 用三线制或者四线制把导线电阻影响直接抵消掉。还有一个经常被忽略的因素是 ADC 输入前端的漏电流。如果你用了很大量程的电阻分压网络比如超过 100kΩ少量漏电流就会在电阻上产生可观的压降。这种情况下要么改用低阻值网络要么在 ADC 输入引脚附近铺保护环要么从根本上换用电流源激励的方案。5.3 采购与焊接细节最后再说几个跟芯片本身相关的经验。ADS122U04IPWR 的 PWR 后缀意味着 TSSOP-16 卷带包装这种封装焊接难度不算高但手工焊接时要注意助焊剂用量。TSSOP 引脚间距只有 0.65mm助焊剂残留如果没有清洗干净在高湿度环境里会成为漏电路径直接影响 24 位 ADC 的测量结果。有条件的话回流焊之后做一次超声波清洗效果比手工擦洗靠谱得多。采购方面这类工业级芯片建议走正规授权渠道并且留意批次。ADS122U04IPWR 后缀里有个字母 I表示工业温度范围如果买到民用级或者老批次库存性能指标尤其是温度漂移可能会不达标。芯片到货后先查一下丝印和生产周期再上电测一遍 ID 寄存器和内部温度传感器确认芯片没被翻新或者重新打标。这套动作看起来简单但能省掉后面一大半的调试时间。如果你手头项目对成本和复杂度更敏感也可以考虑 ADS1220 这类 SPI 接口芯片只是 MCU 那边要多占用几条 IO 线。只要系统对 UART 通信、CRC 校验和远程隔离有硬性要求ADS122U04IPWR 加 PIC18LF4515 这个组合无论是价格还是开发效率都是非常值得推荐的路线。实际用下来我最满意的是 UART 把整个时序逻辑简化了很多8 位单片机没有压力整机稳定跑了大半年也没出过幺蛾子。