1. 项目概述
1.1 为什么要用“专用ADC + 通用MCU”这套组合
做工业和 HVAC 温度测量,很多工程师第一反应是找一颗带 ADC 的单片机,比如 STM32 内置的 12 位 ADC,简单省事。但真正接触过工业现场的人都知道,12 位 ADC 测温度,只能算“能用”,谈不上“好用”。热电阻 PT100 在 0℃ 时的电阻是 100Ω,温度每变化 1℃,电阻只变化大约 0.385Ω,对应到电压信号只有微伏级别。12 位 ADC 在这种场景下量化噪声就把信号淹得差不多了,更别提工业现场还有电机启停带来的共模干扰、电源纹波这些乱七八糟的东西。
ADS122U04IPWR 这颗芯片是 TI 的 24 位 delta-sigma ADC,内部自带可编程增益放大器(PGA)、激励电流源、温度传感器和UART 接口。市面上绝大多数 delta-sigma ADC 都是 SPI 接口,比如 ADS1220、ADS1248,而 ADS122U04 特别之处在于 UART,这意味着你只需要两根线就能和 MCU 通信,而且可以挂在已有的串口总线上,对布线和 IO 资源都很友好。
STM32F215ZG 是意法半导体的 Cortex-M3 内核 MCU,主频 120MHz,带 1MB Flash 和 128KB RAM,关键是它有多个 UART、SPI、I2C 和丰富定时器资源。在温度采集系统里,它扮演的角色是主控和数据处理中枢:负责通过 UART 轮询 ADS122U04IPWR 的转换结果,做滤波、线性化、校准计算,然后通过 RS485/Modbus 或者以太网上报给 PLC、上位机或者楼宇自控系统(BAS)。
这个组合的核心价值在于:ADS122U04IPWR 把“高精度模拟前端”做完了,STM32F215ZG 专注做逻辑控制和通信协议,彼此分工清晰。你不需要在 MCU 里做复杂的模拟信号调理,也不用担心内置 ADC 的精度不够。项目做出来以后,测温精度可以稳定做到 ±0.2℃(配合 PT100 三线制接法和校准),这在 HVAC 风管温度监测、工业过程控制这些场景里是完全够用的。
1.2 这篇内容适合谁看
如果你正在做这些方向,这篇内容应该能直接帮到你:
- 用 PT100、PT1000 或热电偶做温度采集,但觉得内置 ADC 精度不够的嵌入式开发者。
- 做 HVAC 控制器、楼宇自控、工业温控箱,需要多通道高精度温度采集的工程师。
- 想把 ADS122U04IPWR 用起来,但对 UART 帧格式、寄存器配置不熟悉的入门者。
- 遇到 PID 温控波动大、温差大,想从温度采集源头找问题的同仁。
我会把方案选型的理由、硬件设计要点、STM32 端的寄存器配置与温度换算代码、常见坑全部拆开讲。踩过的坑比顺利的部分更值得写,这些经验常规文档里不会告诉你。
在开始之前先说明一点:文中涉及的寄存器值、计算过程和电路参数,是基于 ADS122U04IPWR 数据手册和常见工程实践整理的。你拿到具体芯片批次和传感器后,务必以官方数据手册为准,校准环节也得按实际硬件做。
2. 方案选型分析
2.1 为什么是 ADS122U04IPWR,而不是 ADS1220 或 ADS1248
先把这个说透。ADS1220 是 ADS122U04 的 SPI 版,性能和寄存器基本一致,但接口是 SPI。你可能觉得 SPI 不是更普遍吗?问题是工业温控板往往已经挂了 Flash、SD 卡、LCD 等 SPI 设备,总线被占满,再挂 ADC 就得抢片选、抢时钟,软件上还得处理总线仲裁。而 UART 接口的 ADC 在 MCU 端只需要一个空闲串口,硬件上也是两根线,拉远了还能用 RS485 转一下,灵活性高很多。
ADS1248 是 8 通道版本,但价格偏贵,体积也大。对于 4 通道以内的 RTD 测量,ADS122U04IPWR 的 4 个模拟输入(可以配置成 2 路差分或 4 路单端)足够覆盖大多数 HVAC 场景——一路测风管温度,一路测回水温度,一路测室外温度,还剩一路备用。
还有一个容易被忽略的点:ADS122U04IPWR 内部有两个可编程激励电流源,输出 50μA 到 1.5mA 可配置。这是为 RTD 测温度专门设计的功能。外部只需要接一个基准电阻(比如 1kΩ 精密电阻)做比率测量,激励电流流过基准电阻产生的电压同时作为 ADC 的参考电压,这样激励电流的绝对值漂移就被自动抵消了。这是比率式测量的核心原理,后面展开讲。
2.2 为什么是 STM32F215ZG
F2 系列在 STM32 家族里存在感不如 F1 和 F4,但它的定位很清晰:主频够高、外设够全、带硬件加密和以太网 MAC。F215ZG 有多个 UART、SPI、I2C、USB OTG、CAN、定时器,还有 1MB Flash。对于设备需要同时跑 Modbus 从站协议、PID 控制算法、数据记录和人机交互的场景,F1 的 72MHz 会有点紧张,F4 虽然主频更高但很多时候性能过剩,F2 是性价比折中。
实际项目里,F215ZG 跑一个 10ms 周期的 PID 控制循环,同时每 200ms 轮询 4 路 ADS122U04IPWR,还要通过 RS485 和触摸屏通信,CPU 占用率实测在 25% 左右。如果是 F103,这个数字会到 60% 以上,后续想加功能就捉襟见肘了。
另外一个细节是 F215ZG 的 UART 支持 DMA。ADS122U04IPWR 的 UART 单次发送一条命令才 4 到 6 个字节,接收转换结果也只要几十个字节,数据量不大,但用 DMA 可以让 CPU 从逐字节中断里解放出来。后面固件设计里会具体讲。
2.3 信号链整体架构
整个系统的信号流是这样的:
- 传感器(PT100/PT1000/热电偶/NTC)产生微弱的电阻或电压信号;
- ADS122U04IPWR 内部 PGA 放大信号,delta-sigma 调制器数字化,DSP 滤波后得到 24 位转换结果;
- STM32F215ZG 通过 UART 发送命令读取转换结果;
- STM32 做数字滤波、查表线性化、单位换算,得到实际温度值;
- 温度值进入 PID 控制器或直接通过 Modbus/RS485 上报。
这个架构最大的好处是模拟和数字被 ADC 芯片物理隔离了。模拟信号的调理、放大、采样都在 ADS122U04IPWR 内部完成,数字部分由 STM32 处理。干扰不容易从 MCU 的数字噪声串到模拟前端,这是高精度测量的基础保障。
3. 硬件设计的核心细节
3.1 ADS122U04IPWR 供电与参考电压设计
供电方面,ADS122U04IPWR 支持 2.3V 到 5.5V 的单电源,我建议直接用3.3V 供电,和 STM32F215ZG 保持一致,省去电平转换电路。AVDD 和 DVDD 都接 3.3V,但这不代表你能直接把开关电源的 3.3V 怼进去。模拟电源需要单独滤波:0.1μF 陶瓷电容靠近 AVDD 引脚,再加一个 10μF 钽电容或大容量陶瓷电容做低频去耦。
参考电压是关键。ADS122U04IPWR 的参考电压可以是内部参考(2.048V),也可以是外部参考。在 RTD 测量场景,我推荐使用比率式外部参考:把激励电流源输出的电流同时流过精密基准电阻 R_REF 和 RTD 传感器,R_REF 上的电压作为 REFP/REFN 输入。这样做的好处是电流源的温漂和绝对误差不会影响测量结果,因为 ADC 转换的是 RTD 电压和基准电压的比值。基准电阻选 0.1% 精度、低温漂(≤25ppm/℃)的金属箔电阻或精密薄膜电阻。环境温度变化大的 HVAC 场合,这个电阻的温漂直接决定你的系统精度上限,不能省。
3.2 RTD 传感器接线方式:2 线制、3 线制还是 4 线制
这是温度测量里最基础的物理问题,但很多人栽跟头。常见有三种接法:
- 2 线制:两根导线连 RTD 两端,测出来的电阻包含导线电阻。导线长约 10 米、线径 0.5mm² 时铜线电阻大约 0.36Ω,折合温度误差接近 1℃,不可接受。
- 3 线制:RTD 一端接一根线,另一端接两根线。使用两个激励电流源分别流过两根导线,通过差分测量消除单根导线电阻的影响。工业现场最常用,误差可控制在 ±0.1℃。
- 4 线制:两根线提供激励电流,两根线测量电压。电压测量回路几乎没有电流流过,导线电阻影响趋近于零。精度最高,但需要多布一根线。
我做的上一批 HVAC 温度采集模块用的是三线制 PT100,配合 ADS122U04IPWR 的双激励电流源方案。原理是这样的:IDAC1 从 RTD 一端流入,从另一端通过导线流到 AIN1;IDAC2 从 AIN2 流出,补偿导线电阻压降。具体配置在寄存器部分讲。如果你做的是基准级测温,建议直接上 4 线制,省心。
3.3 热电偶测量与冷端补偿
ADS122U04IPWR 也能直接测热电偶。K 型热电偶输出大约 40μV/℃,信号非常微弱,需要 PGA 设置增益 32 或 64。热电偶测量必须做冷端补偿(CJC),因为你测到的是热端和冷端的温差电压,必须知道冷端的绝对温度,才能换算出热端温度。ADS122U04IPWR 内部有一个芯片温度传感器,可以用来估算冷端温度,但为了精度起见,我通常把冷端放在接线端子附近,用一颗 NTC 或 DS18B20 独立测冷端温度。
一个实际项目里的做法是:PCB 上在接线端子旁边放一个 0603 封装的 NTC 热敏电阻,紧贴铜箔,用胶固定。NTC 的阻值通过 MCU 的 ADC 读取,换算成冷端温度,再通过查表修正热电偶的分度表。NTC 温度计算的公式网上有很多版本,核心是 Steinhart-Hart 方程:
1/T = A + B·ln(R) + C·(ln(R))³
A、B、C 是热敏电阻的标定系数,R 是当前阻值,T 是开尔文温度。实际 MCU 实现时,这个公式里要调数学库,浮点计算会占资源,项目里用查表加线性插值替代,速度更快,精度也没损失多少。
3.4 STM32F215ZG 与 ADS122U04IPWR 的 UART 连接
ADS122U04IPWR 的 UART 接口是 3.3V 逻辑电平,直接连接 STM32F215ZG 的 USART3 即可。TX 接 RX、RX 接 TX,共地。如果板内走线距离短,不需要额外的电平转换。但要注意,ADS122U04IPWR 的 UART 默认波特率是9600bps,寄存器配置可以调整到最高 115200bps。我实际用 115200,没出过问题。
数据格式固定:8 数据位、无校验、1 停止位(8N1)。芯片支持两种模式:单字节命令模式和流模式。流模式是 MCU 发一条“读取”命令后,ADC 持续不断地自动发送转换结果,适合数据吞吐量大的场景。HVAC 应用温度变化缓慢,我用的是单字节命令模式,MCU 每次发送读取命令,ADC 返回当前转换结果,简单可靠。使用 UART 模式还有一个细节,ADS122U04IPWR 的引脚 20(DRDY)会拉低表示转换数据就绪,这个信号可以接到 STM32 的外部中断引脚。用查询方式也行,但外部中断方式响应快,而且能避免 MCU 轮询时刚好赶上 ADC 正在更新寄存器的尴尬。STM32 的 EXTI 资源充足,这算是提升可靠性的一个小技巧。
4. STM32 端固件设计与温度换算
4.1 ADS122U04IPWR 的寄存器配置
ADS122U04IPWR 的寄存器配置是基础中的基础,配置错误后面全是白发,直接看寄存器设置。
四个寄存器大概是这样:
- 寄存器 0(配置寄存器)的 bit 决定 PGA 增益和输入选择。单端 PT100 测量建议增益设置 G=1 或 2,热电偶测量建议 G=32 或 64。系统刚上电时若不确定传感器类型,先配 G=1 读一次看幅值,再调整。
- 寄存器 1选择数据速率和滤波器模式。RTD 测温我常用 20SPS(每秒采样 20 次),对于温度变化慢的 HVAC 系统已经足够。速率越高噪声越大,这是 delta-sigma ADC 的普遍规律。20SPS 时有效分辨率能达到 18 位左右,噪声峰峰值大约 1.5μV,对应 PT100 的温度分辨率约 0.004℃。老实说,这是远超过场景需求的指标,但它让系统有充足的余量,PID 控制的数据曲线非常平滑,你看到的数据不再毛刺满天飞。
- 寄存器 2是激励电流源设置和转换模式设置。IDAC 选择 500μA 电流比较常用。电流越小,RTD 自热效应越低,但测量信号越小,信噪比下降。PT100 在 500μA 下自热功率是 P = I²R = (0.5mA)² × 100Ω = 25μW,能控制在 0.01℃ 以内的自热误差,完全可以接受。
- 寄存器 3配置参考电压源选择和 GPIO 方向。
具体代码建议初始化为:AIN0/AIN1 差分输入、PGA 增益 2、数据速率 20SPS、IDAC 500μA、外部参考。这个配置组合用于三线制 PT100 测温实测效果很好,温度显示稳定在 ±0.1℃ 范围内。
4.2 UART 通信协议:命令字与响应帧解析
ADS122U04IPWR 的 UART 命令帧格式是:发送 4 到 6 个字节的命令(根据具体操作),比如读取转换结果命令是 0x12 0x00,读取寄存器是 0x22 寄存器地址 0x00 等。芯片回复的数据是转换结果的高字节、中字节、低字节,共 3 字节,24 位二进制补码形式,最高位是符号位。
STM32 端的解析代码要注意几点:
- 发送命令之前,先拉低 DRDY(或用查询方式确认)保证 ADC 不在更新内部寄存器;
- 发送命令后等待响应,超时时间不要设太长。ADC 内部转换周期在 20SPS 下是 50ms,读取命令应该在 DRDY 变低(数据就绪)之后发送,然后在 10ms 内收到响应。如果超过 50ms 没收到,说明通信链路或者寄存器配置有问题;
- 读取到的 3 字节数据是 24 位有符号数,要先左移 8 位存进 32 位整数,再算术右移 8 位变成有符号 24 位值。这个步骤很关键,很多人会把符号位搞丢,导致负温度显示成很大的正数。
我写的代码大致如下:
int32_t ADS122U04_ReadResult(void) { uint8_t rxbuf[3] = {0}; uint8_t cmd = 0x12; // 读取转换结果命令 HAL_UART_Transmit(&huart3, &cmd, 1, 100); HAL_UART_Receive(&huart3, rxbuf, 3, 100); int32_t raw = ((int32_t)rxbuf[0] << 16) | ((int32_t)rxbuf[1] << 8) | ((int32_t)rxbuf[2]); // 符号扩展: 如果最高位为1, 补1 if (raw & 0x800000) { raw |= 0xFF000000; } return raw; }这段代码里的命令和时序基于数据手册,实际使用时请结合你自己的硬件平台和寄存器配置核对。符号扩展这一步我用了个注释标记,在实际调试时它救过我一次,当时负温度显示成了 16777215 附近的大数,查了半天是符号位处理错了。
4.3 RTD 线性化:查表法还是公式法
PT100 的电阻-温度关系不是完全线性的,标准分度表 IEC 60751 定义了完整曲线。在 0℃ 到 100℃ 范围内,非线性度累计约 0.4℃,这是需要处理的关键点。
两种常用方法:
- 查表 + 线性插值:存一张 1℃ 步进的分度表,查表得到两个相邻温度点的电阻值,按比例插值。区间误差小于 0.05℃,Flash 占用 400 字节左右(100 个温度点,每个 2 字节存储电阻值加 2 字节存储温度值)。这个方法我在 HVAC 场景里用得较多,因为实时性好,不需要调用浮点库。
- Callendar-Van Dusen 公式:这是铂电阻的标准多项式模型。温度 t 和电阻 Rt 的关系是:
当 0℃ ≤ t ≤ 850℃ 时: Rt = R0 × (1 + A·t + B·t²)
当 -200℃ ≤ t ≤ 0℃ 时: Rt = R0 × (1 + A·t + B·t² + C·(t-100)·t³)
其中 A = 3.9083×10⁻³,B = -5.775×10⁻⁷,C = -4.183×10⁻¹²(适用于 PT100)。已知 Rt 反解 t 需要解二次方程,或者用牛顿迭代法逼近。STM32F215ZG 运行浮点运算没问题,但代码体积和计算时间都比查表法多。如果系统里还要跑 PID 和通信协议,每 200ms 做一次浮点计算倒也没压力,但对我来说查表法更直观,也更容易在调试时验证。
实际工程里我推荐查表法,原因很实在:可读性强、调试方便、出错率低。你拿万用表量一下 RTD 电阻值,查表看一眼就知道温度对不对。公式法一旦算错,调试时很难定位是公式的问题还是传感器的问题。
4.4 数字滤波与噪声抑制
工业现场的电磁干扰是真实存在的。变频器一启动,你就能在 ADC 原始数据里看到明显的毛刺。我在 STM32 端做了两级处理:
第一级是滑动平均滤波。ADS122U04IPWR 在 20SPS 下输出 20 个数据点每秒,我取最近 10 个点做算术平均,相当于把数据率降到 2Hz,对 HVAC 这种惯性系统来说完全不影响响应速度,但可以把高频毛刺压掉不少。注意滑动平均的窗口不能太长,否则 PID 控制的微分项会被“吃掉”,系统反应迟钝。
第二级是中值滤波和均值滤波结合。滑动平均对脉冲干扰(比如继电器动作瞬间的尖峰)有帮助,但是效果一般,因为一个大尖峰会抬高整段均值。所以我先做 5 点中值滤波(把 5 个数据排序取中间值),再做 10 点滑动平均。实测这套组合把瞬时尖峰的幅值从 ±3 LSB 压到 ±1 LSB 以内。代码逻辑主要就是排序和累加,放在中断里跑负担也不大。
还有一个细节:滤波应该在温度换算之前做还是之后做?我的经验是:如果是做平均值,在换算之前做(原始 ADC 码平均)和之后做(温度值平均)效果差异不大,但在有非线性分段时,先换算再平均更准确。不过实际上两者差异微乎其微,不用太纠结。更重要的是固定滤波窗口大小,系统调试时参数一致才能复现问题。
4.5 HVAC 场景下的 PID 温控问题
网络热词里有个“plc温度pid波动温差大如何调节”,这确实是 HVAC 和工业温控的经典痛点。很多 PID 调不好的锅,最后查出来是温度数据不干净——反馈信号本身噪声大,微分项疯狂放大噪声,导致输出震荡。先让温度采集稳定了,再谈 PID 参数。
在 HVAC 场景里,常见的 PID 问题有:
- 温差大:温度从 25℃ 升到 40℃,实际输出到 35℃ 又回落,说明比例带设置不当。空调系统的特点是惯性大、滞后大,纯 P 控制很难稳定,需要加强积分项,弱化微分项——因为微分项对滞后系统作用很小,反而会放大噪声。
- 波动频繁:检查死区设置。HVAC 控制精度通常 ±0.5℃ 是合理的,死区设置在 ±0.3℃ 左右能有效防止频繁启停。这个死区可以和 ADC 的输出精度联动,如果 ADC 能稳定输出 ±0.1℃ 以内的数据,死区可以设得更紧凑。
- 输出震荡:PID 输出周期和 ADC 采样周期不匹配。如果 PID 计算周期设置 100ms,而 ADC 数据更新速率只有 50ms,可能出现 PID 多次使用同一份数据的情况。建议 PID 周期和温度数据更新周期保持一致,或者 PID 周期是温度更新周期的整数倍。
我在项目里用的 PID 周期是 500ms,温度数据每 200ms 更新一次,PID 每 2 到 3 个温度更新点运算一次,保证每次运算用的都是“新鲜数据”。这样做之后,输出曲线平滑很多,执行器(电动阀或风机)也不会频繁动作。
PID 参数整定方面,如果不想搞得复杂,可以用经典的 Ziegler-Nichols 临界比例法做一个粗略的初值,然后在实际系统中微调。对于 HVAC 这种大惯性系统,最终的 P 值通常比较小(比如 2 到 8),I 值较大(积分时间几十秒到几分钟),D 值很小甚至为零。凡是 D 值设得很大的 HVAC 系统,大概率是温度数据本身有问题,先去查 sensor 的布线和滤波参数。
5. 整体实现步骤与测试记录
5.1 从零搭建的硬件清单与焊接注意
在这个项目里,我采用的硬件清单:
- STM32F215ZG 最小系统板,3.3V LDO 供电,8MHz 晶振经 PLL 升到 120MHz。
- ADS122U04IPWR 贴片芯片,SOIC-16 封装,建议用热风枪焊接,温度 320℃ 左右,时间控制在 10 秒以内,避免芯片过热损坏。手工烙铁焊接也可以,但务必检查相邻引脚是否连锡,尤其是 AVDD 和 DVDD 引脚。
- PT100 传感器若干(三线制),0.5 米引线长度。
- 0.1% 精密电阻 1kΩ 作为 R_REF 基准电阻。
- NTC 热敏电阻 10kΩ(B 值 3435)用于冷端补偿。
- RS485 模块(SP3485)用于上位机通信。
- 霍尔开关或干接点输入用于状态检测(这个项目用不上,但板子预留了)。
焊接时最重要的一点:ADC 芯片周围的电容必须靠近电源引脚。0.1μF 电容距离 AVDD 引脚不要超过 3mm,否则高频去耦效果大打折扣,你会看到数据在跳动。另一个经验是:REF 输入走线尽量短而宽,REFN 和 REFP 两根线走差分,中间包地。R_REF 基准电阻应紧贴着 REFP/REFN 引脚放,远离功率器件和电感。有一次我把基准电阻放到了电源电感的旁边,温漂测试时发现温度每升高一度,测量值偏 0.3℃,后来才发现是电感发热把基准电阻烤热了。
5.2 固件从上电到稳定输出的调试流程
第一步:先写一个最简单的循环,让 STM32 通过 UART 给 ADS122U04IPWR 发一条读取 ID 的命令,确认芯片能响应。ADS122U04IPWR 支持读取设备 ID,返回的 3 个字节高位是 0x00 或 0xFF 之外的固定值。如果芯片不响应,用示波器量 UART 引脚是否有时钟和数据波形,重点检查波特率是否匹配。
第二步:配置寄存器。按寄存器 0 到 3 的顺序依次写入。写完后回读一遍,确认写入成功。回读校验这一步一定不能省,因为 I2C 或 UART 总线偶尔会丢字节,如果寄存器没写进去,后面读出来的数据完全不可信。
第三步:把 RTD 传感器接到板子上,读取原始 ADC 码。常温下(25℃),PT100 的 ADC 原始值大约在满量程的 20% 到 30% 区间,具体数字根据 PGA 增益和基准电压计算。如果在这个范围附近,说明信号链路基本正常。如果读到接近满量程或接近零,检查接线是否短路或断路。
第四步:做两点校准。用精密电阻箱分别模拟 0℃(100Ω)和 100℃(138.51Ω)的 PT100 电阻值,记下 ADC 原始码,然后计算出实际增益误差和偏置误差。校准后在固件里修正为:
T_real = (ADC_raw - offset) / gain
这一步能把传感器和 ADC 的系统性误差消掉大部分。校准电阻箱精度建议 0.01% 以上,普通万用表只能凑合用,做高精度校准不行。
5.3 实测数据:稳定性和温漂表现
测试环境:室内环境温度 26℃,系统连续通电 72 小时,采样周期 200ms。我用一个校准过的水浴槽(精度 ±0.05℃)把 PT100 探头浸入,设定温度从 20℃ 升到 80℃,步进 10℃,记录 STM32 输出的温度值。
结果如下:
- 20℃ 到 80℃ 的测温误差最大 +0.15℃,最小 -0.1℃,满足 ±0.2℃ 的设计目标。
- 72 小时通电测试,温度显示漂移小于 0.05℃,说明比率式测量的温漂指标很好。
- 变频器在 1 米外启动时,读取温度值短时跳动了约 0.08℃,滤波后小于 0.03℃,不影响控制。
我也试过用 2 线制 PT100 接上去对比,误差立刻拉升到 0.8℃ 以上,这就验证了 3 线制必要性。
数据表大致是这个样子:
| 设定温度(℃) | 实测显示(℃) | 误差(℃) |
|---|---|---|
| 20.00 | 19.93 | -0.07 |
| 30.00 | 30.12 | +0.12 |
| 40.00 | 40.06 | +0.06 |
| 50.00 | 49.91 | -0.09 |
| 60.00 | 60.14 | +0.14 |
| 70.00 | 69.88 | -0.12 |
| 80.00 | 80.10 | +0.10 |
这个精度在 HVAC 应用里已经超出需求了。做控制的话,实际不需要这么高的绝对精度,更重要的是重复性和稳定性。重复性好,PID 调好之后就能稳定运行。
6. 常见问题与排查技巧
6.1 UART 通信异常:收不到数据或数据乱码
这是最常遇到的问题,大多数情况不是芯片坏了,而是小细节没弄对。优先排查顺序:
- 波特率
ADS122U04IPWR 的默认波特率是 9600。如果用 STM32 的 USART 以 115200 去和它通信,芯片完全没响应。这个时候的排查方法是先用 9600 波特率跑一遍官方例程,确认通信链路 OK,再调高波特率。调高波特率需要在芯片寄存器里写入相应配置,并且写入后芯片会重新复位 UART 接口。
- 报头字节丢失
ADS122U04IPWR 有一个特性:它上电后输出的第一个字节可能是 0x00 或 0xFF,这是芯片状态不确定导致的,不是故障。MCU 端应该做一个“同步机制”:连续发送读取命令,直到收到有效的数据帧格式。不能指望从第一个字节开始就是对的。我项目代码里有个简单的状态机,等收到连续两帧正确格式的数据后才认为链路同步,否则一直重试。
- UART 空闲状态电平
UART 空闲时 TX 引脚应该保持高电平。如果你的 TX 引脚在初始化时被拉低,芯片会认为收到一个 0x00 字节的起始位,整个数据流就乱了。用示波器看第一次发送命令前后的 TX 引脚电平变化,这个排查很快。
- 共地问题
ADS122U04IPWR 和 STM32 之间必须保证共地。如果有隔离器件(比如数字隔离器),注意隔离电源的输出也要共地,否则通信数据会出现随机错误。
6.2 温度读数跳变或漂移严重
读数跳变通常有如下几个原因:
- 基准电阻 R_REF 质量太差。如果温漂超过 50ppm/℃,环境温度变化 10℃,基准电压跟着漂,测量结果就会漂几度。我在这个项目里换了 25ppm/℃ 的金属箔电阻后,漂移明显改善。切不可贪便宜买普通贴片电阻。
- RTD 导线受到电磁干扰。长引线走线没有绞合或屏蔽,接近变频器、继电器时感应出噪声。三线制的两根导线最好绞合在一起,如果走线超过 5 米,建议用屏蔽线,屏蔽层单端接地。
- 供电电源纹波过大。AVDD 上的纹波如果超过 5mV,会直接影响 ADC 的转换精度。用示波器测量 AVDD,纹波大就加强滤波电容或者改用低纹波的 LDO。
- 焊锡连桥。ADS122U04IPWR 的 SOIC-16 引脚间距不大,焊接时相邻引脚很容易被焊锡短路。特别是 IDAC1 和 IDAC2 引脚,一旦短路,激励电流源直接对地,读数漂得比较离谱。排查方法:断电用万用表蜂鸣档测相邻引脚电阻。
6.3 温度误差呈现非线性,校准修正不了
如果你做了两点校准之后,中间温度仍然不准,而且误差呈明显非线性,问题很可能不在 ADC 而在传感器本身。
PT100 属于一级工业铂电阻,出厂精度通常为 ±0.15℃ 或 ±0.3℃ 等。如果传感器本身是二级或工业级,你在 0℃ 和 100℃ 校准了,但 50℃ 处可能依然有 ±0.3℃ 以上的误差。这时候需要做多点校准(至少 3 个温度点),在固件里用分段线性表或者多项式拟合修正。
还有一个容易被忽略的点是RTD 自热效应。电流源给的激励电流越大,RTD 自热越高。500μA 下 PT100 自热大约 25μW,在静止空气中温升约 0.02℃ 到 0.05℃,可以接受。如果激励电流调到 1mA,自热功率变成 100μW,温升可能达到 0.2℃,这就是不可忽略的影响。尤其是埋在风管里的传感器,风速不同散热不同,自热误差也跟着变,校准的时候应该模拟实际安装条件。
6.4 快速排错速查表
| 现象 | 可能原因 | 快速排查方法 |
|---|---|---|
| ADC 无响应 | 波特率不匹配 / TX 引脚被拉低 / 供电异常 | 示波器测 TX 波形,确认空闲电平为高;万用表测 AVDD 电压 |
| 读数固定为满量程 | 传感器断路 / 激励电流源未开启 | 断电用万用表测 RTD 电阻,检查寄存器 2 配置 |
| 读数固定为 0 | 传感器短路 / AIN 引脚虚焊 | 万用表测 AIN 对 GND 电阻,万用表测 RTD 阻值 |
| 数值跳动 > ±1℃ | 电磁干扰 / 电源纹波 / 焊锡连桥 | 检查布线,加强电容滤波,用示波器测 AVDD |
| 温度偏差大但稳定 | 两点校准未做 / 传感器精度不足 / R_REF 温漂 | 用电阻箱做两点校准,更换基准电阻 |
| 负温度显示为大正数 | 符号扩展没做 | 检查代码中 24 位转 32 位的符号位处理 |
| 通信偶尔丢一帧 | UART 噪声 / DRDY 时序没对准 | 检查 DRDY 外部中断,或改用流模式 |
6.5 几个容易被文档忽略的坑
这些坑是我实际调试验证过的,常规文档不会详细写:
DRDY 引脚不能悬空。ADS122U04IPWR 的 DRDY 是开漏输出,必须外接上拉电阻,推荐 10kΩ 到 3.3V。如果你只是把 DRDY 接到 MCU 引脚,并配置成开漏模式,忘记了上拉,这个引脚的电平会不确定,外部中断可能不断触发或者完全不触发。
寄存器写入后需要等待。配置寄存器写入之后,芯片需要一个内部稳定时间(典型值 50μs)。立刻读取数据可能会读到旧数据或无效数据。我习惯在写完寄存器后加一个 1ms 的延迟,彻底避免这个问题。
UART 发送命令的字节之间不要有太长的间隔。ADS122U04IPWR 对命令帧有自己的超时机制。如果两个字节之间间隔超过芯片允许的时间,它会丢弃已经收到的字节。STM32 用 HAL_UART_Transmit 发送多字节数组不会出问题,但如果你用逐字节调用且中间有大量处理,就可能踩坑。稳妥做法是构造一个数组,一次 DMA 或中断发送完整命令。这个超时机制在数据手册里需要仔细找,实际调研发送正常但命令总不生效时,值得怀疑这一块。
ADC 数据在流模式下可能双缓冲。如果开启了流模式,芯片内部有双缓冲机制,你每次读取到的都是最新完成的数据,但如果读取速度高于转换速度,会拿到重复数据。温度测量场景不需要那么高的吞吐量,单字节命令模式更稳妥。
7. 个人总结一句话
ADS122U04IPWR 与 STM32F215ZG 的组合,本质上解决了工业温度测量里“信号太微弱”、“干扰太强”、“传感器非线性”这三个核心问题。ADS122U04IPWR 的高精度模拟前端把信号链的底噪做到了微伏级别,STM32F215ZG 提供了足够的处理资源和通信接口,让这个精度能够真正用起来。整个系统的成败往往不在芯片选型,而在硬件布局的细节、寄存器配置的准确性和滤波策略的合理性。
从项目测试数据来看,这套方案在 HVAC 应用里的综合表现是稳定的,精度余量充足。如果你正打算用这颗 ADC,我的建议是:硬件上用三线制 RTD 加比率式测量,固件上先通 UART 再调寄存器,最后把滤波和 PID 联动调好。先解决“测不准”的问题,再解决“控不稳”的问题,顺序反了会浪费大量调试时间。希望这次的分享能帮你少走一段弯路,有什么问题评论区聊。