
工业现场的温度测量看起来是个再普通不过的需求但真正做过 HVAC 控制柜或者工业数据采集终端的人都知道这里面坑不少。PT100、PT1000、热电偶、热敏电阻传感器类型五花八门信号幅度从几十微伏到几百毫伏不等现场还有变频器、接触器、继电器这些干扰源在旁边嗡嗡作响。用 STM32 自带的 12 位 ADC 直接采精度不够温漂还大根本扛不住工业级 ±0.5°C 甚至 ±0.1°C 的要求。所以外挂一颗高精度 ΔΣ 型 ADC 几乎是标配方案而 ADS122U04IPWR 就是德州仪器在这个细分场景里非常能打的一颗芯片——24 位分辨率、内置 PGA、双匹配电流源、UART 接口配合 STM32F217ZG 这种带 FPU 和丰富外设的 Cortex-M3能搭出一套相当扎实的温度采集系统。这篇内容我打算把整套方案从头到尾拆一遍。不是那种“贴个原理图就完事”的流水账而是把选型逻辑、寄存器配置、采样时序、抗干扰处理、校准方法这些真正影响测量结果的东西讲透。如果你正在做工业温度变送器、HVAC 楼宇自控、冷库监控、锅炉温度采集这类项目或者单纯想搞明白 24 位 ADC 到底怎么用才能发挥出它应有的性能那接下来的内容应该能帮你少走不少弯路。1. 为什么偏偏是 ADS122U04 加 STM32F217ZG 这个组合1.1 先搞清楚温度测量对 ADC 的真实需求很多人选 ADC 的时候第一反应是“位数越高越好”24 位听起来就比 16 位厉害。但实际选型要看的是有效分辨率和噪声-free 分辨率而不是标称位数。举个具体的例子假设用 PT100 做 -50°C 到 150°C 的测量PT100 在这个区间的阻值大约是 80.31Ω 到 157.33Ω对应的灵敏度大约是 0.385Ω/°C。如果激励电流是 500μA那么每摄氏度产生的电压变化只有 0.385 × 500μA ≈ 192.5μV。想要做到 0.1°C 的分辨率ADC 需要能分辨大约 19μV 的电压变化。这个量级STM32F217 内置的 12 位 ADC 在 3.3V 参考下 LSB 是 806μV差了四十多倍完全没戏。ADS122U04 在增益为 1、数据率 20SPS、使用内部 2.048V 参考时的 RMS 噪声大约在 1.5μV 左右峰峰值噪声约 10μV折算下来有效分辨率能到 20 位以上。这意味着上面那个 19μV 的需求它能轻松覆盖甚至还有余量去做更精细的分辨。这就是为什么工业温度测量几乎清一色用 ΔΣ ADC 的原因——不是追求标称的 24 位而是追求在低速采样下极低的噪声底。另外还要考虑共模电压范围和输入阻抗。PT100 在 500μA 激励下满量程也就 80mV 左右信号很小容易受干扰。ADS122U04 内置的 PGA 可以把这个小信号放大 1 到 128 倍把有效信号抬到接近参考电压的水平再量化这样 ADC 的量化噪声相对于信号就被压下去了。这是外置运放加普通 ADC 方案很难做到的性价比。1.2 ADS122U04IPWR 的关键特性拆解这颗芯片的型号后缀 IPWR 表示工业级温度范围-40°C 到 125°C和 TSSOP-16 封装。它的核心资源包括24 位 ΔΣ 调制器输出速率 5SPS 到 2000SPS 可配内置 PGA增益 1/2/4/8/16/32/64/128 可选两个匹配电流源10μA 到 1.5mA专门为 RTD 激励设计内部 2.048V 参考温漂典型值 5ppm/°C也可以外接参考UART 接口兼容 2 线制最高 2Mbps内部温度传感器用于冷端补偿或板级温度监测50/60Hz 同步抑制在 20SPS 时同时抑制两种工频干扰这里要特别说一下双匹配电流源这个设计。用 RTD 测温时激励电流的精度和温漂直接影响测量结果。如果用外部电流源你得额外做恒流电路还要保证两路电流匹配。ADS122U04 内部集成了两路可编程电流源可以配置成从同一基准派生匹配度很好。更关键的是它支持比例式测量——用同一路电流源激励 RTD 和参考电阻ADC 测量两者的比值这样电流源的绝对精度和温漂就被抵消掉了。这是 RTD 测量里最经典也最有效的抗漂移手段。1.3 STM32F217ZG 在这个方案里扮演什么角色STM32F217ZG 是 ST 的 Cortex-M3 旗舰型号之一168MHz 主频、1MB Flash、192KB SRAM、带 FPU、以太网 MAC、USB OTG、多个 USART/SPI/I2C。在这个温度采集方案里它的主要职责是通过 UART 与 ADS122U04 通信配置寄存器、读取转换结果运行温度换算算法包括 RTD 线性化、冷端补偿、多点校准管理多通道切换如果系统需要测多个温度点通过外部多路复用器切换处理通信和上位机交互以太网、USB 或者 RS485 上传数据实现控制逻辑比如 HVAC 里的 PID 调节、报警判断选 F217 而不是 F103 或者 F407主要是看中它的以太网 MAC 和更大的 SRAM。工业温度采集终端往往需要同时跑协议栈、数据缓冲和算法192KB SRAM 比 F103 的 64KB 宽裕太多。而且 F217 的 FPU 在做浮点温度换算时能省不少时间虽然温度换算本身计算量不大但多通道轮询时累积起来还是有差别的。注意ADS122U04 的 UART 是 2 线制只有 TX 和 RX没有硬件流控。STM32 这边用普通 USART 就行但要注意波特率匹配和帧格式配置后面会详细讲。2. 硬件设计里那些容易翻车的地方2.1 RTD 接口电路三线制和四线制怎么选PT100 的接线方式直接决定了测量精度。两线制最简单但导线电阻会直接叠加到测量结果里。假设导线电阻 0.5Ω折算成温度误差就是 0.5 / 0.385 ≈ 1.3°C这在工业场景里完全不可接受。所以实际项目里基本只用三线制或四线制。三线制是工业现场最常用的方案。它假设三根导线电阻相同通过两次测量或者配合匹配电流源来抵消导线电阻。ADS122U04 的双电流源正好支持这种接法IDAC1 从 AIN0 流出经过导线 1 到 RTD再从 RTD 经过导线 2 回到 AIN1IDAC2 从 AIN2 流出经过导线 3 到 RTD 的低端。这样两根电流源导线上的压降在差分测量中被抵消只剩下 RTD 本身的压降和回路线的影响。四线制精度最高用两根线通激励电流另外两根线做高阻抗电压检测导线电阻完全不影响测量。但四线制需要四根线现场布线成本高一般只用在实验室或者对精度要求极高的场合。实际项目里我的建议是HVAC 和一般工业场合用三线制就够了配合 ADS122U04 的双匹配电流源精度能做到 ±0.1°C 以内。四线制留给校准设备或者高精度计量场合。2.2 参考电阻的选择和布局比例式测量的核心是参考电阻。ADC 测量的是 RTD 压降与参考电阻压降的比值所以参考电阻的精度和温漂直接决定系统精度。这里有几个硬性要求初始精度至少 0.1%最好 0.05%温漂低于 10ppm/°C最好 5ppm/°C阻值要匹配电流源和 PGA 的输入范围阻值怎么算假设用 500μA 激励电流RTD 在最高温 150°C 时阻值 157.33Ω压降约 78.7mV。参考电阻上的压降应该接近但不超过 ADC 的满量程同时考虑 PGA 增益。如果 PGA 设为 8参考电压 2.048V那么 ADC 输入满量程是 2.048 / 8 256mV。参考电阻压降应该在这个范围内取 500μA × Rref ≈ 200mV则 Rref ≈ 400Ω。实际选 390Ω 或 402Ω 的标准值都可以。布局上参考电阻要靠近 ADC 的 REF 引脚走线短而粗远离发热元件。如果参考电阻本身发热它的阻值会漂整个测量就废了。我见过一个项目把参考电阻放在电源芯片旁边结果电源一加载温度测量就偏了 2°C查了半天才发现是参考电阻被烤热了。2.3 电源和地去耦处理ADS122U04 是模拟和数字混合芯片电源处理不好噪声直接进测量结果。几个关键点AVDD 和 DVDD 分开供电或者至少用磁珠隔离每个电源引脚配 100nF 加 1μF 去耦100nF 尽量靠近引脚模拟地和数字地单点连接通常在芯片下方UART 信号线如果走线长加串联电阻和 TVS还有一点容易被忽略ADS122U04 的 UART 接口在空闲时应该保持高电平。如果 STM32 的 TX 引脚在初始化前是浮空的ADS122U04 可能收到乱码。解决办法是在 STM32 TX 上加一个上拉电阻或者在初始化时先把 TX 配成高电平输出再切换成 UART 功能。3. 寄存器配置把芯片调到想要的工作状态3.1 ADS122U04 的寄存器映射ADS122U04 有四个配置寄存器通过 UART 命令访问。命令格式是55h 寄存器地址 数据。比如写配置寄存器 0发送 0x55 0x00 0xXX。读寄存器则是发送 0x25 0x00然后读回一个字节。四个寄存器的功能大致如下寄存器地址关键位作用Config000hMUX[3:0], GAIN[2:0], PGA_BYPASS输入多路选择、增益、PGA 旁路Config101hDR[2:0], MODE[1:0], CM数据率、转换模式、连续/单次Config202hVREF[1:0], FIR[1:0], PSW, IDAC[2:0]参考选择、滤波器、电流源Config303hI1MUX[2:0], I2MUX[2:0], DRDYM电流源输出引脚、DRDY 模式配置顺序很重要先配 Config2 的参考和电流源再配 Config0 的输入和增益最后配 Config1 启动转换。如果顺序反了可能在电流源还没稳定时就开始转换前几次结果会飘。3.2 针对 PT100 三线制的具体配置假设我们用 AIN0/AIN1 做差分输入AIN2 接第二路电流源内部 2.048V 参考PGA 增益 8数据率 20SPS连续转换模式。配置值如下Config0MUX 设为 0000AIN0 正AIN1 负GAIN 设为 011增益 8PGA 不旁路。二进制 0000_0110 0x06。Config1DR 设为 00020SPSMODE 设为 00连续转换CM 设为 0单次转换后不关断。二进制 0000_0000 0x00。Config2VREF 设为 00内部 2.048VFIR 设为 00无滤波PSW 设为 0自动IDAC 设为 100500μA。二进制 0000_0100 0x04。Config3I1MUX 设为 100AIN0I2MUX 设为 101AIN2DRDYM 设为 0。二进制 1001_0100 0x94。对应的 STM32 发送序列uint8_t cfg0[] {0x55, 0x00, 0x06}; uint8_t cfg1[] {0x55, 0x01, 0x00}; uint8_t cfg2[] {0x55, 0x02, 0x04}; uint8_t cfg3[] {0x55, 0x03, 0x94}; HAL_UART_Transmit(huart1, cfg2, 3, 100); // 先配参考和电流源 HAL_Delay(1); HAL_UART_Transmit(huart1, cfg0, 3, 100); // 再配输入和增益 HAL_Delay(1); HAL_UART_Transmit(huart1, cfg3, 3, 100); // 配电流源输出 HAL_Delay(1); HAL_UART_Transmit(huart1, cfg1, 3, 100); // 最后启动转换提示每次写寄存器后建议加 1ms 延时让内部电路稳定。虽然数据手册没强制要求但实测下来不加延时偶尔会出现配置不生效的情况。3.3 数据读取的时序处理ADS122U04 在连续转换模式下每次转换完成会把 DRDY 引脚拉低。STM32 可以用外部中断检测 DRDY 下降沿然后在中断里读取数据。读数据的命令是0x10发送后芯片会返回 3 个字节24 位结果MSB 在前。这里有个细节读数据命令发送后要等芯片把数据准备好再读 UART。如果 STM32 用 HAL_UART_Receive 阻塞读取超时时间要设够。20SPS 时转换周期 50ms但读数据本身很快通常几毫秒内就能收到。建议超时设 10ms。void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) { if (GPIO_Pin DRDY_Pin) { uint8_t cmd 0x10; uint8_t rx[3]; HAL_UART_Transmit(huart1, cmd, 1, 10); HAL_UART_Receive(huart1, rx, 3, 10); int32_t raw (rx[0] 16) | (rx[1] 8) | rx[2]; if (raw 0x800000) raw | 0xFF000000; // 符号扩展 // 后续处理 } }注意符号扩展这一步。24 位有符号数的范围是 -8388608 到 8388607如果直接当 32 位用负数会出错。上面这段代码把 bit23 复制到高 8 位得到正确的 32 位有符号值。4. 从原始码值到温度换算和校准的完整链路4.1 比例式测量的数学推导比例式测量的核心思想是ADC 码值正比于输入电压与参考电压的比值而输入电压和参考电压都由同一个电流源产生所以电流源的大小被约掉了。设激励电流为 IRTD 阻值为 Rrtd参考电阻为 RrefPGA 增益为 GADC 满量程码值为 2^23 - 1 8388607。则RTD 压降Vrtd I × Rrtd参考压降Vref I × RrefADC 码值Code (Vrtd × G / Vref_adc) × 8388607但这里要注意ADS122U04 的参考电压是外部参考引脚上的电压如果参考电阻接在 REFP/REFN 上那么 Vref_adc I × Rref。代入得Code (I × Rrtd × G) / (I × Rref) × 8388607 (Rrtd × G / Rref) × 8388607电流 I 被完全约掉。所以Rrtd (Code × Rref) / (G × 8388607)这个公式就是比例式测量的精髓。只要 Rref 精确电流源的漂移完全不影响结果。4.2 PT100 阻值到温度的换算拿到 Rrtd 之后要换算成温度。PT100 的阻温关系在 -200°C 到 0°C 和 0°C 到 850°C 用不同的公式。工业上最常用的是Callendar-Van Dusen 方程0°C 以上R(t) R0 × (1 A×t B×t²)其中 R0 100ΩA 3.9083×10⁻³B -5.775×10⁻⁷。反解温度需要解二次方程t (-A sqrt(A² - 4B(1 - Rrtd/R0))) / (2B)这个公式在 STM32F217 上用 FPU 算一次大约几微秒完全不是瓶颈。如果嫌 sqrt 麻烦也可以用查表加线性插值但精度会差一些。float rtd_to_temp(float rtd) { const float R0 100.0f; const float A 3.9083e-3f; const float B -5.775e-7f; float ratio rtd / R0 - 1.0f; float disc A * A - 4.0f * B * ratio; if (disc 0) return -999.0f; // 错误标志 return (-A sqrtf(disc)) / (2.0f * B); }4.3 实际校准为什么理论公式还不够理论公式假设 PT100 是理想器件但实际传感器的 R0 有公差Class A 是 ±0.06ΩClass B 是 ±0.12Ω而且长期使用后会有漂移。所以工业产品出厂前都要做校准。校准方法通常有两种单点校准在 0°C冰水混合物下测一次调整 R0 的偏移量。简单但只能修正零点误差。多点校准在 0°C、50°C、100°C 三个点测量拟合出实际的 A、B 系数。精度更高但需要恒温槽设备。我在实际项目里的做法是先用单点校准修正 R0再用两点校准修正增益。具体来说在 0°C 和 100°C 各测一次算出实际的 R0 和平均斜率然后微调 A 系数。这样不需要昂贵的恒温设备用冰水浴和沸水就能做精度能到 ±0.1°C 以内。校准参数存在 STM32 的 Flash 里每次上电加载。建议存两份一份备份防止 Flash 写入失败导致参数丢失。5. 抗干扰和稳定性工业现场的实战经验5.1 工频干扰的抑制策略工业现场最大的干扰源就是 50Hz 工频。ADS122U04 在 20SPS 数据率下数字滤波器对 50Hz 和 60Hz 都有很强的抑制这是它的一大优势。但前提是数据率必须精确设置为 20SPS如果设成 21SPS 或者 19SPS抑制效果就大打折扣。另外输入端的 RC 滤波也很重要。在 AIN0/AIN1 和 AIN2/AIN3 之间各加一个差分电容100nF每个输入端对地加一个共模电容10nF再串一个小电阻100Ω。截止频率算一下差分滤波的 -3dB 频率是 1/(2π×2×100×100nF) ≈ 8kHz对工频没什么用但能滤掉高频噪声。真正对付工频还是靠 ADC 内部的数字滤波。如果现场干扰特别严重可以考虑在软件里做滑动平均。20SPS 下取 10 个点平均等效数据率 2SPS噪声能再降 3 倍左右。但响应速度会变慢适合温度这种慢变量。5.2 多通道切换的注意事项如果系统要测多个温度点通常用外部多路复用器比如 CD4051 或者 ADG708切换。这里有几个坑切换后要等稳定再采样。多路复用器的导通电阻和输入电容会形成 RC 延迟切换后至少等 1ms 再启动转换。未选中的通道要接地或接参考不能浮空否则会通过寄生电容耦合干扰。激励电流源也要跟着切换。如果电流源一直开着但通道切走了RTD 上没电流测出来是零。我一般用CD4051 加三线制 RTD的方案每个通道配一个参考电阻通过模拟开关切换。这样每个通道的校准参数可以独立存储避免通道间串扰。5.3 自热效应和测量电流的权衡RTD 测量有个绕不开的矛盾电流越大信号越强但自热越严重。PT100 在 1mA 下的自热大约 0.1°C 到 0.5°C取决于封装和安装方式。在静止空气中自热更明显。ADS122U04 的电流源可以设到 10μA但信号会小到几十微伏对噪声要求更高。我的经验是一般工业场合用 500μA 比较平衡自热在 0.05°C 左右信号幅度也够。如果是高精度计量场合用 100μA 甚至更低配合更长的平均时间。还有一个技巧间歇激励。不是一直开着电流源而是测量前开测完关。这样自热时间短平均功耗也低。ADS122U04 支持通过命令控制电流源开关可以在单次转换模式下实现。6. 常见问题排查从现象到根因6.1 读数跳动大或者不稳定这是最常见的问题。排查顺序应该是先看电源纹波。用示波器测 AVDD如果纹波超过 10mV先解决电源。检查参考电阻。如果参考电阻温漂大或者布局不好读数会随环境温度漂。确认数据率设置。如果设成了 2000SPS噪声会大很多温度测量没必要用这么高的速率。检查输入滤波。没有 RC 滤波的话高频噪声会混叠进来。看 DRDY 时序。如果读数据时机不对可能读到旧数据或者不完整的数据。我遇到过一个案例读数每隔几秒跳一次幅度大约 0.5°C。查了半天发现是旁边继电器动作时通过电源耦合进来的。解决办法是在继电器线圈上加续流二极管同时在 ADC 电源上加 LC 滤波。6.2 读数始终偏一个固定值如果偏差是固定的通常是校准问题或者参考电阻阻值不对。先确认 Rref 的实际阻值用高精度万用表测然后检查校准参数是否正确加载。还有一种可能是PGA 增益设错了比如实际设的是 8 但代码里按 4 算结果会差一倍。6.3 UART 通信失败ADS122U04 的 UART 是 2 线制配置起来比 SPI 容易出问题。常见原因波特率不匹配。ADS122U04 默认波特率是 115200但可以通过命令改。确认两边一致。TX/RX 接反。这个低级错误其实很常见尤其是自己画板子的时候。空闲电平不对。前面说过UART 空闲应该是高电平如果 STM32 引脚配置成开漏没上拉就会通信失败。命令格式错误。写寄存器是 0x55 地址 数据读是 0x25 地址别搞混。提示调试 UART 通信时先用示波器或者逻辑分析仪抓一下波形看命令有没有正确发出芯片有没有回应。比盲猜快得多。7. 把算法跑在 STM32F217 上的性能考量7.1 浮点运算和定点运算的取舍STM32F217 有 FPU单精度浮点运算很快。温度换算里涉及 sqrt 和除法用浮点写起来直观性能也够。但如果系统要同时处理 16 个通道每个通道 20SPS那就是 320 次换算每秒每次换算大约 1μs总共 320μs占 168MHz 主频的 0.05%完全不是问题。不过如果项目对成本敏感换成没有 FPU 的 STM32F103那就建议用定点运算。把温度放大 100 倍用整数表示sqrt 用查表加牛顿迭代也能做到很快。7.2 数据缓冲和通信任务的分工在实际产品里温度采集只是系统的一部分。STM32F217 还要跑以太网协议栈、Modbus 从站、LCD 显示等。我的做法是ADC 读取放在中断里只做最少的处理把原始码值存入环形缓冲区温度换算放在主循环批量处理缓冲区里的数据通信任务用独立的状态机避免阻塞这样即使通信任务偶尔卡顿也不会丢采样数据。环形缓冲区的大小根据数据率和通信周期算一般存 100 个点足够了。7.3 低功耗场景的处理如果设备是电池供电或者对功耗有要求可以用 ADS122U04 的单次转换模式。STM32 平时休眠定时唤醒启动一次转换读完后继续休眠。20SPS 下单次转换大约 50ms平均电流可以做到几百微安。配合 STM32F217 的低功耗模式整体功耗能控制在 1mA 以内。需要注意的是每次唤醒后要等电流源和 PGA 稳定。ADS122U04 从关断到稳定大约需要 100μs如果不等就启动转换第一次结果会不准。可以在启动转换前加一个短延时或者用芯片的 DRDY 信号确认。8. 写在最后的一些个人体会这套 ADS122U04 加 STM32F217ZG 的方案我从几年前开始用在几个工业温度采集项目上累计出货也有几千台了。整体稳定性很好但前提是硬件设计和软件配置都要到位。最容易出问题的地方往往不是芯片本身而是电源、布局和校准这些“外围”工作。如果让我给正在做类似项目的朋友几条建议我会说第一参考电阻一定要用好料布局要远离热源第二校准不要省哪怕只做单点校准也比不做好第三UART 通信一定要加超时和重试工业现场什么奇怪的事情都可能发生。还有一点ADS122U04 的 datasheet 里有很多细节比如不同数据率下的噪声表、电流源的建立时间、PGA 的共模范围限制这些都要仔细看。我见过有人直接用 128 倍增益去放大 PT100 信号结果发现共模电压超范围了读数完全不对。PGA 增益不是越高越好要结合信号幅度和共模电压一起算。温度测量这个事说起来简单做起来细节很多。希望这篇内容能帮到正在这条路上摸索的人。