ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

UART接口24位Δ-Σ ADC与STM32F373的高精度温度采集方案解析

UART接口24位Δ-Σ ADC与STM32F373的高精度温度采集方案解析

一开始接触这套配置时,我的第一反应是:为什么放着 SPI 接口的高速 ADC 不用,偏偏选一颗走 UART 的 24 位 Δ-Σ 转换器 ADS122U04IPWR,再搭配 STM32F373VC 这颗混合信号 MCU?后来在工业和 HVAC 项目里跑过几个版本,我反而觉得这个组合非常合理——尤其是当你需要把温度传感器放在机器旁边、把控制板放在几十米外的控制柜里,而中间还隔着一道隔离栅栏的时候。

这篇内容适合正在做温度采集板、搞 RTD/热电偶前端、或者想给现有控制板扩展多路高精度温度通道的硬件和嵌入式工程师。我会把选型原因、传感器接线、寄存器配置、STM32 驱动、温度线性化计算和数据诊断整个链路都过一遍,顺便把现场容易踩的坑也提出来。就算你对 Δ-Σ ADC 不太熟,照着思路走也能把板子调通。

1. 为什么偏偏是“UART 版 ADC + 混合信号 MCU”:选型背后的真实逻辑

1.1 ADS122U04 不是 ADS1220 加个串口那么简单

很多人把 ADS122U04 理解成“ADS1220 换了通信接口”,这样说没有错,但容易低估它的价值。ADS122U0x 系列本质上是把 ADS1220 的 SPI 数字接口换成了异步 UART,其余模拟链路保持一致:24 位分辨率、4 通道输入、可编程增益放大器(PGA,增益 1 到 128)、两个用于 RTD 激励的集成电流源 IDAC、2.048V 内部基准,以及传感器开路检测功能。

真正的区别在接口。SPI 在单板内部很好用,可一旦遇到以下场景,UART 往往更省心:

  • 模拟板和数字板距离远,需要用双绞线或屏蔽线连接。UART 本身就是异步串行,很适合长线传输,而且在低波特率下对线缆电容和干扰的容忍度比 SPI 的时钟边沿采样高不少。
  • 需要加光电隔离或数字隔离。UART 即使不做隔离,只要把 TX/RX 电平转一下就能直接对接隔离芯片,比 SPI 的四线接口少好几路隔离通道,成本和 PCB 面积都更友好。
  • 主控侧资源紧张。很多工业控制板的主控已经跑着 PLC 协议、显示任务,没有多余 SPI 从机片选引脚,但空闲的 USART 通常还有。ADS122U04 刚好能“借”一个串口完成 4 通道高精度采集。

加上它自带 IDAC,意味着一个芯片能完成 PT100/PT1000 的恒流激励、热电偶毫伏信号放大、多路输入切换和模数转换,前端器件数量大幅减少。这个集成度对 HVAC 温控面板那种空间有限的板子尤其重要。

1.2 STM32F373VC 的存在意义:自带可靠模拟底子的控制大脑

STM32F373VC 属于 STM32F37x 系列,核心是带 FPU 的 Cortex-M4F,主频 72MHz。选它不只是因为它“够快”,而是因为它有几点和温度采集项目高度匹配:

第一,F373 系列内置了 3 个独立的 16 位 Σ-Δ ADC(SDADC),这在整个 STM32 家族里都不多见。虽然在这个方案里温度转换主要由外部 ADS122U04 完成,但多出的 SDADC 可以用来采集冷端补偿的温度传感器、监控电源电压或者做通道自检,不必再去占用外部 ADC 的输入。

第二,Cortex-M4F 的浮点单元对温度计算很重要。RTD 的 Callendar-Van Dusen 方程、热电偶的 NIST 多项式反算、滤波算法,这些全都是浮点运算。如果在 Cortex-M0 上慢慢用定点硬算,代码复杂度高,调试也麻烦;在 F373 上直接float一把梭,后期改系数和校准参数都方便。

