2026/11/5 6:26:35

ADS122U04+STM32高精度温度采集方案:RTD与热电偶实战

ADS122U04+STM32高精度温度采集方案:RTD与热电偶实战 在做工业级温度采集的时候很多人第一个想法就是“传感器输出接单片机ADC读一下就好了”但真到了HVAC这种既有精度要求又有强干扰的现场这条路走不通。我在一套中央空调控制器项目里最初就是用了NTC加运放的方案结果被共模干扰和温漂折腾得够呛后来换成ADS122U04IPWR 加 STM32F405RG的组合测量链路才算真正稳定下来。这篇文章就把这套基于UART接口的24位ADC温度测量的完整做法包括硬件前端、固件流程、线性化标定和抗干扰处理整理出来供大家参考。这套方案适合做HVAC控制器、工业数据采集模块、设备状态监测的工程师。如果你正纠结“用内置ADC简单省事还是外挂ADC更稳”这个问题文中也会给出我的判断依据。1. 为什么是“ADS122U04IPWR STM32F405RG”温度测量不是查表那么简单1.1 ADS122U04IPWR 到底提供了什么ADS122U04IPWR 是 TI 的 24 位低功耗 Delta-Sigma ADC带 UART 接口。单看型号后缀里的 U04很多人容易把它和 SPI 接口的 ADS1220 弄混但 U04 最大的特点就是把 SPI 换成了串口。这个差别在工程上非常实用SPI 接线多、时序要求高而且单片机侧还要专门腾出引脚和中断UART 只要两根线任何一个串口都能接连 DMA 读取都好写得多。芯片内部集成的东西也不少可编程增益放大器 PGA常见档位 1~128 倍、两个可编程激励电流源 IDAC、内部基准、内部温度传感器还支持 2 个差分输入或 4 个单端输入实际接法取决于你的通道规划。这些资源放在一起意味着你不需要单独设计仪表放大器、恒流源和基准电路一颗芯片就把 RTD 和热电偶的前端全包了。对我个人来说最看重的其实是 IDAC。PT100 这类电阻型传感器需要激励电流之前用分立器件搭恒流源温度一变电流就飘。ADC 自带 IDAC 后激励源和测量通道在同一颗芯片里配合比例测量法整个测量链路对电源和温漂的敏感度都大幅下降。1.2 STM32F405RG 在里面扮演什么角色STM32F405RG 是一颗 Cortex-M4 内核的单片机主频 168 MHz资源非常充裕。很多人觉得测个温度用这么强的 MCU 有点浪费但 HVAC 控制器的实际需求远不止“读温度”这一件事要有 PID 调节阀输出要驱动压缩机变频逻辑要跑通信协议Modbus、BACnet 都可能还要带人机界面。在这种场景下F405 的 UART、DMA、FPU 和 Flash 容量反而是刚需。它的分工很明确ADC 芯片负责“把模拟量变成数字量”STM32 负责“把所有数字量变成有用的工程数据并做控制决策”。测量通路数据通过 UART 进来MCU 侧直接 DMA 搬运CPU 几乎不参与等待算温度、查表、滤波、PID 这些计算则放在 FPU 上跑整个系统响应速度很快。1.3 为什么不用 STM32 内置 ADCSTM32F405 内部其实就有 12 位 ADC采样率还不低那为什么还要外挂一颗如果你只是做一个 0.5°C 精度级别的室温检测内置 ADC 确实能用但工业和 HVAC 现场的要求通常更苛刻——温度分辨率要高、长期漂移要小、传感器要用 RTD 或热电偶而不是 NTC。内置 ADC 在这种场景下有几个硬伤12 位分辨率直接限制了电能分辨的温度粒度。接 PT100 时在 0~100°C 区间大约对应 38.5Ω 电阻变化12 位再加上参考噪声一个 LSB 的温度当量通常超过 0.1°C余量很小。输入范围有限内置 ADC 无法直接测毫伏级热电偶信号你必须加外部运放放大这又回到温漂和共模问题。通道间切换串扰明显多个传感器轮询时读数会跳。无内置 PGA 和激励源RTD 的前端电路会复杂得多。把这些问题加在一起你就会发现外挂一颗像 ADS122U04IPWR 这样的 ADC不只是提升位数而是把模拟前端的设计复杂度也一起解决了。2. 硬件前端设计RTD 与热电偶接入的关键细节2.1 PT100/PT1000 的三线制与四线制接法RTD 接法里我优先推荐四线制精度最高。两根线给 RTD 提供激励电流另外两根线测量电压因为测量回路里几乎没有电流所以导线电阻不影响读数。实际项目里如果受端子数量和线缆成本限制三线制就必须做导线电阻抵消最简单的工程做法是用两个 IDACIDAC1 电流流过一根励磁线进入 RTD然后从另一根励磁线返回IDAC2 输出等大电流同时流过一颗精密参考电阻 RREF测量差分电压时RTD 上的压降和 RREF 上的压降都包含了导线电阻的影响两路相减后导线电阻的影响就基本抵消了。具体到 ADS122U04IPWR通道规划可以参考这种模式一个差分通道接 RTD 或扩展信号线另一个差分通道接 RREF然后通过比例公式计算 RTD 阻值。比例公式的形式是R_temp (ADC_rtd_code / ADC_ref_code) × RREF这个公式的精髓在于只要 IDAC 是同源电流激励电流的漂移会同时影响分子和分母最后约掉。ADC 基准电压的漂移也不会影响比值。真正决定精度的只剩一颗电阻——RREF所以这颗电阻必须用低温度系数精密电阻至少 25 ppm/°C 起步预算够就上 10 ppm 甚至 5 ppm 的金属膜电阻。激励电流的选取也值得单独说。IDAC 大一点RTD 上的差分信号就大抗噪声能力强但功耗和自热也随之上升。PT100 在 100Ω 时IDAC 取 500 μA 的话信号只有 50 mV配合 PGA 倍数的提升可以解决取 1 mA 信号到 100 mV自热在大多数散热条件下约 0.02~0.1°C。我实测下来500 μA 是精度和自热的平衡点。如果你做的是耐热流体管道测量散热好可以放大到 1 mA如果传感器贴在小体积空气腔里还是用 250~500 μA 更稳。2.2 热电偶接入与冷端补偿热电偶和 RTD 是两类完全不同的传感器。K 型热电偶灵敏度大约 41 μV/°C信号极其微弱所以 PGA 倍数最好直接拉到 64 或 128。在内部基准 2.048V、24 位、PGA128 的情况下一个 LSB 对应的电压大约是 0.19 μV理论上温度分辨率可以干到 0.005°C 级别。当然这是理想值实际噪声会把有效位数拉下来但至少信号的动态范围是够的。热电偶真正的麻烦在冷端补偿。热电偶输出的电动势对应的是热端和冷端之间的温度差你必须知道冷端温度才能算出真实温度。冷端补偿的做法分两步一是测量冷端温度二是把冷端温度换算成等效电动势加回去。冷端温度怎么测可以用一颗 NTC 或者 DS18B20 放在热电偶端子附近也可以用 ADS122U04IPWR 内部温度传感器。内部温度传感器省事但精度一般只有 ±2°C 量级对冷端补偿来说会导致整体误差变大。我的做法是在主板上靠近端子位置放一颗高精度 NTC经过三线或四点校正后冷端误差控制在 ±0.3°C 左右对于 K 型热电偶来说已经能保证系统整体精度在 ±1°C 以内。信号通路设计上要注意热电偶的输入共模电压不能随便接。很多人直接把热电偶负极接地这在有 PGA 的 ADC 上容易出问题——输入共模太靠近负电源的时候PGA 内部偏置点会漂移导致增益失真。稳妥的做法是给每个模拟输入提供一个偏置电阻网络把共模电压抬到接近电源中点比如用两颗 100 kΩ 电阻分压把 AIN 输入偏置到 (AVDDAVSS)/2 附近。2.3 输入滤波与保护电路温度测量虽然是低频信号但工业现场的干扰是高频为主的所以前端必须做低通滤波。每个模拟输入串联 1 kΩ 电阻并到差分端并联一个 10 nF 电容可以构成简单的 RC 低通滤波器截止频率大约 8 kHz 级别用来滤掉变频器和开关电源的骚扰。不过这里有个坑Sigma-Delta ADC 的输入端不是纯电阻而是开关电容输入阻抗是动态变化的。如果你把串联电阻加得太大ADC 内部采样电容在转换周期内充不满测量结果就会出现和输入电阻相关的偏置误差。所以串联电阻一般控制在几百欧到 2 kΩ 之间再配合稍微延长一些的采样设置。保护电路方面开关电源、继电器触点、电机绕组引入的瞬态浪涌能直接打坏 ADC所以输入端需要加钳位。比较常见的做法是模拟输入串接限流电阻然后对电源和地各接一个低漏电流的 TVS 管或者用 BAV199 这类低漏二极管对做钳位。防止大电流灌进芯片的同时保证常温下漏电流不引入可感知的测量误差。3. 固件实现UART 通信、配置流程与数据解析3.1 ADS122U04 的 UART 通信基础ADS122U04IPWR 的通信方式是标准的 UART 帧格式主机是 STM32从机是 ADC。使用 UART 的好处是两线就能跑数据速率不需要太高工程上常用 9600 到 115200 bps 都能正常通信具体波特率按照数据手册要求配置。每次通信包含一个命令字节和相应的数据字节读取转换结果时芯片会把状态信息和 24 位 ADC 数据组成数据帧发回来。具体帧大小和字节序建议对照手册时序图确认我在这里重点讲逻辑框架因为不同固件版本对命令封装可能有差异。通信配置上有一个工程细节值得注意UART 数据位长度、校验位和停止位最好和芯片一致。ADS122U04 支持无校验模式也可以用偶校验增强抗干扰但一旦开启MCU 侧也必须同步配置否则数据完全对不上。我建议在 Modbus 和主从控制较多的 HVAC 项目里开启校验虽然每帧多一个 bit 开销但现场总线出现毛刺时能提前拦截一部分坏帧。3.2 初始化流程上电、复位、寄存器配置ADC 初始化时序非常重要尤其是上电后的时序。直接贴一段我常用的初始化逻辑以 STM32 HAL 库为例uint8_t cmd_reset CMD_RESET; // 复位命令具体数值见数据手册 HAL_UART_Transmit(huart4, cmd_reset, 1, 100); HAL_Delay(5); uint8_t cfg[3] {0x0?}, ; // 配置寄存器内容按你的通道、PGA、IDAC、误差设置决定 HAL_UART_Transmit(huart4, cfg, sizeof(cfg), 100); // 单次转换模式发启动命令 uint8_t cmd_start CMD_START; HAL_UART_Transmit(huart4, cmd_start, 1, 100);这几步看着简单但有一个讲究上电后先等电源稳定再发复位命令。ADS122U04 的 AVDD 如果直接从 DC-DC 输出取电上电瞬间会有振铃此时发复位和配置命令很容易丢失。我的做法是在硬件上加一个 RC 延时电路控制 EN或者干脆在软件里把上电后的首个延时做到 50~100 ms稳定之后再初始化。寄存器配置要说清楚几个重点PGA 增益RTD 用 4~16 倍足够热电偶用 64~128 倍。数据速率默认速率低噪声好但 HVAC 扫描多个通道时又希望快点实际选 20 SPS 到 100 SPS 比较合理具体看噪声指标。激励电流RTD 场景选 500 μA 量级热电偶场景如果不需要 IDAC就把它关掉避免自热和功耗浪费。转换模式我喜欢用单次转换加轮询的模式每个通道读一次就切换方便做多传感器扫描连续转换模式吞吐高但要处理数据粘包复杂度更高。3.3 转换结果的数据处理与换算读取数据时STM32 通过 UART 发读取命令从 ADS122U04 返回的是一段数据帧其中包含状态位和 24 位转换结果。状态位里通常含有转换状态、超范围标志等建议在代码里先检查再使用防止异常数据进入算法。24 位 ADC 数据是按二进制补码存储的需要先扩成有符号 32 位整数再按下面的公式换成电压int32_t code (int32_t)((raw[0] 16) | (raw[1] 8) | raw[2]); if (code 0x800000) { code | 0xFF000000; } // 24位全量程对应 ±2.048V内部基准 float voltage (float)code / 8388607.0f * 2.048f / (float)PGA;如果是 RTD 比例测量那就不需要关心绝对电压直接把 RTD 通道的 code 和 RREF 通道的 code 做比例运算算出来的电阻值再查表得到温度。多通道轮询时要注意切换到新的输入通道后第一次转换结果里面带有前一个通道的残余影响应该丢弃第一帧数据从第二帧开始采。这个细节在数据手册的建立时间参数里有写但很多人不看实测会发现在温度突变时读数出现一个明显的“拖尾”就是这个原因。3.4 用 DMA 减轻 CPU 负担既然 STM32F405 是一颗主频很高的 MCU数据接收就不该用阻塞式等待。我建议直接用 UART 空闲中断 DMA 的方式接收数据帧HAL_UARTEx_ReceiveToIdle_DMA(huart4, rx_buf, RX_BUF_SIZE);当一帧数据接收结束后产生空闲中断在回调里判断帧长度、解析数据。这样主循环可以专心做滤波和控制计算不需要不断轮询串口。对ADS122U04这种固定长度的数据帧来说这个方法尤其合适整帧直接进 DMA 缓冲区拷贝一次就能解析。我实际跑下来的情况是ADS122U04 单次转换的吞吐量在低压状态可以达到极高的速率虽然实际项目中 20~100 SPS 的采样率不算高但 DMA 的方式依然值得用因为 HVAC 整机里通常会挂多路传感器、多路开关量和多路通信任务CPU 空闲时间永远不够用。4. 线性化与标定从 ADC 数值到真实温度4.1 RTD 电阻到温度的换算PT100 的温度-电阻关系不是完全线性的。在 0~100°C 区间平均每摄氏度大约变化 0.385 Ω但用这个斜率直接算全量程误差会到零点几摄氏度对 HVAC 控制器这种目标精度在 ±0.2°C 的系统来说不够。所以工程上一般用查表法或者用 Callendar-Van Dusen 方程。Callendar-Van Dusen 方程是这样的R(t) R0 × [1 A×t B×t²]t 0°C R(t) R0 × [1 A×t B×t² C×(t-100)×t³]t 0°C其中 A3.9083×10⁻³B-5.775×10⁻⁷C-4.183×10⁻¹²R0 是 0°C 时的标称阻值PT100 就是 100Ω。从 ADC 算出的阻值反解温度时这个方程不能直接求逆需要用牛顿迭代法。我一般先猜一个初始温度比如 25°C然后不断迭代几次循环就能收敛到 0.001°C 精度。在 STM32F405 的 FPU 上跑这个计算毫无压力即使是多通道 RTD 轮询也完全来得及。如果嫌迭代麻烦也可以把 PT100 的分度表做成 1°C 间隔的查找表再配合线性插值。表越大精度越高但 Flash 占用也会增加。对存储容量不敏感的 F405 来说放一个 0~200°C 的表格没问题。工业测量场景下我两者都用查找表用于快速出值牛顿迭代用于对特殊温度点复核。4.2 热电偶的查表与冷端补偿计算热电偶的电压-温度关系用多项式表达比较繁琐工程上更常用分度表。比如 K 型热电偶一张 -50°C 到 500°C 的分度表每 1°C 一个点表格本身很小查表加线性插值的精度完全可以满足家用和轻工业 HVAC 需求。前面说过热电偶测的是温差所以冷端补偿的算法要严格按下面的顺序从 ADC 读取热电势 Vmeas。读取冷端温度 TrefNTC 或板载传感器。查表或多项式求出冷端温度对应的补偿电压 Vcom。真实热端电动势 E Vmeas Vcom。再用 E 反查温度。这个顺序看着简单但冷端温度某些时候变化很快而 ADC 通道是轮询的如果你先读热电偶电压等几个通道扫完再读冷端温度冷端已经变了好几度补偿结果就会偏差。所以我的经验是热电偶和冷端温度的读取时间间隔必须控制在极短范围内最好在同一个采样循环里连续完成或者使用更高频率的冷端采样。4.3 标定实操零点、满度和重复性不管 RTD 还是热电偶ADC 本身的失调和增益误差都会引入最终温度误差。芯片在出厂时有校准但装配到板子上后参考电阻、PCB 走线、冷端传感器的安装误差都会改变实际特性所以整机标定是躲不过的。我的标定流程是零点标定把传感器探头放到恒温槽或者冰点槽里让它稳定 15 分钟以上记录 ADC 值算出零点偏移系数。满度标定在 60°C 或 100°C 的干体炉里重复同样过程算出增益修正系数。中点多点验证至少测 3 个中间温度点检查线性度误差是否在指标内。修正系数保存到 STM32 内部 Flash 或者外挂 EEPROM 里每次上电加载。如果系统有多块板子每块板的标定系数可能都不同所以生产流程里最好为每台设备单独烧录一套校准参数。这个“组装之后必须标定”的工序很容易被开发阶段忽略但它直接影响最终交付的精度真正做了量产调试的工程师都懂这一步的分量。5. HVAC 和工业现场的干扰怎么扛5.1 干扰来源变频器、继电器和开关电源HVAC 系统里产生干扰的东西太多了变频压缩机、风机电机启停、电磁阀继电器、开关电源的高频纹波。这些干扰可以分几类共模干扰电机地线和控制板地线之间的电压差通过传感器线缆传导到 ADC 输入端。差模干扰导线耦合的磁场和电场在两根信号线之间产生压差。电源纹波开关频率几十 kHz 的高频噪声灌进 AVDD直接影响内部基准和 PGA。其中共模干扰是最隐蔽的。信号线往往很长一跟到电机旁你的地和电机的地之间就可能出现几十伏的瞬态电压两个输入引脚对地的共模电压都在跳。Sigma-Delta ADC 本身对共模有抑制作用但这个抑制能力是有限度的超出范围后转换结果会直接出现通道串扰或偏置突变。5.2 PCB 布局与滤波的实战取舍PCB 布局可能是成本最低但效果最明显的抗干扰手段。几个关键原则模拟区域和数字区域尽量分开AVDD 和 DVDD 分别用 LDO 供电两个 LDO 的输出之间加磁珠隔离。ADC 放在靠近传感器接线端子一侧模拟走线要短而宽不要在下方走数字信号线。RTD 和热电偶的输入走线做成差分对两线紧贴走减少环路面积。环路面积越大电磁感应进来的噪声越多。传感器线缆在外部用屏蔽双绞线屏蔽层单端接地通常是在控制板端接地避免形成地环路电流。在滤波方面除了输入端 RC 滤波器UART 信号线也建议加小型共模电感。之前遇到过一种情况温度读数正常但串口数据偶尔出错用逻辑分析仪看才发现是 UART 线上被灌入了变频器的开关噪声本来稳定的串口帧出现了毛刺。加一个共模扼流圈和 100 pF 电容问题就消失了。5.3 系统隔离与电源设计如果控制板直接驱动压缩机或大功率继电器信号地和功率地之间只靠铺铜连接是不够的。我的建议是温度测量通道和主控制回路做电气隔离。方法上可以做数字侧隔离用数字隔离器把 UART 信号隔开ADC 的电源也单独用隔离式 DC-DC 供电。这样即使功率部分有瞬间高压干扰也不会通过模拟地串进测量链路。如果不做隔离至少要保证单点接地模拟地和数字地在 ADC 芯片下方一点连接不要多点搭接到功率地。同时 AVDD 的 LDO 输入输出都要加足够容量的滤波电容通常输入 10 μF输出 1 μF 加 100 nF。电源纹波这个东西在万用表上不好测但在 ADC 的转换结果里看得清清楚楚——读数最后几位一直抖多半是电源惹的祸。6. 实测数据与踩坑记录6.1 实测定点效果我在这套组合上跑过一轮比较完整的测试传感器用的是 PT100 铂电阻激励电流 500 μAPGA 16 倍数据速率 40 SPS参考电阻 RREF 用 25 ppm/°C 精密电阻。分别在 0°C 冰水混合物、25°C 室温、60°C 恒温箱里测了长时间稳定性典型的结果如下环境温度读数均值最大波动备注0°C0.02°C±0.05°C恒温后稳定25°C25.06°C±0.08°C室温波动导致60°C60.01°C±0.04°C恒温箱稳定后这个水平对 HVAC 来说相当充裕。热电偶通道用 K 型热电偶在 100°C 干体炉里校验全量程误差大约 ±1.0°C瓶颈主要出在冷端补偿的 NTC 精度上如果换更高精度的冷端传感器还能进一步压缩。6.2 几个真实的坑这里面有几个坑完全是“不实测根本发现不了”的类型值得单独说。第一个是 IDAC 自热的问题。最开始我把激励电流设成 1.5 mA 想提高信号幅度结果发现在空气流通差的温度传感器里读数比实际温度偏高约 0.2°C。刚开始还以为是标定问题后来把电流降到 500 μA同样的环境下读数立刻降回来。自热效应不是你可以事后修正的因为它和传感器所在介质的导热系数相关修正系数本身就会漂。所以选激励电流宁小勿大信号幅度不够就靠 PGA 去补。第二个是输入共模电压。刚开始做热电偶接入时我把负极直接接到了系统地结果发现读数和调试台上差别很大尤其在增益倍数高的时候。后来仔细看了一下 PGA 的输入范围才明白共模电压太低会导致内部偏置失效。解决办法就是前面提过的用偏置电阻把共模抬高改完之后读数立刻正常。第三个是参考电阻的温漂。这是最容易忽略但影响最狠的。比例测量法能把 ADC 的参考和激励电流漂移都抵消掉但 RREF 自身的温漂抵消不了。如果你用了普通厚膜电阻当 RREF环境温度从 25°C 变到 50°C阻值可能漂几十 ppm对 0.1°C 精度目标来说是不可接受的。所以 RREF 一定要选精密低漂电阻并且尽量远离功率原件和发热元件。第四个是上电顺序。ADS122U04 如果在 AVDD 还没有完全稳定时收到配置命令不是报错而是直接忽略之后寄存器处于默认状态你读到的数据全是按默认增益和通道来的表现就是“数据没变化但就是不对”。这个现象排查起来很头疼因为你反复发命令都觉得没问题其实是芯片还没醒。解决就是上电后延时 100 ms 再复位然后再写配置。6.3 这套方案还能往哪里扩展这套硬件和固件框架的扩展性比想象中好。同样的电路把 RTD 通道去掉其中一路就可以直接接入 NTC、热敏电阻或者 0~10V 传感器的分压信号只是 PGA 和换算公式要改一下。ADC 丰富的通道数也支持同时接多路 PT100 和多路热电偶混合测量配合轮询机制做多区温控很合适。软件层面F405 上的 FPU 跑 PID 和滤波算法非常顺手后续如果要加 Modbus 从站或者云网关直接用这颗 MCU 的 UART/USART 资源就够不需要额外换主控。整套方案从做样板到小批量试产大概两周就能跑通还是很值得投入的。如果觉得精度还不够下一步可以做两点一是把内部基准换成外置精密基准进一步压低参考温漂二是给每个传感器接入前做独立校准系数并写入 EEPROM让系统支持“现场换探头不重新标定”。这两件事做完这套方案基本可以往医疗级和实验室级精度靠了。