UART接口24位ADC+STM32F302实现工业级RTD温度测量方案
先说明一下标题里这个组合:ADS122U04IPWR是TI一颗自带UART接口的24位Δ-Σ ADC,STM32F302VC则是ST基于Cortex-M4F内核、带FPU和一堆高级定时器的MCU。这两个器件搭在一起做工业级温度测量,核心思路其实很简单——用UART把ADC和MCU之间的通信隔离做得更便宜、更省引脚,同时保留24位分辨率和RTD传感器激励能力。这套方案在HVAC冷热源机房、新风机组还有工业加热炉上我都实际调过,今天把设计思路、寄存器配置、传感器接线、软件滤波和排错经验一次性讲透。
1. 整体设计思路与方案选型拆解
1.1 为什么是ADS122U04而非SPI接口的ADS1220
先说结论:选ADS122U04而不是它的SPI兄弟ADS1220,就是为了隔离成本和布线自由度。工业现场最怕的不是精度不够,而是共模干扰和地环路。SPI的SCLK、DIN、DOUT、CS四根线,每根都得上数字隔离器,隔离器单价不低,PCB面积也压不住。UART只需要TX、RX两根线,隔离器用两通道的就够了,成本直接减半。
ADS122U04本身集成了两个IDAC激励电流源、内部2.048V基准、PGA可编程增益放大器和温度传感器。这颗芯片本质上就是把信号链的模拟前端全包了,MCU只需要通过UART扔命令和读数据。你说SPI接口传输速率快,但温度测量本身是个慢变量,20SPS的数据率对HVAC场景完全够用,UART通信在低速率下的可靠性反而更高,信号完整性问题少。
1.2 STM32F302VC的角色定位
F302VC在这个系统里不是主力信号处理单元,更像个协调者。Cortex-M4F带FPU,做PID温控或者线性化计算很顺手,这为后续在MCU侧跑PT100线性化算法留了余量。我在这套系统里还挂了一路PWM控制加热器、一路UART接上位机、一路I2C接OLED显示当前温度,F302VC的外设资源刚好覆盖。
选型时要注意的是,ADS122U04的UART波特率最高能到1.8432Mbaud,而F302VC的USART时钟来自PCLK。F302VC在72MHz主频下,USART波特率寄存器分频可以精确覆盖ADS122U04支持的几个固定波特率,这一点在后面配置里会详细展开。如果你选的是内部RC振荡器精度不够的MCU,UART通信会因为波特率误差累积导致帧错误,这是很多人踩过的坑。
1.3 系统架构与信号流向
这套温度测量系统的信号路径为:RTD铂电阻(PT100或PT1000)→ 通过IDAC激励源驱动 → ADC内部PGA放大 → 24位Δ-Σ调制器数字化 → 数字滤波 → 通过UART输出结果 → STM32F302VC接收并换算温度 → 控制逻辑。
这里有个关键设计决策——比例式测量。ADS122U04内部基准可以直接连接到IDAC的输出,这样基准电压就跟随激励电流波动。激励电流受温度漂移影响时,ADC的参考电压也同比例变化,测量结果不受电流绝对精度影响。在HVAC应用中,环境温度从机房20摄氏度到户外-10摄氏度来回变,IDAC电流漂移导致的误差被这个架构自动抵消了。很多新手会额外接一个外部基准芯片,反而破坏了比例测量的优势。
2. 传感器接口与信号调理核心细节
2.1 RTD传感器的连接方式
ADS122U04支持两线、三线、四线RTD接法。HVAC工况下,传感器到控制器之间的距离可能超过10米,此时两线制根本不值得考虑,因为导线电阻本身就是误差源。铂电阻的温漂系数大概是0.385Ω/℃,如果两线制导线电阻是1Ω,温度读数就偏了大约2.6℃,在恒温控制场景里这已经是灾难。
三线制是个很好的折中方案。原理是激励电流正负两条通路分别经过一根导线,测量端再用高阻抗ADC输入检测电压差,线电阻在正负端的压降相互抵消。接线方式如图1所示(实际接线请参照数据手册Figure 78),RTD一端接IDAC1输出,另一端分出两根线分别接到AIN1和AIN0。这种接法下,只要两根线材质相同、长度一致,线电阻误差基本被消除。
四线制精度最高,但成本也最高,通常只用于计量级设备。我个人的建议是HVAC冷热水管温度测量用三线制足够,工业加热炉控制回路如果要求长期稳定性才考虑四线。还有一点,RTD引线尽量使用屏蔽双绞线,屏蔽层单端接地,防止50Hz工频干扰耦合进测量回路。
2.2 IDAC激励电流与PGA增益配置
ADS122U04的IDAC电流可以从多个档位选择,常见的有250μA、500μA、1mA。选择IDAC电流时考虑两个约束:一是传感器的自热效应,电流过大会导致RTD自身发热,引入额外误差;二是ADC输入范围匹配。
以PT100为例,在500℃时电阻约280.9Ω,1000℃时约375Ω。如果用250μA激励,最高电压只有375Ω×250μA=93.75mV,这个信号太小,要依赖PGA放大。如果用1mA激励,同样375Ω下电压是375mV,但自热效应在PT100这种小型薄膜式传感器上可能会造成0.1~0.3℃的偏差。
我常用的配置是500μA + PGA增益8倍。这样满量程电压500μA×375Ω≈187.5mV,经过8倍增益后得到1.5V,而ADC的满量程是2.048V(内部基准),还有充足余量,不会削波。增益不是越大越好,PGA增益增加的同时输入偏置电压误差也被放大,8倍这个档位综合表现最稳。
2.3 ADC寄存器配置实战
ADS122U04通过UART接收8位命令字来配置寄存器。它的寄存器映射共4个,其中最关键的是配置寄存器0(地址0x00)和配置寄存器1(地址0x01)。
配置寄存器0控制PGA增益和输入多路复用器。PGA增益为8时,写入0x0B。寄存器0的低4位选择输入通道,AIN0和AIN1差分输入时,设置为0x00。所以寄存器0的完整值是0x0B。
寄存器1控制数据速率和滤波器模式。HVAC应用推荐20SPS数据率,此时数字滤波器能抑制50Hz和60Hz工频干扰——20SPS时FIR滤波器的陷波点在50Hz和60Hz及其整数倍频率上。设置20SPS对应的寄存器值是0x20。
寄存器2控制IDAC电流值和基准电压源。IDAC设为500μA时写入0x06,基准选择内部基准且采用比例测量模式,这个位域设置需要参考数据手册Table 23中的REF_SEL0和REF_SEL1。寄存器3控制IDAC电流输出引脚,设置为从IDAC1输出,RTD接在AIN0和AIN1之间。
写入命令格式是0x43开头,后面跟寄存器地址和值。例如写入寄存器0的命令序列为:0x43 0x00 0x0B。读数据的命令需要先用0x20设置状态位,然后等待DRDY引脚拉低,最后通过UART读取24位数据。这里有个细节——DRDY引脚必须接到MCU的GPIO,不能用轮询寄存器状态替代,否则高速率下会丢数据。
3. STM32F302VC端UART通信与数据处理实现
3.1 UART初始化与波特率匹配
STM32F302VC的USART1挂在APB2总线上,我实际项目里配置为72MHz主频,PCLK2=72MHz。ADS122U04支持的常见波特率是57600和115200,我在实际项目中使用115200,因为数据量小而且这个速率在UART隔离下可靠性仍然很高。
USART的波特率寄存器计算公式是:USARTDIV = PCLK / (16 × BaudRate)。代入72MHz和115200:USARTDIV = 72000000 / (16 × 115200) = 39.0625。分数部分0.0625对应BRR寄存器的DIV_fraction = 0.0625 × 16 = 1。写入BRR值 = (39 << 4) | 1 = 0x271。
有个必须说明的细节:ADS122U04的UART协议不是标准UART。它每帧是8位数据、无校验、1位停止位,但发送命令时MSB先发,读取数据时返回24位结果分3个字节,先收到的是高字节。如果用标准库的HAL_UART_Receive函数直接收,需要自己拼字节序,不然数值完全对不上。
3.2 从原始码到温度的换算算法
ADS122U04输出24位有符号数,二进制补码格式。量程对应关系是:满量程2.048V对应0x7FFFFF,负满量程-2.048V对应0x800000。实际电压计算为:V_in = (RawCode × 2.048V) / 0x7FFFFF。
RTD电阻值的计算利用比例测量特性简化。因为基准电压等于IDAC电流乘以参考电阻(R_REF),而ADC测量到的电压是IDAC电流乘以RTD电阻,所以:R_RTD = (V_in / V_REF) × R_REF。代入之前的PGA增益G:R_RTD = (RawCode × R_REF) / (0x7FFFFF × G)。
例如R_REF为2kΩ(注意这个电阻必须精度高、温漂低,我用到0.1%精度、25ppm温漂的金属箔电阻),PGA增益为8,原始码值为0x30D40(即200000),计算得到V_in = 200000 × 2.048 / 8388607 ≈ 0.04883V。经过8倍增益前,真实输入约6.1mV,RTD阻值 = 6.1mV / 500μA ≈ 12.2Ω——这个值接近PT100在-87℃的阻值,说明低温段信号真的很微弱,前级调理必须足够干净。
3.3 PT100线性化查表方案
铂电阻的阻值与温度关系是二次曲线,0~100℃范围内可以用查表加线性插值解决。把-50℃到250℃的RTD阻值表预先存在MCU的Flash中,以1℃为步进。运行时拿到R_RTD,先查表定位所在区间,再线性插值得到小数部分。
这段代码我放在中断外的主循环里执行,200μs内算完,完全不阻塞控制逻辑。为什么不用多项式拟合?因为HVAC控制器里MCU资源还要跑PID、心跳检测和通信协议栈,一次三阶多项式要3次乘法和加法,每次温度计算耗时200μs上下。查表加插值在整个运行周期分摊下来更省CPU,代码也更容易审查。
还要注意看门狗与主循环的耦合。我用F302VC的内核看门狗,喂狗操作放在1kHz定时器中断里,即使温度换算死循环也不会影响喂狗——但这样的话,看门狗就无法保护温度换算代码了。我的处理方法是换算完成后置一个标志位,喂狗中断检查这个标志,超过500ms没置位就强制复位。这种看门狗策略在工业设备里很实用,能暴露死循环又不会误杀正常任务。
4. 30天连续运行中的抗干扰策略与滤波实现
4.1 50Hz工频与差模干扰处理
工业现场最顽固的干扰源就是工频。ADC本身的数字滤波器在20SPS数据率下理论上对50Hz有无限抑制,但真实工况中整流设备会产生谐波、变频器干扰覆盖到几十kHz频段。ADS122U04数据手册上写了,20SPS时有效分辨率约21.5位,这是在不考虑外部干扰的条件下。实际测试中,如果PCB布线不合理,有效位数可能掉到17~18位,相当于温度分辨率从0.001℃恶化到0.01℃,这在HVAC恒温控制中还能接受,但对实验室级测量就是不可接收的。
我的对策是两级组合:第一级靠ADC内置的数字FIR滤波器,在20SPS速率下自动陷波50Hz和60Hz;第二级在MCU中再做移动平均。移动窗口长度取16个采样点,每个窗口覆盖16/20=0.8秒,等效带宽进一步收窄。经过两级滤波后,峰峰值噪声从±20LSB降到±3LSB,温度读数稳定在0.02℃以内波动,这个实测数据在工业论坛做过记录。
4.2 电源去耦与PCB布局实操
ADS122U04的模拟电源和数字电源分开,但单电源系统里很多人共用一个LDO,这是噪声超标的常见原因。我在这套系统中用了一颗低噪声LDO给模拟部分供电,数字部分直接用F302VC的3.3V。模拟电源和数字电源之间用电感隔离,容值上用了10μF钽电容和0.1μF陶瓷电容并联,分别覆盖低频和高频噪声频段。
PCB布局有几个具体到焊盘级的细节:RTD差分信号线要等长,走内层并排,两层板时中间要有完整GND平面,不能跨分割;IDAC输出引脚靠近RTD传感器,避免长走线引入寄生电感;采样电阻R_REF与ADC的REF引脚之间走线越短越好,过长会引入额外感抗导致比例测量失配。我第一版PCB在R_REF走线上走了5cm,实测温度在50Hz磁场环境中读数波动0.15℃,改版后缩短到1.5cm,波动降到0.02℃以下。这组对比数据可以说明布线对精度的影响有多大。
4.3 软件滤波策略与抗毛刺设计
硬件滤波做足了,软件层还是要防一手——尤其是HVAC现场会有大功率电磁阀启停、接触器通断,这些是ms级的脉冲干扰,幅度能到几伏,虽然ADC数字滤波器能压制一小部分,但偶尔还是会出现一个远离真实值的离群点。
我采用的策略是双重校验:先做个简单的中值滤波,窗口取7个点排序取中值,这能干掉明显的脉冲尖刺;然后再套一个限幅滤波——当前温度与上次采样值差超过3℃(这个阈值要通过实际工况标定)时,丢弃这次数据,保持上一次的值不变。这个限幅逻辑看着简单,但能在一次完整的数据更新周期内防止错误温度值送到PID控制器。
4.4 长时间漂移与校准周期
HVAC系统要求连续运行数月不校准,长时间漂移主要来源是采样电阻R_REF的老化、IDAC电流长期稳定性、以及ADC本身的Offset漂移。参考电阻使用金属箔电阻或精密线绕电阻,必须有低于10ppm/℃的温漂指标。IDAC电流内部的温度漂移由比例测量架构抵消,残余误差主要来自R_REF的温度漂移,所以R_REF尽量远离发热源——把这个电阻放在PCB上的LDO附近会受热,实测一台样机运行24小时后温度读数偏移0.3℃,把R_REF挪到远离LDO和电源电路的位置后降到0.05℃。
校准机制上,我在软件里配置了两个校准系数:偏移校准和增益校准。出厂前用高精度温度源做单点校准,记录修正因子存入EEPROM。实际上,这个方案对于HVAC控制精度要求(通常±0.5℃)来说,无需频繁校准,每年维护巡检时做一次零点检查即可。
5. 调试过程与排错方法实录
5.1 UART通信无响应的排查步骤
这套系统里如果UART没有响应,先从最简单的物理层查起。ADS122U04的UART是3.3V逻辑,直接接F302VC没问题,但要确认共地——我遇到过用USB转TTL调试时USB地线没接导致整个系统浮动,MCU和ADC的地之间有0.5V电位差,所有数据都错乱了。
物理层没问题后,用逻辑分析仪抓UART波形。ADS122U04的命令帧格式是:一个起始位(低电平)、8个数据位(MSB先发)、一个停止位(高电平)。波形上如果出现奇怪的中间电平,优先怀疑电平不匹配,少数USB转TTL模块是5V电平输出,会损坏ADC输入引脚或导致逻辑误判。
排除电气问题后,用示波器检查ADS122U04的上电时序。这颗芯片虽然没有严格的时序要求,但上电后必须等电源稳定后再开始操作,建议在MCU启动代码中延时100ms再初始化UART和设备,比上电立刻通信要可靠得多。
5.2 温度读数明显偏大的原因定位
如果读数比实际温度高好几度,最常见的不是计算错了,而是传感器的漏电流回路。三线制接法里,RTD的一端接到了地,导致IDAC电流不全部流过RTD,而是有一部分从地回流,相当于激励电流变相减小,电阻计算出来就偏大了。
还有一种情况是PGA增益配置错误导致读数直接偏到满量程附近。如果寄存器0设置为0x0B,实际读出原始码值却是满量程,先检查是否把命令写成了0x03而不是0x0B。寄存器的低4位是输入通道,中4位是增益,直接照抄命令写成0x0A,增益会变到4倍而不是8倍,对应电压就被截断了。建议用示波器读UART的实际写入字节,别用调试器单步追踪,实时波形比断点快得多。
5.3 温度读数跳变的间歇性故障
这种问题最折磨人,因为不是每次开机都出现。我遇到过一台原型机在运行2小时后突然读数跳变+20℃,随后自动恢复,重复出现的时间间隔逐渐缩短。最终定位原因是R_REF附近的风扇启停引起板级微振动,采样电阻引脚虚焊,接触电阻从毫欧级跃升到欧姆级,导致参考电压波动。
解决方法是补焊后涂敷三防漆固定,并把采样电阻改为双焊盘并联设计,任何一个焊盘失效系统仍能继续工作。这个教训解释了为什么工业级产品里要对精密电阻做灌封或点胶处理,而不是像实验室板卡一样裸露着。
5.4 看门狗复位与通信卡死的循环问题
F302VC与ADC之间的UART通信偶尔会因为一帧数据错位导致整个链路卡死,之后看门狗复位MCU,但复位后MCU的UART状态还停留在半帧状态下,再次通信依然失败——形成了一个复位循环。解决方式是在初始化UART时,连续发送两个0xFF字节作为同步帧头,清除ADC侧的错误状态,再发送正常命令。这相当于给通信链路做了一次软件复位,比单纯重启MCU更有效。
6. 场景扩展:从HVAC到工业现场的运用心得
6.1 HVAC场景的具体要求与配置差异
在HVAC冷热源系统里,温度测点的种类很多:供水/回水温度(通常在4~95℃范围)、新风温度(可能到-20℃)、冷凝器管壁温度(可能有腐蚀环境)。这个系统如果只配一套固定参数,根本无法覆盖这些场景。我的做法是把传感器类型、IDAC电流、PGA增益和R_REF值放到配置表中,通过上位机下发配置而不需要重新编译固件。比如PT1000传感器自热更小,允许用1mA激励,信号幅度更大,PGA增益可以降到2倍,这样整体噪声表现更优。
6.2 工业加热炉与温控回路中相同的方案
工业加热炉的温控回路对温度精度和响应速度的要求比HVAC高一个量级。虽然20SPS的数据率对温度响应足够,但PID控制器还是会被量化噪声诱导而产生微幅震荡。这种情况下我的做法是:读取原始24位码后,不急于换算成温度,而是在PID控制器中直接用原始码的残差做微分项输入,因为微分量对LSB级噪声敏感,用原始码可以避免换算过程中的舍入误差被放大。
6.3 多通道扩展思路
ADS122U04本身是单通道,但HVAC系统中可能需要8个甚至16个测点。有两种扩展方式:一是每个测点放一颗ADS122U04,全部挂同一条UART总线(芯片之间有菊花链功能),这种情况接线简单但需要合理规划时序;二是用模拟多路开关切换RTD信号,共用一颗ADC,成本低但引入开关导通电阻和热电动势误差。以我的实践来看,如果测点少于4个用多路开关没问题,超过4个就老老实实菊花链,在可维护性和稳定性上更值。
7. 关键参数速查与常见问题汇总
以下是我在多个项目里反复确认过的参数组合,直接抄作业即可:
| 参数项 | 推荐值 | 说明 |
|---|---|---|
| 传感器类型 | PT100(三线制) | 工业现场主流,-50~250℃覆盖HVAC所有场景 |
| IDAC电流 | 500μA | PT100自热小,信号充足,功耗低 |
| PGA增益 | 8倍 | 250℃时输出电压约1.5V,余量充足 |
| 数据速率 | 20SPS | 有效滤除50Hz工频干扰 |
| R_REF | 2kΩ(0.1%,25ppm) | 比例测量基准,精度直接影响整体精度 |
| UART波特率 | 115200 | 稳定、隔离器适配性强 |
| 移动窗口 | 16次采样 | 约0.8秒窗口,兼顾响应速度和平滑度 |
常见问题速查表:
| 问题现象 | 优先排查项 | 次要排查项 |
|---|---|---|
| UART无响应 | 供电电压、共地 | 波特率配置、串口命令拼接 |
| 读数固定偏大 | 三线制接线是否形成地回路 | R_REF温漂 |
| 读数波动过大 | PCB布线差分走线 | 数字电源纹波 |
| 长时间漂移 | R_REF散热位置 | IDAC老化 |
| 偶发跳变 | 焊点接触电阻 | 看门狗复位循环 |
8. 在动手前你必须知道的经验教训
这套方案我从验证板到量产迭代了三个版本,有些教训是数据手册上不会直接写的。第一,ADS122U04的UART没有硬件流控,MCU端发送命令和读取数据之间必须留出足够的延迟时间,尤其是连续读取时,DRDY信号和UART数据之间的时序关系必须先逻辑分析仪确认,否则偶尔丢掉一帧高位字节,温度会瞬间跳到满量程。
第二,别为了省成本把R_REF从2kΩ换成1kΩ。比例测量中R_REF电压降也决定了ADC输入的共模电压。R_REF为1kΩ时,500μA电流带来的压降只有0.5V,共模电压太低,PGA的共模抑制比会下降。实测在同样2kΩ改成了1kΩ后,50Hz干扰下的温度波动从0.02℃增大到0.07℃,这就是共模电压降低导致的。
第三,ADS122U04的24位数据在高增益下有噪声,这不是故障而是器件特性。我已经在前面章节说明过,有效分辨率在20SPS下大约为21.5位,所以不要因为读数的最后两三位在跳就反复调硬件滤波,这是正常现象。温度控制场景里0.001℃的波动没有任何意义,软件做移动平均到一个合理精度就可以了。
我实际体会最深的一点是:测温系统的最终精度不是由ADC位数决定的,而是从传感器焊接到布线到电源每一环加起来的效果。ADS122U04是一颗很能打的ADC,但真正拉开产品差距的,是周边那几十个无源元件和PCB铜箔的布局。把每一个环节都控制在合理范围内,这个方案在工业现场跑两三年不校准也没问题——这比单看分辨率数字有意义得多。如果后续要扩展,我建议在这个系统上加入断线检测和传感器老化诊断功能,ADS122U04的输入通道可以配置为高阻抗模式来检测开路,这是工业设备维护中非常实用的增值点。