第三,它支持多路 USART,一片 F373 甚至可以用一个串口接 ADS122U04,另一个串口接 RS-485 走 Modbus 上报给上位机或楼宇自控系统。正经做工业温度设备时,这个“下接传感器、上接总线”的结构几乎是标配,通信口紧张是常事。

1.3 这套组合的适用边界

我也要说句公道话,它并非所有场合都合适。如果你只是在单块 PCB 上做一个高速多通道数据采集,那么直接用 ADS1220 的 SPI 接口更简单,吞吐率上限也更高;如果传感器数量超过 8 路,可能还得考虑 ADS1262 这类更高阶的前端,或者用菊花链。ADS122U04 的典型应用是“中等精度、多类型温度传感器、需要一定通信距离和隔离”的监测型设备,而 F373VC 则负责把这些数据变成可靠的温控逻辑和总线报文。理解这个边界,选型才不会走偏。

2. 前端接线设计:RTD、热电偶、热敏电阻的信号调理细节

2.1 PT100/PT1000 的比例式测量电路

ADS122U04 做 RTD 测量时,我最推荐的是比例式接法。所谓比例式,就是让激励电流同时流过 RTD 和一个精密参考电阻 RREF,然后以 RREF 两端的电压作为 ADC 的基准电压。这样即使 IDAC 电流随温度漂移,ADC 的输入电压和基准电压也会同步变化,测量结果基本不受电流漂移影响,电阻计算只取决于码值和 RREF 的精度。

实际接线可以这样安排:

  • IDAC1 连接到 AIN0,电流流过 RTD 后从 AIN1 返回,再经过 RREF 回到 GND。
  • RTD 的两端分别接 AIN0 和 AIN1,作为差分输入通道。
  • RREF 两端同时接到 ADC 的基准输入端 REFP/REFN。
  • ADC 测量 AIN0 与 AIN1 之间的电压,电压值等于I × R_RTD;ADC 的基准电压等于I × R_REF;于是码值直接反映R_RTD / R_REF。

PT100 的阻值变化范围不大,0°C 时约 100Ω,100°C 时约 138.5Ω,500°C 时约 280.9Ω。为了兼顾信号幅值和自热效应,我一般选 500µA 或者 1mA 的 IDAC。500µA 时,RTD 在 500°C 产生的电压只有约 140mV,如果不加 PGA,分辨率会很吃亏;所以通常把 PGA 设为 8 到 16 倍,让信号更充分地使用 ADC 量程。

PT1000 阻值大约是 PT100 的十倍,激励电流可以降到 250µA 或 100µA,这样功耗更小,自热误差也更低,但同样要保证信号幅度足够。

2.2 热电偶通道,别忘了冷端补偿

热电偶输出的是一些毫伏级电压,比如 K 型热电偶灵敏度约为 41µV/°C,J 型约 52µV/°C。引脚可以直接接到另一组差分输入,但输入共模和放大增益要留意。

我常用的通道分配是:

通道传感器类型接线方式典型 PGA 增益备注
AIN0/AIN1PT100/PT1000差分,IDAC激励8 或 16比例式接法,配 RREF
AIN2/AIN3热电偶差分,加上拉偏置电阻16 或 32冷端由板载传感器补偿
另一组输入热敏电阻/NTC单端或差分2 或 4可做 CJC,也可做辅助温度

热电偶的冷端补偿其实是个容易翻车的点。很多人只盯着热端的热电偶电压,却忘了参考端其实在接线端子上,那个位置的温度必须被测出来,否则系统误差就是几度甚至十几度。我在设计里通常把 NTC 或 PT1000 贴在接线端子附近,用 PCB 上的铜箔做等温块,再通过另一路 ADC 通道或 STM32F373 内置的 SDADC 读取冷端温度。这样整个测量链路的“冷端”位置是确定的。

另外,热电偶测量通道需要在 AIN2 或者 AIN3 上接一个几百 kΩ 的上拉电阻到 AVDD。正常工作时这个电阻对测量影响很小,主要是配合 ADC 的烧毁检测功能判断传感器是否断线。这个后面第 5 节再展开。

