搞嵌入式测温搞了快十年,手里过过不少 ADC 和 MCU 的组合,但 ADS122U04IPWR 配 STM32F373RC 这套,算是我在工业和 HVAC 温控项目里用得最顺手的一组搭配之一。一个 24 位 ΔΣ ADC 带 UART 接口,一个自带高精度 SDADC 的 Cortex-M4 内核 MCU,光看规格书容易觉得“杀鸡用牛刀”,但真正把产线设备跑起来以后,才发现这组合在处理长线传输、抗干扰、多点测温这些事上,确实有两下子。
这篇文章不打算复读数据手册,而是把我在实际项目里踩过的坑、验证过的电路、写过的通信流程和算温公式,从头到尾捋一遍。如果你正准备做 -40℃ 到 150℃ 范围的 RTD 测温,或者要在大电流变频器旁边布置温度采集节点,又或者单纯想找一套“MCU 主控 + 外置高精度 ADC”的可靠方案,这篇应该能省你不少折腾时间。
1. 方案选型:为什么不用 STM32F373 自带的 SDADC?
很多朋友一看 STM32F373RC 名字里有“高精度”三个字,就觉得外挂 ADC 多此一举。F373 内部确实集成了三个 16 位 Σ-Δ ADC,这在通用 MCU 里已经算异类了,但真拿去测 PT100 或者热电偶,还是差点意思。内部 SDADC 的输入范围、 PGA 增益挡位、激励电流源这些资源都是固定死的,而且 16 位的有效分辨率在 100Ω 量级的 RTD 上,换算成温度也就零点几摄氏度的理论极限,加上内部基准温漂和数字地噪声,实际做到 ±0.5℃ 都费劲。工业现场要求的往往是长期稳定、可溯源、抗干扰,这时候外置独立 ADC 的优势就很明显了。
ADS122U04 是 TI 家的 24 位 ΔΣ ADC,严格说它属于 ADS1220 系列的 UART 变种。这颗芯片最吸引我的点,不是 24 位分辨率这个数字,而是它把 PGA、2 个 IDAC 激励电流源、内部 2.048V 基准、50/60Hz 工频抑制滤波器、4 通道输入选择全部集成在了一片 3mm×3mm 的 QFN 封装里。这意味着我拿到手的不是一颗裸 ADC,而是一个完整的模拟前端。配合 STM32F373RC 的多个 USART 资源,只需要两根线就能把 ADC 挂在主控上,板子布线压力小很多,尤其是在 HVAC 设备那种空间紧凑的控制板上。
1.1 为什么坚持选 UART 接口而不是 SPI 版本
ADS1220 是 SPI 接口,ADS122U04 是 UART 接口,硬件上几乎一样,选型时我纠结过一阵。实际对比下来,UART 在工业现场有两个不可替代的好处。第一是传输距离,SPI 在板级通信没问题,但一旦引出排线超过 30cm 就明显容易受干扰,而 HVAC 系统里温度探头往往要接到压缩机仓、风道内部,走线一两米很常见,UART 用 9600 波特率跑双绞线能轻松到 5 米以上;第二是隔离方便,后期如果遇到强干扰或者需要电隔离,UART 只需要加两个数字隔离器就行,SPI 要隔离四条线(SCLK、MOSI、MISO、CS),成本和故障率都上去了。
不过 UART 也不是没有代价,它最大的问题是通信速率上限低,ADS122U04 最高好像支持到 3.69Mbps,实际为了稳定通常跑 115200 甚至 9600。而 ADC 的输出速率最高能到 2000SPS,这意味着如果真把采样率拉满,UART 会来不及搬运数据。但在测温场景下,我们通常只需要 20SPS 到 640SPS,这个速率下 9600 波特率都绰绰有余。所以选 UART 本质上是一个“需求匹配”的取舍:测温不追求高吞吐,追求的是稳和准。
1.2 F373RC 在里面扮演什么角色
STM32F373RC 在这套方案里不是简单的“读数据、算温度”的跑腿角色。它最大的硬件资本是内置了 3 个 SDADC,虽然单独用它做高精度测温力不从心,但可以拿来做多通道同步采样、故障诊断和冗余校验。比如我在某个项目里,用 ADS122U04 测主回路 PT100,同时用 F373 内部 SDADC 测一路 NTC 做板温参考,两路独立硬件通道互为印证,一旦偏差超过阈值立刻报警,这种冗余设计在压缩机保护逻辑里非常管用。
另外 F373RC 的 256KB Flash 和 32KB RAM 也够用,跑一个简易 RTOS 加上点对点通信协议毫不吃力。更重要的是它的 USART 外设多,最多有 5 个,我可以在一个 USART 上挂 ADS122U04,另一个 USART 走 Modbus 跟 PLC 或者上位机通讯,第三个 USART 留给调试打印。这种“一个 MCU 管多路串口”的玩法,在板卡面积紧张的工控设备里是很实际的加分项。
2. 硬件设计:别在电源和参考电压上省钱
硬件设计这块我吃过不少亏,尤其是给 ΔΣ ADC 供电这件事。ADS122U04 的模拟电源 AVDD 和数字电源 DVDD 虽然都可以接 3.3V,但我强烈建议用两个独立的 LDO 分别供电,中间加磁珠隔开。第一次画板子时我图省事,AVDD 和 DVDD 直接短接在一个 AMS1117 上,结果读数在最低位跳了七八个 LSB。后来查资料才发现,数字部分的开关噪声会通过共用电源耦合进模拟前端,24 位 ADC 对电源纹波的敏感程度远超想象。用 TPS7A4901 这种低噪声 LDO 单独给 AVDD 供电之后,跳动立刻降到了两三个 LSB。
参考电压是另一个关键点。ADS122U04 内部基准虽然标称 2.048V,温漂做到 10ppm/℃ 左右,但我做的是工业级产品,环境温度可能从 -20℃ 飙到 70℃,10ppm 换算下来满量程就是 1.8mV 的漂移,折算成 PT100 温度读数能差出 0.5℃。所以我后来改用了外部精密基准 REF5025,5V 供电输出 2.5V,温漂 3ppm/℃,再配合低温漂的 0.1% 精度电阻做分压,长期稳定性立刻上了一个台阶。如果你只是做 HVAC 里的舒适性控温,内部基准完全够用;但如果要做出厂校准、要过计量认证,外部基准是必须的投资。
2.1 模拟输入通道的滤波网络
ADS122U04 内部有可编程增益放大器,输入阻抗其实不低,但工业现场传感器引线上难免耦合电磁干扰,所以输入端的无源 RC 滤波不能省。我常用的做法是每一路模拟输入对地接一个 100Ω 电阻串联,再接一个 100nF 电容到地,构成截止频率约 16kHz 的低通滤波器。电阻取值不能太大,否则会跟传感器源阻抗分压产生误差;100Ω 在多数场景下和 RTD 的 100Ω~1000Ω 阻抗匹配良好。
如果你测的是热电偶,源阻抗更低,滤波电阻可以放宽到 1kΩ,配合 100nF 电容能更好地抑制射频干扰。另外在这些滤波电容的选择上,要用 C0G 或 NP0 材质,不能用 X7R,因为 X7R 电容在直流偏压下容量会变化,对低频测量精度的影响非常隐蔽,我第一次排查动态误差时完全没想到罪魁祸首是几个贴片电容。
2.2 UART 通信线怎么接才稳
ADS122U04 的 UART 接口是 TTL 电平,外围只需要把 MCU 的 TX 接到 ADC 的 RX,把 ADC 的 TX 接到 MCU 的 RX,两根线互交叉。这里有个容易掉坑的地方:很多 STM32 的 USART 引脚默认是推挽输出,而 ADS122U04 的 RX 引脚内部可能没有很强的上下拉,上电时序不对时容易误锁。我的做法是在 MCU 的 TX 线上串联一个 1kΩ 电阻,既能限流又能在异常状态下保护引脚;同时在 ADC 的 TX 线上加一个 10kΩ 上拉电阻到 3.3V,保证空闲状态是确定的高电平。
如果通信距离超过 1 米,建议把 UART 信号转成差分传输,最简单的方式是用 MAX3485 转 RS-485,或者用 ISO7721 数字隔离器加电平转换。理论上 UART 是异步串口,不需要时钟同步,抗干扰能力本身就比 SPI 强,但加上隔离后就是完全两个世界,变频器启动的时候读数纹丝不动,那种体验是真舒服。
3. 软件实现:从同步到连续读数的完整流程
ADS122U04 的 UART 协议跟普通传感器不太一样,它不是那种“主机发一条指令,从机回一帧数据”的简单模型。芯片内部维护了一套基于寄存器的配置体系,上电后需要主机先做同步,再通过命令读写寄存器,最后启动转换并周期读回数据。这套流程第一次接触会觉得繁琐,但理顺了以后非常可靠,不会有 SPI 那种时钟极性搞错就一脸懵的问题。
我建议的电平流程是:上电等待至少 10ms → 发送同步字节(比如连续发几个 0x55 或者按数据手册规定的 SYNC 序列)→ 等待芯片应答 → 发送 WREG 命令配置寄存器 → 发送 RREG 命令回读校验 → 发送 START 命令启动转换 → 周期发送 RDATA 命令读取 24 位转换结果。每一步之间加一个小的超时保护,防止芯片死锁后整个采集链路卡死。这里没法给出具体命令字节,因为不同版本的数据手册对命令定义略有差别,建议翻到 TSDR 那节对着 Table 逐条核对。工程上最忌讳的就是从网上抄一段寄存器配置,然后盲调一整天。
3.1 STM32F373 端的 UART 驱动程序框架
用 HAL 库还是裸机寄存器看个人习惯,我自己偏好寄存器操作,因为可控性强、中断开销小。UART 初始化时重点设置波特率、8 位数据、无校验、1 位停止位,使能接收中断和空闲中断。接收数据的核心思想是维护一个环形缓冲区,中断里只负责把字节塞进 FIFO,主循环里再解析帧格式——切记不要在中断里做复杂的协议解析,否则高优先级中断会把 UART 的接收时序打乱。
一个比较实用的小技巧是:把 ADS122U04 的 RX 引脚配置成 EXT 中断,在发送命令之前拉低一段时间再恢复高电平,相当于给 ADC 一个硬件复位边沿。这颗芯片对 UART 总线上的毛刺比较敏感,上电后如果通信不正常,先别急着怀疑配置,试试看重新同步。我实测下来,在 9600 波特率下,主机每发送一个 0x55,ADC 大概在 1ms 内会回复一个 0x00 或者状态字,通过这个握手信号就能判断链路是否正常。
3.2 多通道轮询与数据对齐
ADS122U04 有 4 个模拟输入通道,可以配置成 2 组差分或者 4 路单端。实际测温时我喜欢把通道配置成差分模式,因为差分能同时抑制共模工频干扰和地电位差。切换通道的流程是:先 WREG 修改输入多路选择器 MUX 位,然后发送 START 命令重启转换,延时等待转换完成(用 SPS 换算),最后 RDATA 读回数据。这里最容易犯的错误是刚切完通道就立刻读数据,读到的还是上一个通道的残留值。正确做法是切通道后丢弃第一组转换结果,从第二组开始才有效。
我在 HVAC 项目里最多挂了 3 路 PT1000 和 1 路 NTC,全走差分模式,轮询周期设置在 100ms 左右,也就是每通道 10SPS。这个速度足够温控 PID 使用,而且数据非常平滑。如果硬要 4 个通道全部跑满 640SPS,UART 在 115200 波特率下会接近带宽瓶颈,而且数据抖动会明显增大,属实没必要。
4. 温度计算与校准:从码值到摄氏度的关键几步
拿到 24 位转换码值以后,最核心的一步是把它换算成真实的电阻值,再换算成温度。ADS122U04 的比例式测量方式让这个过程特别优雅:使用芯片内部 IDAC 电流源激励,一路电流流过 RTD 再经过精密参考电阻 RREF 到地,ADC 的参考电压取自 RREF 两端的压降,同时测量输入通道上 RTD 的压降。因为激励电流是同一个,所以电流源的绝对精度和温漂在计算中直接抵消掉了,这就是比例测量的精髓。
转换公式很简单:Rrtd = RREF × (Code / (2^23 - 1))。注意这里的前提是芯片配置成无符号二进制格式,如果配置成二进制补码,负温度时会出现负数码值,需要先做偏移处理。RREF 我选了 2490Ω、0.1% 精度、25ppm/℃ 温漂的电阻,这样在测 PT1000 时,满量程约 3.9V 激励电压,配合 500μA 电流源,功耗低且线性度好。如果你测的是 PT100,RREF 选 820Ω 更合适,因为 PT100 在 0℃ 时只有 100Ω,用小阻值 RREF 可以保证在低温段也有足够的激励电流分辨率。
4.1 查表还是公式:各有各的适用场景
PT100/PT1000 的电阻-温度特性可以用 Callendar-Van Dusen 方程描述,但直接算这个方程在单片机里涉及多次乘除运算,如果 MCU 没有 FPU 或者不想引入浮点库,查表是最简单粗暴的方案。IEC 60751 标准里有标准的电阻温度对照表,我把 -50℃ 到 200℃ 范围按 1℃ 间隔做成 251 个点的常驻 Flash 数组,用二分查找加线性插值,整个表格才 502 字节,查询一次最多十几次比较,速度快得很。
如果你追求更高精度,推荐在 0℃ 以上范围用 Callendar-Van Dusen 两段公式:R(t) = R0(1 + A·t + B·t²),其中 A=3.9083e-3,B=-5.775e-7。这个公式在 0~850℃ 范围内的误差不超过 ±0.1℃,工业级够用了。0℃ 以下会多一个 C 项,公式变长,我一般直接改用查表,省得算错。
4.2 两线制、三线制与四线制的误差控制
做 HVAC 时为了省线经常用两线制接法,但两线制的致命问题是:激励电流流过传感器引线时会产生压降,这个压降被 ADC 当作 RTD 压降的一部分测量了,导致读数系统性偏高。以 500μA 电流、2Ω 引线电阻计算,误差是 1mV,折算成 PT100 大约是 2.5℃,这个误差根本没法接受。所以我坚持在工业项目里用三线制:一根激励线走电流,两根测量线差分采样,采样端几乎无电流,引线误差天然被消除。
四线制精度最高,但需要 4 根线,成本高,我一般只在计量级应用中采用。在软件层面,还可以做一次“开短路检测”校准:先把 RTD 短接,读一个零值,再把 RTD 断开,读一个满量程值,然后把这两个值存进 Flash,后续每个读数都做线性纠偏。这个方法能同时校正前端放大器的偏置误差和 ADC 的增益误差,实测能把整体精度提高 0.2℃ 左右。
5. 工业与 HVAC 场景:抗干扰、布线与系统集成
HVAC 系统里最头疼的不是温度测量本身,而是温控设备周边的电磁环境。压缩机一启动,接触器火花、变频器 PWM 输出、风机电机反电动势,全都会往电源和信号线上灌干扰。ADS122U04 功耗很低,整机电流才 1mA 级别,反而更容易被外部噪声带着跑。我曾经在实验室里测试一切正常,一装到空调外机上就开始周期性跳数,最后定位到是排线跟压缩机电源线绑在同一个线槽里,感应了几百毫伏的噪声。解决方案很朴素:模拟信号线用屏蔽双绞线,屏蔽层单端接地,走线尽量远离功率线,如果非要交叉,必须垂直交叉而不是平行走线。
另一个 HVAC 常见场景是冷凝器管壁温度测量。这种场合传感器离 MCU 很远,而且经常会遇到地电位不一致的问题。这时候建议在 UART 通信线上加数字隔离器,隔离器两侧分别供电,模拟前端用独立隔离电源。虽然成本和板面积上去了,但换来的是彻底消灭地环路,数据稳定性会给你惊喜。
5.1 长线 RTD 测量时的充放电时间问题
ADS122U04 内部的 PGA 输入阻抗很高,但输入引脚对地总会存在寄生电容。如果你用很长的屏蔽线连接传感器,线缆电容可能达到几十纳法,加上输入滤波电容,等效 RC 时间常数可能大到影响转换结果。我第一次接了一根 20 米长的屏蔽线,发现读数明显偏低而且响应迟钝,就是因为线缆电容还没来得及充电,ADC 就开始采样了。解决方法是降低激励电流源的上升时间问题,在硬件上把采样延时配置开大,或者在启动转换之前让 IDAC 先稳定一段时间。ADS122U04 的寄存器里有一个设置转换建立时间的位,调到较长档位后,长线场景的读数立刻恢复正常。
5.2 系统集成:Modbus 上报与多节点组网
F373RC 读到的温度最终要上报给 PLC 或者楼宇自控系统,最通用的方式是走 Modbus RTU。我习惯把 F373RC 的 UART1 挂 ADS122U04,UART2 接 RS-485 收发器,把 F373 变成 Modbus 从站,寄存器地址里直接放温度值(放大 100 倍的整数)。这样做的好处是上位机不需要关心模拟前端细节,只读寄存器就行。如果你在一个系统里挂多个节点,每个 F373 分配不同的 Modbus 地址,就能组成一个经济实惠的多点测温网络,成本远低于专用温度变送器。
还有个小细节:ADR(地址)和波特率可以通过拨码开关配置,量产时每台设备烧录不同的默认地址,现场调试改起来就很轻松。F373RC 的 5V 容忍引脚在这里也派上用场,可以直接和标准 RS-485 芯片连接,无需额外的电平转换。
6. 问题排查与经验速查表
这套方案用了两三年,我整理了几个高频踩坑点,做成速查表,按这个顺序排查能省一多半的时间。
| 现象 | 排查方向 | 我实测的解决办法 |
|---|---|---|
| 转换值全部接近满量程 | 输入悬空、激励电流没建立 | 检查 IDAC 是否使能,探头是否断路 |
| 转换值跳动超过 5 个 LSB | 电源纹波、参考电压去耦不足 | AVDD 和 DVDD 分开供电,参考电压脚加 10μF 钽电容 |
| UART 通信偶尔超时 | 波特率偏差、上电时序异常 | 每次开始采集前发同步字节,加超时重试 |
| 温度读数偏高且随线长变化 | 两线制引线电阻压降 | 改三线制,或在软件里做引线电阻补偿 |
| 数据周期性跳变 | 与功率线平行走线 | 屏蔽线单端接地,改变线束走向 |
| 负温区读数非线性 | 查表插值步长过大 | 在 0℃ 附近加密表格,或改用公式计算 |
6.1 一个容易被忽略的“静默故障”
ADS122U04 有个特点:它的数据就绪状态不是用外部引脚输出的,而是靠主机的 RDATA 命令状态位来查询。如果代码里漏了读状态这一步,会发现偶尔读到的数据是重复的——芯片其实已经准备好新数据,但你没去取,等下次读时拿到的还是老数据。这种现象在高速采集时不明显,在低速采集时非常困惑,看起来像“数据偶尔不更新”。解决方法是启动转换后先发一个查询命令确认 DRDY 状态,或者干脆在定时器中断里固定周期读取,宁丢数据也不读旧值。
6.2 调试时必备的“三板斧”
如果你也是第一次玩这颗 ADC,我建议把调试流程控制在三步以内。第一步,先用内部基准、关掉 PGA、单通道、20SPS 的最低配跑起来,用万用表测传感器电压看读数是否大体符合预期;第二步,打开 PGA 和 IDAC,改成比例测量模式,重点检查码值和 RREF 计算后的电阻值是否在误差范围内;第三步,再逐步提高采样率、加滤波、加校准,每一步都通过串口打印原始码值和计算值,确认无误了再做下一步。别一上来就追求高精度全功能,问题会交织在一起没法定位。
多说一句,F373RC 的 SWD 调试接口并口调试时可能影响 ADC 的时序,我遇到过调试器挂着时通信正常,一拔掉就不稳定的怪事,后来把调试器供电和板子供电完全隔离才解决。这种“调试环境的隐性问题”最容易让人怀疑自己的代码,遇到莫名其妙的故障不妨先把调试器断开看看。
写在最后:这套组合的真正价值
用 ADS122U04IPWR 和 STM32F373RC 做温度测量,不是奔着“跑分”去的。24 位分辨率是噱头,真正的价值在于它提供了一条高可靠的模拟采集链路:比例测量消掉电流源漂移、UART 接口简化长线通信、外部基准守住长期稳定性、F373RC 提供充足的算力和串口资源来做协议转换和系统联动。我在多个 HVAC 项目和工业设备上跑过上千小时的连续运行,数据稳定度令人满意,温漂控制在 ±0.3℃ 以内。如果你也在找一套兼顾精度、成本和抗干扰的测温方案,我建议你认真考虑这个组合,照着上面的电路和代码思路搭一版,实测一遍胜过读十遍数据手册。