做了七八年采集类项目真正让我静下心来琢磨温度测量这事的还是去年那台HVAC控制器。设备要用热电偶和PT100测风管内温度现场变频风机一启动信号就飘用普通16位ADC根本压不住。最后定下的方案就是ADS122U04IPWR STM32F446ZE。当时查了一圈发现这套组合在工业温度采集和HVAC场景里其实很典型而且踩过的坑不少今天把从选型到固件到现场排查的完整过程整理出来给正要碰这个方案的朋友做个参考。先说清楚这套东西能干什么。ADS122U04IPWR是TI的24位Delta-Sigma ADC自带UART接口专门为温度传感器设计内部集成了可编程增益放大器、两个激励电流源、内部基准和故障检测功能STM32F446ZE是ST的Cortex-M4 MCU主频168MHz资源绝对够用。两者一搭可以直接接K型热电偶、PT100/PT1000铂电阻、NTC热敏电阻输出稳定可靠的温度数据。适合做工业过程控制里的温度变送器、HVAC系统的风管温度/水温监测、冷媒管路温度采集以及任何对精度有要求、又需要在较长距离上走数字信号的应用。1. 为什么是 ADS122U04IPWR STM32F446ZE 这套组合1.1 从应用需求倒推选型选型不能只看芯片手册得先从现场需求反推。HVAC 和工业温度采集有几个共性要求传感器输出信号极微弱。K 型热电偶在常温下每度只有约 40µV 的变化如果直接进 ADC量化噪声就能把信号埋掉。所以前级必须要有高增益、低噪声的 PGA。ADS122U04 内部集成了 PGA增益可选 1 到 128 倍能把微伏级信号放大到 ADC 量程内。现场干扰大。变频器、压缩机、继电器通断都会在传感器线上耦合出共模干扰需要 ADC 有好的共模抑制能力。ΔΣ ADC 本身对带内噪声有整形作用配合内部滤波能压掉不少高频干扰。传感器种类多。一套控制器可能要同时接热电偶和 RTDADS122U04 内置激励电流源可以给 PT100 提供恒流激励也能给热电偶做偏置检测这样硬件上不用换板子固件配置一下就能切换。布线距离远。工业现场传感器和主控板之间往往隔着几米甚至十几米。模拟信号走远了会被衰减和干扰所以最好把温度传感器信号就近数字化再用数字接口传回。ADS122U04 的 UART 接口就是为这个场景设计的比 SPI 更适合长距离传输。至于为什么选 STM32F446ZE而不是更小的 F103一是 F446 有多个 UART可以同时挂几个 ADC 或者保留调试串口二是它有 FPU做热电偶线性化和 RTD 多项式计算时速度更快三是内存大以后想加数据缓冲、曲线存储都方便。尤其在做多通道温度采集时F446 的 DMA 加 FIFO 能大幅降低 CPU 占用。1.2 和常见替代方案对比很多人第一反应是用 ADS1220同样是 TI 的 24 位 ADC但接口是 SPI或者干脆用 ADS111516 位。这里面的差别很关键我列个表格方案分辨率接口激励电流源适合场景短板ADS122U0424位UART有热电偶/RTD长距离传输速率相对低ADS122024位SPI有板内高速采集SPI 线多远距离易受干扰ADS111516位I2C无需外置低成本简单测温分辨率不足激励需自搭普通 MCU 内置 ADC12位内部无要求极低的场景精度和抗干扰能力不够UART 的优势在于线少只用 TX/RX/GND波特率低时传输距离比 SPI 远很多而且方便做电气隔离——加一对数字隔离器就能把现场侧和主控侧隔开这在工业上非常重要。SPI 需要四根线速率高时线间串扰明显而且主从时钟同步在隔离时更麻烦。I2C 虽然有地址概念可以挂多设备但受上拉电阻限制抗干扰和距离都不行。这里不是全盘否定 SPI 方案如果你的 ADC 和 MCU 在同一块 PCB 上距离不到 10 厘米那 SPI 的 ADS1220 完全够用还便宜一点。但只要涉及传感器探头外置、穿过接线端子、走一段电缆我就会选 UART 接口的 ADS122U04。2. 硬件连接与模拟前端设计2.1 UART 接口接线与 STM32F446ZE 引脚映射ADS122U04 的 UART 接口电平是 3.3V TTL可以直接接到 STM32F446ZE 的 USART 引脚。我实际用的配置是STM32F446ZE 的 USART2TX 引脚是 PA2RX 引脚是 PA3。ADS122U04 的 TX 接 STM32 的 PA3RXADS122U04 的 RX 接 STM32 的 PA2TX地线共地。这里有个容易踩的坑ADS122U04 的 UART 是异步串口不支持自动波特率检测所以 MCU 和 ADC 的波特率必须严格一致。我用的 9600 波特率8 数据位、无校验、1 停止位。为什么不用 115200因为 24 位 ADC 的转换速率本身不高UART 只是用来发命令和收数据9600 波特率下每条命令约 1ms 完成完全够用而且低波特率时误码率更小抗干扰能力反而更强。如果想让通信更稳可以在 UART 线路上加 TVS 管和串联电阻。工业现场常有静电和浪涌串一个 220Ω 电阻加一个 3.3V 的 TVS能省掉很多售后麻烦。远距离传输时还可以在 UART 前后加数字隔离器比如 ISO7721把现场侧电源和主控侧电源彻底分开这样即使传感器端受到电击也不会烧坏 MCU。2.2 热电偶和 RTD 的模拟前端电路硬件上最容易出问题的不是数字接口而是模拟前端。ADS122U04 虽然内部集成了很多东西但外围不处理好精度照样拉垮。热电偶接入热电偶输出是差分信号动态阻抗很低所以走线要尽量靠近 ADC 引脚。我的做法是在 ADC 输入端前加一节 RC 低通滤波以抑制高频噪声每根热电偶线串 1kΩ 电阻对地接 0.1µF 电容形成截止频率约 1.6kHz 的低通滤波器。这个滤波也能在传感器断线时提供共模电压路径防止 ADC 输入悬空。热电偶还有一个关键点是冷端补偿CJC。ADS122U04 内部有温度传感器可以读内部温度做冷端补偿但前提是芯片温度接近热电偶连接器温度。如果 PCB 上有发热器件冷端误差会很大。所以 PCB 布局时要把 ADS122U04 和热电偶接线端子放一起远离电源模块。RTD 接入PT100 是电阻型传感器需要激励电流。ADS122U04 有两个内部激励电流源可配置为 10µA 到 1.5mA我实际用 1mA。PT100 在 0°C 时是 100Ω1mA 激励产生 100mV 信号经过 PGA 放大后到 ADC 输入。RTD 接法建议用三线制一根激励电流从 ADC 的 IDAC1 流出经过 PT100再从 RTD 的公共端回流到 IDAC2。这样可以抵消引线电阻影响因为激励电流和测量回路共用同一根线电压测量不受引线电阻变化影响。如果条件允许四线制精度最高但工业现场很多时候只有三根线所以三线制最实用。还要注意 RTD 连接线不能太长否则线上寄生电容和电感会影响激励电流设置导致测量自己产生偏置。我一般把线长控制在 3 米以内超过就做 4-20mA 变送器方案。2.3 PCB 布局上的经验这块属于普通文档里不写、但在实际中要命的内容。ADS122U04 是 24 位 ADC最忌讳的就是数字噪声串到模拟电源。我的经验模拟电源 AVDD 和数字电源 DVDD 要分开走线各自用 0.1µF 加 10µF 电容滤波。ADC 下方的模拟地要完整不要在 ADC 底下走数字信号线。STM32F446ZE 和 ADC 之间如果距离较远数字线不要和模拟线平行放置。如果做的是多通道采集热电偶的冷端温度参考点要保持稳定不要在附近放高功率电阻或散热片。3. 通信协议与寄存器配置3.1 理解 UART 协议帧结构ADS122U04 的 UART 协议并不复杂但一定要把帧结构搞清楚。每条命令或数据都遵循固定的字节组合命令帧起始字节0x00、命令类型、寄存器地址、数据字节、校验和。数据帧ADC 转换结果通常由 3 个字节组成加上状态字节组成 4 字节数据。以读寄存器为例标准命令是0x00 0x20 0x00 0x00其中 0x20 表示读操作具体值以数据手册为准后面跟着地址和校验。写寄存器类似。我建议把命令封装成函数不要每次手写。波特率方面ADS122U04 支持多种标准波特率具体要在初始化时通过寄存器配置。我用的 9600 是默认值只要 MCU 端设置一致即可。一个常见的问题是MCU 发送命令后ADC 并不是立即返回结果而是需要等待转换完成。如果你在发送命令后立刻读串口大概率读到空。正确做法是发送命令后延时再检查 RX 缓冲区。这个延时时间取决于数据速率设置。比如设置在 20SPS 时一次转换约 50ms至少延时 60ms 再读。3.2 关键寄存器与初始化流程ADS122U04 的寄存器按功能分组最重要的几个配置寄存器 0设置 PGA 增益、输入多路复用、传感器检测电流源。配置寄存器 1设置数据速率、转换模式连续或单次、滤波器模式。配置寄存器 2设置激励电流源数值以及内部基准使能。配置寄存器 3设置 UART 波特率、CRC 校验使能等。我的初始化流程是复位 ADC发送 RESET 命令等待 10ms。写配置寄存器 0根据传感器类型设置 PGA 增益。热电偶使用 128 倍增益PT100 使用 32 倍或 16 倍增益。写配置寄存器 1设置为连续转换模式数据速率 20SPS50Hz/60Hz 干扰抑制都开。写配置寄存器 2使能内部基准配置激励电流源为 1mA。写配置寄存器 3设置 UART 波特率 9600关闭 CRC 或者开启现场干扰严重时建议开启。等待至少两次转换周期让数字滤波器稳定。这里有一个必须注意的细节更改 PGA 增益或数据速率后ADC 需要重新校准内部失调和增益误差。ADS122U04 有自校准命令初始化完成后发一次 SELFOCAL 或者 SELFGCAL取决于你想校准失调还是校准增益。我自己总会发一次完整自校准因为它会把内部失调抵消掉实测能减少几十个 LSB 的零漂。4. 固件实现从原始码到真实温度值4.1 STM32F446ZE 的 UART 初始化HAL 库固件我用 STM32CubeIDE 开发HAL 库。初始化很简单UART_HandleTypeDef huart2; void MX_USART2_UART_Init(void) { huart2.Instance USART2; huart2.Init.BaudRate 9600; huart2.Init.WordLength UART_WORDLENGTH_8B; huart2.Init.StopBits UART_STOPBITS_1; huart2.Init.Parity UART_PARITY_NONE; huart2.Init.Mode UART_MODE_TX_RX; huart2.Init.HwFlowCtl UART_HWCONTROL_NONE; huart2.Init.OverSampling UART_OVERSAMPLING_16; if (HAL_UART_Init(huart2) ! HAL_OK) { Error_Handler(); } }注意HAL_UART_Receive 是阻塞的如果在主循环里长时间等待接收会卡死逻辑。我建议用中断或 DMA 接收。简单的做法是开 UART 接收中断把收到的字节放进环形缓冲区主程序轮询缓冲区判断是否收到完整一帧。uint8_t rxBuf[64]; volatile uint16_t rxLen 0; void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) { if (huart-Instance USART2) { rxBuf[rxLen] rxByte; HAL_UART_Receive_IT(huart2, rxByte, 1); } }4.2 发送命令与读取转换数据下面这段代码封装了发送写寄存器命令和读数据的函数uint8_t adcBuf[4]; void ADC_WriteReg(uint8_t addr, uint8_t data) { uint8_t cmd[4]; cmd[0] 0x00; // 起始字节 cmd[1] 0x40 | addr; // 写命令 cmd[2] data; cmd[3] checksum(cmd, 3); HAL_UART_Transmit(huart2, cmd, 4, 100); } int32_t ADC_ReadData(void) { uint8_t cmd[4]; uint8_t resp[4]; cmd[0] 0x00; cmd[1] 0x10; // 读数据命令具体参考手册 cmd[2] 0x00; cmd[3] checksum(cmd, 3); HAL_UART_Transmit(huart2, cmd, 4, 100); HAL_UART_Receive(huart2, resp, 4, 100); // 24位有符号数据符号扩展 int32_t raw ((int32_t)resp[0] 16) | ((int32_t)resp[1] 8) | resp[2]; if (raw 0x800000) { raw | 0xFF000000; // 符号扩展为32位 } return raw; }这段代码里的校验和函数实际就是 CRC 或累加和建议用芯片手册指定的算法不要自己发明否则通信不稳定时要排查半天。4.3 热电偶温度换算读取到的原始码要转成温度。以 K 型热电偶为例大致流程先计算热电偶电压V raw * (2 * VREF / gain) / 2^24。从内部温度传感器读取冷端温度 T_cold。用冷端温度反查热电偶分度表得到冷端对应的电压 E_cold。实际热端电压 E_hot E_measured E_cold。再用 E_hot 查分度表或使用多项式拟合得到 T_hot。我为了节省 Flash没有整张查表而是用了分段线性插值把 K 型热电偶 -50~500°C 分成 20 个区间每个区间存两个点和斜率误差可以做到 0.2°C 以内。如果你对精度要求极高可以用 ITS-90 多项式但计算量大一些。F446 有 FPU跑几百次多项式完全没问题。4.4 RTD 温度换算PT100 的换算相对简单使用 Callendar-Van Dusen 方程0°C 以上R(t) R0(1 At Bt²)0°C 以下需要额外加 C*(t-100)*t³ 项。代码里我一般反向计算先测电阻再用二分法或牛顿法求解温度。F446 跑二分法 20 次迭代精度到 0.01°C耗时不到 1ms。不过实测中发现用 ADC 内部基准配合激励电流源测电阻时基准电压的温漂会被视为误差。更好的做法是使用比例测量把激励电流同时流过 PT100 和一个精密参考电阻用 ADC 同时测量两个电压比值的精度只取决于参考电阻的精度不受电流源和基准漂移影响。ADS122U04 支持这种接法就是多接一个精密电阻的事成本可能增加几毛钱但稳定性提升明显。5. 实测数据与误差分析5.1 测试环境与结果硬件调试完成之后我在实验室用干体炉和精密万用表做了一组对比测试。测试条件K 型热电偶PGA 增益 128数据速率 20SPS内部基准。结果如下设定温度°C实测显示°C偏差°C重复性峰峰值-20-19.830.170.1100.050.050.095050.210.210.12100100.140.140.10200200.310.310.15400399.86-0.140.18我做了自校准和冷端补偿之后基本能把误差压在 0.3°C 以内。对于 HVAC 应用通常要求 ±0.5°C 就足够这个精度是富余的。5.2 偏差来源与校准方法偏差主要来自三处冷端补偿误差。ADS122U04 内部温度传感器和热电偶端子之间如果有温差会产生接近 1:1 的误差。解决办法是在热电偶端子附近放一个 NTC 或者用 PCB 铜箔测温把冷端补偿点设计在真正连接处。PGA 失调和增益误差。虽然自校准能消除大部分失调但增益误差仍存在。可以用标准信号源输入一个已知电压然后修正增益系数。数据速率和滤波器的相位滞后。20SPS 响应慢如果被测温度在快速变化会有滞后。但这在 HVAC 管道测温里不是问题因为热惯性本身就是低通。实际工程做法是两点校准在 0°C 冰点和 100°C 沸点各测一次计算偏移和增益修正系数然后写进 Flash。如果产品要求批量一致性可以在生产线上用干体炉做三点校准。6. 工业现场的噪声治理与故障排查6.1 来自变频器和继电器群的干扰HVAC 系统里有变频风机、压缩机、接触器这些设备会通过电网和空间辐射产生干扰。我在现场遇到过一个很典型的例子设备在实验室怎么测都正常一装进风机柜就偶发数据跳变。用示波器抓 UART 线上的波形发现通信线在继电器吸合瞬间有毛刺电压幅度超过 3.3V。解决办法从几个方向同时下手通信线使用屏蔽双绞线屏蔽层单端接地避免形成地环路。UART 线上增加了 RC 滤波和 TVS 二极管吸收尖峰。传感器信号线远离动力线不能避免时使用金属管屏蔽。电源端加共模电感和 X/Y 电容抑制来自电源端口的传导干扰。ADC 的模拟信号处理上ADC 输入端已经有 RC 低通但还想再提高共模抑制可以接一个仪表放大器。不过 ADS122U04 内部 PGA 本身的共模抑制比已经达到 100dB 以上只要不在输入端人为搞不对称基本够用。6.2 通信异常与数据跳变的排查链路如果 UART 通信经常超时不要急着改代码按这个顺序排查用示波器在 ADC 的 TX 引脚看是否有波形。没有波形检查命令有没有发出去波特率是不是设置错了。检查 TX/RX 是否交叉接反。这个错非常低级但接反后 ADC 完全没有回应。检查电平幅值。如果波形幅度低于 2.5V 或者高于 3.6V可能是接线过长衰减或地电位差引起的需要检查共地。检查供电。ADS122U04 对电源噪声敏感如果电源纹波超过 20mV转换数据会跳动。示波器看 AVDD 引脚。检查 CRC。开了 CRC 之后每次收到的数据帧需要做校验不要图省事关掉在工业现场开启可以提前发现误码。检查传感器断线。热电偶断线时 ADC 可能输出非常大的码值这其实是故障检测功能的正常表现。我最深刻的体会是ADC 数据跳变 90% 不是 ADC 本身的问题而是模拟前端和数字通信链路出了状况。曾经排查过一个偶发跳变问题最后发现是 PT100 接线端子松动接触电阻从 0.1Ω 变到 1Ω激励电流引起的电压变化被 ADC 忠实记录下来了。这种情况下任何滤波算法都救不了只能靠定期检查端子和使用防松端子解决。6.3 提高系统可靠性的几个小花招代码层面可以加一些保护逻辑比如当读取到的原始码接近正满偏或负满偏时主动判断为传感器断线或短路输出故障状态而不是异常温度值。对连续读取的数据做中值滤波去掉最大的 20% 和最小的 20%再取平均。这个算法在 HVAC 现场很实用能有效抵御脉冲干扰。每次上电后先读一次 ADC 芯片 ID 寄存器确认芯片沟通正常再进入正常流程避免上电时序乱导致死等。7. 写在最后这套方案的实际调试心得ADS122U04IPWR 和 STM32F446ZE 这套组合我已经用了一年多先后做了两版产品。整体评价是上限很高下限也低。如果你照着参考设计画板子按照手册配置初始化精度可以做到 0.2°C 以内如果你忽略模拟前端布局、侥幸不校准、随便选数据速率那结果会让人怀疑芯片是不是有问题。最值得投入时间的地方是冷端补偿和校准这两件事。很多人把注意力放在 24 位分辨率上觉得分辨率高就能测准实际上热电动势的微弱信号经过 PGA 放大后最终的精度瓶颈往往是冷端温度和参考基准的温漂。我后来在 PCB 上把 ADC 和端子尽量靠近在结构上做了隔热才把冷端漂移压下去。另外不要把数据速率调到最高。ADS122U04 虽然有更高的采样率但噪声会随数据速率上升而增加。对于 HVAC 温度控制20SPS 已经是非常快的响应了风管里的温度变化可能以秒为单位20SPS 完全不会影响控制效果。追求高采样率在这里毫无意义反而会给滤波和抗干扰添麻烦。如果后续要做多温度区监控可以直接用多个 ADS122U04 挂在不同的 UART 上或者通过外部 UART 切换芯片地址配置很灵活。再进阶一点可以把 STM32F446ZE 跑上 RTOS每个温度通道一个采集任务通过消息队列发给控制逻辑整个架构会清爽很多。最后分享一个实用技巧产品量产前我建议在每块 PCB 上都做一次回环测试——在 ADC 的输入端用精密电阻器模拟一个已知温度对应的电阻然后通过上位机读取固件算出的温度。整个过程自动化几十秒就能测完能发现焊接不良、元件贴偏等一系列问题。这套方案的价值就在于当你想把温度采集做成真正可靠的产品时它给了你足够的余量去抵抗各种工程上的意外。
阅读完成 · 觉得有帮助?