2.3 供电、去耦和参考电压的现场经验

ADS122U04 的数字供电模拟供电可以连在一起,但模拟电源要尽量干净。我的经验是两个 100nF 陶瓷电容加一个 1µF 到 10µF 钽电容并排放在 AVDD 引脚附近,并且模拟地和数字地单点连接,避免把数字噪声灌进模拟回路。

RREF 的选择没有想象中随意。它既能决定 ADC 满量程范围,又是整个 RTD 测量的参考基准。温度系数至少要选 5ppm/°C 以下的薄膜电阻,甚至用低温漂金属箔电阻;容差最好 0.1% 或更好。如果你用 1% 的普通贴片电阻当 RREF,那么这块板子的理论精度就卡死在 1% 上了,ADC 本身再干净也没用。HVAC 现场环境温度变化大,这种隐藏误差在冬天夏天会直接表现为“同样的水温,两块板子读数差 1°C”。

内部基准 2.048V 很常用,但值得注意的是,内部基准做热电偶测量时有个潜在问题——基准电压本身可能随芯片温度轻微漂移。高要求的工业测量里,我更倾向用外部精密基准,或者对内部基准做一次出厂校准记录,在软件里补偿掉这个偏差。

3. 驱动初始化:ADS122U04 寄存器配置与 STM32F373VC 的串口对接

3.1 寄存器初始化顺序和几个关键字段

ADS122U04 通过寄存器配置工作模式。寄存器一共四个,每个 8 位,分别控制输入多路选择、PGA、数据速率、转换模式、基准、IDAC 电流大小和输出方向。给一个我从项目里常用的初始化顺序:

  1. 先发 RESET 命令,让器件回到已知状态。
  2. 配置寄存器 0:选择输入通道、设定 PGA 增益、决定是否旁路 PGA。
  3. 配置寄存器 1:设定数据速率和转换模式,温度测量一般选 20SPS 到 90SPS 之间,噪声更低。
  4. 配置寄存器 2:选择内部/外部基准,设定 IDAC 电流档位。
  5. 配置寄存器 3:分配 IDAC1 和 IDAC2 输出到具体引脚,同时设置传感器检测相关功能。
  6. 发送 START 命令,启动转换。

拿 RTD 通道举例,我会把寄存器 0 的 MUX 位选为 AIN0/AIN1 差分输入,PGA 增益设为 8;寄存器 2 的 VREF 选择内部基准,IDAC 电流设为 500µA;寄存器 3 把 IDAC1 路由到 AIN0。热电偶通道则把 MUX 切到 AIN2/AIN3,PGA 增益设得更高。

需要注意的是,具体位段定义在不同批次的 ADS122U04 数据手册里表述可能不完全一致,新画板时一定以手册的寄存器表为准。我的习惯是整个初始化期间把读回的寄存器内容打印出来比对写值,这能很快发现总线数据位错乱的问题。

3.2 UART 通信的同步机制和命令格式

ADS122U04 的 UART 通信有一点反直觉——命令不是单个字节,而是双字节结构,需要先发同步字节再发命令。设计成这种格式,主要是为了避免长线上的毛刺噪声被误识别成合法命令。你可以理解为:它要求“两拍确认”才能执行有效动作,单字节的杂散数据会被直接忽略。

实际使用中,我通常在每条命令前发送0x00作为同步帧,然后再发送目标命令字节。区分几个最常用的指令:

  • 复位:RESET
  • 启动转换:START
  • 停止转换:STOP
  • 读取转换结果:RDATA
  • 读取寄存器:RREG + 寄存器地址
  • 写入寄存器:WREG + 寄存器地址 + 寄存器数据

每次读数据时,先判断转换完成,可以等 DRDY/INT 引脚拉低,或者直接读转换周期的间隔时间再延时。等引脚比死等时间更可靠,因为延时碰到数据速率的边界误差容易读到旧数据。

3.3 STM32F373VC 侧 USART 配置要点

STM32F373 的 USART 配置本身并不复杂,这里只说容易出问题的几个点。

第一,波特率不要盲目拉高。ADS122U04 支持到 1Mbps,但长线传输时波特率越高,对线路上升沿质量和噪声越敏感。温度采集本身数据量不大,我常用 115200 或 230400 波特率,稳定压倒一切。

第二,用空闲串口和 DMA 搭配。读数据时发 RDATA 命令然后接收 3 个字节,如果用中断逐字节收,其实也能跑,但系统里还有其他任务时容易丢。我一般开一个 DMA 接收通道,把 ADC 的三个字节直接搬进缓冲区,然后进事件回调处理。

第三,F373 的 USART 支持硬件流控,但这里一般用不上。如果你要接隔离芯片,还要注意隔离器件的延时,波特率较高时延时会直接造成采样错误。我用数字隔离器时会把波特率压到 115200,给整个链路留足时序余量。

3.4 驱动代码主流程示意

下面这个简化伪代码展示了最本质的读取流程,不依赖具体 HAL 还是标准库。关键是传达一个动作序列:

void Ads_Init(void) { Ads_SendCmd(RESET); delay_ms(5); Ads_WriteReg(REG0, 0x32); // AIN0/AIN1差分,PGA=8 Ads_WriteReg(REG1, 0x10); // 20SPS,连续转换 Ads_WriteReg(REG2, 0x30); // 内部基准,IDAC=500uA Ads_WriteReg(REG3, 0x00); // IDAC1输出至AIN0 Ads_SendCmd(START); } uint32_t Ads_ReadData(void) { while (Ads_DRDY_Pin == 0); // 等待转换完成信号 Ads_SendCmd(RDATA); uint8_t buf[3]; Ads_ReceiveBytes(buf, 3); return ((uint32_t)buf[0] << 16) | ((uint32_t)buf[1] << 8) | buf[2]; }

这里REG0 = 0x32只是示意性写法,不同板卡设计时增益和通道会改。重点记住顺序:复位、写寄存器、启动、等引脚、发 RDATA、收 3 字节。这个循环稳定运行一段时间,再去做温度换算才有意义。

4. 把原始码变成可靠温度:线性化、滤波与浮点计算

4.1 RTD 线性化:Callendar-Van Dusen 方程

读回来的 24 位数据是二进制补码,对于双极性输入,满量程对应的码字是 ±2^23。RTD 比例式测量时,先算出电阻值再查温度:

float rtd_res = (float)adc_code / 8388608.0f * (float)RREF / PGA_GAIN;

算出电阻后,PT100 的温度需要解 Callendar-Van Dusen 方程。这个方程有两个分支:

  • 0°C 以上:R(t) = R0 × (1 + A×t + B×t²)
  • 0°C 以下:R(t) = R0 × [1 + A×t + B×t² + C×(t - 100)×t³]

其中 IEC 60751 标准给出的 PT100 常数是:

常数数值
R0100 Ω
A3.9083×10⁻³
B-5.775×10⁻⁷
C-4.183×10⁻¹²

直接解这个方程比较绕,工程上常用牛顿迭代法,迭代两三轮就能收敛。也可以用查找表加线性插值:建一个 -50°C 到 500°C 温度区间、每 10°C 一个点的电阻表,中间段用插值,误差可以压到 0.1°C 以内。我个人的做法是“查找表兜底 + 牛顿迭代精修”,既能保证速度,又不会在零点附近因为多项式分支切换而出台阶。

4.2 热电偶电压到温度的换算和冷端修正

热电偶和 RTD 完全不同,RTD 是“阻值随温度单调变化”,热电偶是“热端与冷端的温差产生热电势”。所以热电偶数据不能孤立的把电压转成温度,要先补偿冷端。

换算步骤:

  1. 利用冷端 NTC/PT1000 读到的温度值 T_cold。
  2. 查热电偶分度表,得到 T_cold 对应的热电势 E_cold。
  3. 读取 ADC 的通道电压 E_meas。
  4. 计算实际热端对应热电势:E_hot = E_meas + E_cold。
  5. 再用 E_hot 查分度表或反演多项式,得到热端温度。

K 型热电偶在 0°C 到 500°C 范围内的灵敏度约 41µV/°C。如果 PGA 增益只有 8,ADC 的数值分辨率会对温度分辨率有损失;所以我通常把热电偶通道增益设在 32 左右,同时把数据速率降到 20SPS,让 ADC 充分发挥 24 位的低噪声优势。

如果做分度表,建议直接用 NIST ITS-90 表,并把表的内存放在 Flash 里。单片机端浮点运算准备好了,查表加插值很轻松。没有表的话,用一个分段多项式拟合也能到几毫伏以内,但维护起来不如分度表直观。

4.3 数字滤波:不能只靠硬件平均

很多 Δ-Σ ADC 自带数字滤波,内部本质上就是一个低通滤波器,但它的滤波特性会随着数据速率改变。20SPS 下的输出噪声纹波已经很小,可是实际系统里还有 50Hz 工频干扰,尤其是 HVAC 设备附近,变频器、水泵电机带来的干扰很典型。

我会在应用层再补一道软件滤波。对一般温度控制,滑动平均窗口取 8 点到 16 点就够;但要注意滑动平均会带来响应延迟。如果做的是电机保护里快速过温报警,窗口不能太长,否则温度已经从 20°C 冲到 80°C 了,你还在平均那堆 40°C 的旧数据。这种场景更适合用一阶低通滤波,取一个较短的时间常数:

static float filtered = 0.0f; float alpha = 0.15f; filtered = filtered + alpha * (new_temp - filtered);

alpha 大小决定了跟随速度和滤波强度。实测下来,通风管道温度这种缓变量可以用很小的 alpha;冷却液回路温度变化稍快但也不算急,alpha 约 0.1 到 0.2 是比较合适的折中选择。

4.4 从原始码到温度的完整换算流程

我自己的转换流水线通常是:

  1. 每路 ADC 读到 3 字节,合并成 32 位整数。
  2. 根据是 RTD 还是热电偶选择不同处理路径。
  3. RTD 路径:算电阻 → CVD 方程 → 温度。
  4. 热电偶路径:算电压 → 查冷端补正 → 反查温度。
  5. 温度单位统一转成 °C,再传给控制逻辑和上位机。

整个过程浮点运算量很小,F373VC 每秒处理几十路温度也毫无压力。FPU 的性能在这里不是瓶颈,真正的瓶颈往往在前端信号质量和标定精度上。

5. 现场可靠性:断线诊断、校准手段和现场布线经验

5.1 传感器“生病”了怎么办:烧毁检测和断线判断

工业现场最常遇到的异常不是测量不准,而是传感器短路、断路和线缆进水。ADS122U04 支持传感器烧毁检测,利用内部一个微弱电流源或者外部上拉偏置电阻来检测电路是否中断。

RTD 断线时,ADC 输入会被上拉到某种固定电平,码值接近满量程或零;热电偶断线时,如果 AIN2 加了上拉到 AVDD 的偏置电阻,码值同样会冲向满量程。检测到这个特征后,软件要立刻把该通道标记为故障,并且不要把这个值扔进控制回路——否则一个断线热电偶会带来“温度极高”的假象,轻则报警,重则触发错误断电。

我会写一个简单的状态机:正常、短路、断路、超上限、超下限。每个转换周期做一次诊断,状态变化超过一次才确认故障,避免单点噪声误判。这个“防抖”机制在现场仓库里救过我不少次,一个插头接触不良导致闪断,如果不加防抖,系统会在正常的传感器值和大报警值之间横跳。

5.2 精度校准:零点、满点和补偿系数的处理

再好的 ADC 也需要校准。我的流程是先做硬件校准,再写软件补偿。

硬件校准以 RTD 通道为例,用精密电阻箱分别代替传感器的几个标准阻值,比如 100Ω、138.5Ω、175.84Ω 对应 0°C、100°C、200°C。记录 ADC 码值,拟合出实际参考电阻和理论值的偏差。这个偏差主要来自 RREF 容差、PCB 走线电阻和 PGA 增益误差。

软件校准上,我在 F373 里留了一组校准参数:零点偏移、增益系数、热电偶冷端补偿偏置。校准后的公式变为:

double corrected_temp = (raw_temp - zero_offset) * gain_coeff + cold_offset;

这个方案在 HVAC 水系统里效果明显。校准后,整系统的不确定度可以压到 ±0.2°C 以内(具体取决于传感器和布线),足以满足绝大多数楼宇自控需求。

如果你没有精密电阻箱,退而求其次的方法是只用沸水和冰水做两个低温标定点。但工业场合条件允许的话,电阻箱还是首选,因为你可以避开流体温度不均匀带来的误差。

5.3 工业与 HVAC 现场的布线经验

最后一个大坑在线缆布置。我见过太多板子放在实验室里很准,一进现场就漂移的情况。原因几乎都和热电动势、接地回路和电磁干扰有关。

先说热电动势。如果信号线用了铜线和传感器引线的连接,不同金属接触点只要存在温差,就会产生额外的热电偶效应。这个误差在热电偶毫伏信号面前很致命,即使只有 0.5°C 的温差也会引入几十 µV 误差。我的对策是:

  • 信号线尽量采用相同材质,并保证传感器端子附近温度尽量一致。
  • 输入端走差分对,两条线尽量等长并保持平行,把共模干扰转成差模的余量降到最低。
  • 屏蔽层单端接地,不要在传感器和主板两端同时接地,否则屏蔽层变成天线,反而引入更多干扰。

再说地回路。如果多个设备放在不同配电回路,参考地电位可能相差几十毫伏到数伏。这种共模电压如果直接灌进 ADC,轻则读数跳动,重则损坏芯片。现场条件差的项目,硬件上加隔离是必要的,UART 配合数字隔离器的方式成本可控,这也是我在章节 1 里说 UART 方案在隔离设计上更省事的原因。

最后是线缆选型。RTD 用三线制或四线制时,导线本身要尽量一致。PT100 的三线接线如果不平衡,线阻差异会直接叠加到测量值里。0.25mm² 铜线的电阻约 70mΩ/m,如果两根线长度相差 10 米,阻值就差约 0.7Ω,对应 PT100 约 1.8°C——这个误差往往比 ADC 本身的误差还大好几倍。所以我在设计里会把三线制的线阻一致性作为硬指标写进采购要求。

5.4 关于自热效应,一个常被忽略的温度误差源

还有一个小点,是我自己在做浸入式传感器时调了很久才确认的:自热效应。无论 RTD 还是热敏电阻,激励电流流过传感器自身都会产生热量。500µA 激励时,100Ω 电阻功耗只有 0.025mW,看起来微不足道,但把它全部用来加热一个体积很小的陶瓷封装传感器,就可能产生 0.1°C 级别甚至更高的温升。如果传感器被密闭在隔热套管里,误差会进一步累积。

HVAC 管道温度传感器通常接触面大、测试介质流动快,自热误差不太明显;但工业里的轴承温度、电机绕组温度监测,传感器往往被紧紧包裹在导热硅脂和绝缘层里,散热条件差,这个问题就必须在精度预算里预留出位置。我可以做几个激励电流档位测试,观察数据跳跃来估算自热大小,然后选择更小的激励电流,或者在算法里做固定补偿。

这些经验总结成一句就是:ADS122U04 和 STM32F373VC 给了你一个能跑得通的框架,但最终精度和长期稳定性的上限,还是由 RREF 的选型、PCB 布线、断线诊断策略和现场的接地隔离方式决定。把前面这些细节处理到位,这套组合能在工业与 HVAC 的温度测量任务里交出很漂亮的答卷。

返回列表