做暖通和工业控制的同行应该都有过这种经历:空调箱机房里的温度传感器,要求看着不高,但现场环境总跟你作对。变频器一启动,接触器一吸合,显示的温度立刻跳好几个数。我上个项目就卡在送风管温度上,甲方给了个±0.2°C的指标,原来用单片机内置ADC加NTC的方案,实验室里好好的,一到设备房就现形。
后来换成标题里这套组合:ADS122U04IPWR做模拟前端,R7FA2L1AB2DFP(瑞萨RA2L1系列MCU)做控制和运算,传感器用三线制PT100。ADS122U04IPWR是一颗24位Δ-Σ ADC,自带可编程增益放大器(PGA)、内部基准和两路恒流源(IDAC),并且直接用UART跟单片机通信,这对HVAC设备来说太方便了。这篇文章就围绕这套测温前端的选型逻辑、UART驱动、RTD参数计算和现场抗干扰经验,按我实际调试的顺序一条线讲下来,希望对做工业/HVAC采集设备的工程师有点参考价值。
1. 为什么是“MCU + 独立ADC”而不是“集成ADC的单片机”:这套组合的选型逻辑
1.1 HVAC和工业测温真正要的是什么
先说需求。HVAC系统里常见的测温点包括送风/回风温度、冷冻水进出水温度、散热器表面温度,工业上还有电机轴承、变频器散热底座、流体管道壁温,量程跨度一般在-40°C到150°C,严苛一点到200°C。精度要求分两档:舒适性控制有±0.5°C就能用,但做设备验证、能效测算、工艺监测时,往往要±0.1~0.2°C。
现场条件却很残酷。设备房里变频器、接触器、电磁阀就在传感器线旁边,动力电缆动不动几十安培,传感器探头还在柜外十几米远。这种工况下,测温链路要同时解决几个问题:传感器信号很弱,PT100在0°C附近只有100Ω,温度变化0.1°C对应的电阻变化不到0.04Ω;现场有大量共模干扰,ADC输入端必须能承受一定的共模电压;还要有办法抑制50/60Hz工频干扰。
MCU内置ADC的问题在于它太“裸”了。12位分辨率在3.3V参考电压下,一个LSB就是0.8mV,对应PT100大约2mΩ,算下来温度分辨率只有0.5°C左右,这是理论值,实际噪声还会把它打得更差。更麻烦的是内部基准温漂大、没有可编程增益、多为单端输入,接差分信号还得自己搭运放。所以干这行稍微认真一点的项目,基本都会把目光投向独立ADC。
1.2 ADS122U04IPWR 真正打动人的地方
ADS122U04IPWR的几个关键点,我按重要程度排一下:
- 24位Δ-Σ架构,配合可编程数据速率和数字滤波器,对低频慢变信号非常友好。Δ-Σ的核心思路是用过采样把量化噪声推到高频,再用数字滤波器压掉,相当于给温度信号配了一副高倍放大镜加一块毛玻璃,慢慢把细节磨出来。温度变化本身就是慢信号,这正是它的主场。
- 内部集成PGA,增益1~128倍可调。PT100在100°C附近的差分电压通常只有几十到一百多毫伏,不放大直接进ADC等于浪费有效位数。
- 两路可编程IDAC恒流源,这是接RTD的关键。PT100/PT1000必须用恒流源激励才能测电阻,省掉外置恒流源电路,BOM和PCB面积都下来不少。
- 内置2.048V基准和外部基准选择,实际做高精度RTD测量时我会优先用外部基准比例式测量,后面详细讲。
- 4路输入MUX,支持差分或单端,灵活性比固定输入的RTD芯片好。
- UART接口,这是它跟ADS1220最大的区别。UART版省了SPI那几根线,隔离成本低,对HVAC这种需要传感器板和控制板分离的设备特别好用。
- IPWR后缀代表TSSOP-16封装,工业温度范围。这封装不大不小,手工焊接没问题,批量回流焊也很稳。
1.3 R7FA2L1AB2DFP 在系统里到底干什么
瑞萨RA2L1是一颗Arm Cortex-M23内核的低功耗MCU,主频48MHz。放在这里很多人第一反应是“这么低端的MCU够用吗?”我的回答是:够,而且很合适。
这套方案里,ADC把所有模拟的脏活累活都干完了,MCU只需要做三件事:通过UART向ADS122U04发命令读数据;把24位原始码值换算成电阻和温度;跑Modbus或自定义协议把温度值上报给主控/触摸屏。这些活儿Cortex-M23跑48MHz绰绰有余,Flash里存一张PT100分度表,做做查表和插值,资源也不紧张。RA2L1的UART外设数量多,一组接ADC,一组接RS485,完全够用。再加上低功耗特性,如果产品需要电池供电或待机模式,也很容易做。DFP后缀是LQFP封装,对工业产品来说焊接良率和长期可靠性都不错。
选型时我特别看重的一点是瑞萨的FSP代码生成器。SCI配置成UART、DTC搬运数据,都是图形化配置直接生成工程,比纯手写寄存器省事得多,后面移植到其他项目也方便。
1.4 几条路线摆在一起对比
| 方案 | 理论精度 | 抗干扰表现 | 开发成本 | 适合场景 |
|---|---|---|---|---|
| MCU内置ADC + NTC | ±0.5~1°C | 差,受电源和基准漂移明显 | 低 | 家用空调、低成本面板 |
| MCU内置ADC + PT100 | ±0.3~0.5°C,受MCU基准限制 | 中等,单端输入易受共模干扰 | 低 | 非严苛HVAC,仅做趋势显示 |
| ADS122U04 + RA2L1 + PT100 | ±0.1~0.2°C,配合查表和校准可更好 | 高,差分输入、数字滤波、UART便于隔离 | 中 | 工业HVAC、机组验证、精准计量 |
| 专用RTD芯片(如MAX31865) | 较高 | 中等,SPI接口隔离麻烦 | 低 | 单通道简单应用,不需要灵活配置 |
从表里能看出来,ADS122U04这套组合更适合“既要精度又要抗干扰,还准备做多类型传感器兼容”的项目。如果只是测一个点温度、成本又卡得很死,专用RTD芯片确实更快,但后面的扩展空间也小。
2. ADS122U04的UART通信与寄存器配置:从命令帧到驱动代码
2.1 为什么UART版比SPI版顺手
ADS122U04的“U04”后缀就是UART接口版,跟SPI版相比,最直接的好处是连线少。SPI至少要接SCLK、MISO、MOSI、CS四根,UART只要TX、RX、GND三根。可别小看这几根线,HVAC设备里传感器板和主控板经常隔着一两米,线少一根是一根。
更关键的是隔离。设备房里为了避免地环路和共模干扰,我习惯在UART线上加数字隔离器或光耦。SPI隔离需要隔离时钟、数据、片选至少三条高速通道,还要处理时钟偏移,成本高、麻烦。UART隔离只有两个方向,随便找一颗双通道数字隔离器就搞定,这也解释了为什么工业现场很多仪表都愿意用UART接口的ADC。
代价是速度。UART版的数据吞吐比不上SPI,但在温度测量这种20SPS都嫌快的场景里,完全不是瓶颈。另外UART没有片选线,没有硬件上的“通道仲裁”,传输层帧同步得自己操心。这是它的唯一麻烦,下面专门讲。
2.2 命令模式与数据帧:怎么保证三个字节对齐
ADS122U04的UART通信,我是按“命令+数据”的单次读取模式来用的,不让它跑连续流模式。连续模式下ADC会不停地把3字节数据推给MCU,一旦中间丢了一个字节,后面所有数据都会错位,读出来的温度可能直接从25°C跳到-50°C。现场排查这种问题特别痛苦。
单次读取模式思路很简单:MCU发送一条读数据命令,ADC把当前完成的转换结果用3字节回回来。每次读取都是完整的一问一答,天然带帧同步,不会因为丢字节导致后续数据全部错位。
这里补充两个通信细节。第一,发送命令前要确保上一条命令已经处理完,不要连续写命令,ADC不是高速设备,命令之间留一点时间更稳。第二,读回来的3字节是24位二进制补码,正满量程对应0x7FFFFF,负满量程对应0x800000。温度测量里差分电压是正的,所以读到的raw值基本是正数,但代码里最好还是做符号扩展,万一接错线、传感器开路,raw变成负值,解析才能看出来异常。
我的建议是:把传感器开路判断融进解析逻辑。raw值接近正满量程或者接近负满量程,往往意味着传感器断线或接线反了,比单纯看温度超范围更早发现问题。
2.3 寄存器配置到底改哪几位
ADS122U04内部有4个配置寄存器,每个8位。我配置PT100三线制测量时只关心以下几件事:
- 输入MUX选择:把AIN1和AIN0组成差分输入对。
- PGA增益:根据量程和参考电压算出来,后面会给完整计算。
- 数据速率:设置20SPS左右,配合内置数字滤波器抑制50/60Hz干扰。
- IDAC电流值:PT100常用1mA,PT1000可以用250µA或500µA。
- IDAC路由:一路IDAC输出到传感器激励,另一路IDAC输出到外部参考电阻。
- 基准选择:选外部基准(REFP-REFN),做比例式测量。
具体每个寄存器的位地址和二进制值,不同数据手册版本可能略有差异,我调板子时都是对照手上那颗芯片的官方寄存器表来写,网上截图只能做参考。一个容易踩的坑是MUX切换后立即读数,ADC内部模拟开关需要建立时间,切换通道后必须丢掉第一次转换结果,否则会读到上一通道的残留电压。
2.4 最小可用的C驱动代码
下面这段代码基于瑞萨FSP生成的SCI驱动接口,做了精简。配置寄存器的具体字节值我用注释说明方向,实际项目里以你手头芯片的手册为准。
#include "hal_data.h" #define ADC_UART_CMD_RDATA 0x10u /* 单次读数据命令,按手册确认 */ #define ADC_SCALE_24BIT 8388608.0 /* 2^23 */ static volatile uint8_t g_adc_buf[3]; /* 通过FSP的SCI回调,把收到的3字节存到g_adc_buf */ void user_uart_callback(uart_callback_args_t *p_args) { if (p_args->event == R_SCI_UART_EVENT_RX_CHAR) { /* 处理接收字节,这里简化成缓冲区赋值 */ } } /* 读取一次ADC原始码值 */ int32_t adc_read_raw(void) { uint8_t cmd = ADC_UART_CMD_RDATA; /* 发送读命令 */ R_SCI_UART_Write(&g_uart0_ctrl, &cmd, 1); while (R_SCI_UART_WriteComplete(&g_uart0_ctrl) != SSP_SUCCESS) {} /* 等待3字节返回,超时判断略 */ R_SCI_UART_Read(&g_uart0_ctrl, g_adc_buf, 3); /* 组装24位数据,再符号扩展 */ int32_t raw = ((int32_t)g_adc_buf[0] << 16) | ((int32_t)g_adc_buf[1] << 8) | ((int32_t)g_adc_buf[2]); if (raw & 0x800000) { raw |= 0xFF000000; } return raw; }这段代码的核心是那行符号扩展。很多新手做完(<<16)|(<<8)|(<<0)就直接当成无符号数用,传感器正常时还好,一旦接反或开路,读出来的温度会变成几十万度,明显不靠谱。加上符号扩展后,raw值从-8388608~8388607连续变化,配合上下限判断就能识别异常状态。
3. RTD温度测量链路:IDAC激励、PGA增益、参考电阻的参数联调
3.1 传感器选型与接线:两线、三线、四线怎么选
PT100在0°C时阻值100Ω,温度系数约0.385Ω/°C。它的优势是便宜、互换性好、工业标准成熟。PT1000阻值大10倍,激励电流可以更小,自发热更低,但传感器相对贵一些。NTC便宜,灵敏度极高,但是非线性大、互换性差,适合精度要求不高的HVAC面板,不太适合做±0.2°C的工程测量。
接法方面,两线制最简单,但引线电阻直接串进测量回路。举个例子:一根20米长的0.5平方毫米铜线,电阻大约0.7Ω,折算成温度就是1.8°C,直接让指标作废。所以两线制只能用在探头就在控制器旁边、线长不超过1米的情况。
三线制是HVAC和常规工业测量的主力接法。原理是两个IDAC分别提供电流,一路经过引线到RTD,另一路经过补偿引线,最终在差分测量里把两条引线压降抵消掉。四线制最准,一条电流路径一条电压检测路径,电压检测回路几乎不流电流,引线电阻完全不参与测量,但线缆成本高,一般用在计量级设备。我那个项目用三线制,因为设备房里探头到主控板也就十几米,三线制完全够用。
3.2 参数计算完整演示
我按项目实例算一遍,这套计算方法是通用的,换量程换传感器都能套。
量程设定为-10°C到110°C,PT100三线制。
第一步,用IEC 60751标准计算电阻范围。我直接给结果:-10°C时约96.09Ω,110°C时约142.29Ω。
第二步,确定IDAC电流。我选1mA。电流太小,传感器输出信号弱,分辨率吃亏;电流太大,自发热明显。1mA在PT100上的功耗是 I²R = 0.001²×100 = 0.1mW,静止空气中造成的自发热误差大约0.01~0.03°C,可以接受。PT1000的话我通常会降到250µA或500µA,因为PT1000阻值大,不需要那么大电流就能得到足够的电压。
第三步,选参考电阻Rref,让Vref落在合理的ADC输入范围。取Rref=2kΩ,IDAC电流1mA流过去,Vref=2V。这个电压低于3.3V供电,也给LDO留了压差空间。
第四步,算PGA增益。最大差分电压发生在110°C:142.29mV。ADS122U04这类ADC的线性输入范围是±Vref/Gain。增益8时满量程=2V/8=250mV,142.29mV大约用了57%的量程,既不饱和又有余量。增益16时满量程=125mV,直接饱和。所以增益定在8。
第五步,算理想分辨率。1个LSB对应的输入电压= Vref/(Gain×2^23) = 2/(8×8388608) ≈ 29.8µV。再除以1mA激励电流,得到电阻分辨率约29.8mΩ,对应温度约0.077°C/bit。这是纯理论量化分辨率,实际噪声会比这差,但配合20SPS的数字滤波和多次平均,把温度做到0.01~0.03°C的有效分辨率是现实的。
这套计算做完,硬件参数才能真正定下来。我见过不少人跳过这一步,PCB都画好了才发现增益选太大导致高温段饱和,只能飞线改参考电阻,非常被动。
3.3 从ADC码值反算电阻和温度
因为用了比例式测量,从raw反算电阻的公式非常干净:
[ R_{rtd} = \frac{raw \times R_{ref}}{Gain \times 2^{23}} ]
这个公式成立的前提是两个IDAC电流相等,且Vref来自同一个参考电阻上的压降。比例式测量的妙处在于,就算Vref因为电源波动漂了一点,raw值和Vref是同时变化的,最终比值基本不变,等于把基准误差自我抵消了。这就是为什么我坚持用外部Rref而不是内部基准。
C代码实现:
double adc_raw_to_ohm(int32_t raw) { const double rref = 2000.0; /* 2k 参考电阻 */ const double gain = 8.0; /* PGA 增益 */ return (double)raw * rref / (gain * ADC_SCALE_24BIT); }拿到电阻之后,温度计算分两条路:要么查标准分度表,要么用Callendar-Van Dusen方程迭代反解。查表最简单,把-40°C到200°C的电阻值存成数组,二分查找加线性插值,误差可以做到0.01°C以内。我实际用的是二分迭代法,因为代码量比大表格小,逻辑还清晰:
double pt100_ohm_to_temp(double r) { double lo = -40.0, hi = 200.0; for (int i = 0; i < 40; i++) { double mid = (lo + hi) / 2.0; double rm = pt100_res_from_temp(mid); if (rm < r) lo = mid; else hi = mid; } return (lo + hi) / 2.0; }pt100_res_from_temp是标准CVD方程的正向计算函数,参数用IEC 60751那组A/B/C就行。40次迭代足够把温度收敛到小数点后好几位了。
3.4 非线性校正:不是可选项,是必选项
PT100如果不做非线性校正,直接用“100Ω + 0.385Ω/°C”的直线公式,在0~110°C范围内最大误差约有0.3~0.4°C。我们目标±0.2°C,这显然超了。IEC 60751标准给出了Callendar-Van Dusen方程:
[ R_t = R_0 \left[ 1 + A t + B t^2 + C(t-100) t^3 \right] ]
对0~850°C范围,A=3.9083e-3,B=-5.775e-7,C=0。如果需要覆盖负温段,C的取值会不同,要看标准表格。这个方程的正向计算很简单,反向求温度就用上面的二分迭代。把这一步做进去,非线性误差立刻压到0.01°C量级。
4. 现场级的抗干扰与精度校准:HVAC和工业柜里的真实考验
4.1 电源、地环路与UART长线隔离
HVAC设备里最要命的是电源噪声和地环路。变频器启停瞬间,母线上会有很大的dv/dt,如果AVDD直接取自系统开关电源,ADC的参考电压和模拟电源都会跟着抖,温度数据就是一串毛刺。
我的做法是模拟部分单独用一颗低噪声LDO,输入侧加一个π型LC滤波器(磁珠+电容)。LDO选型时注意噪声指标和电源抑制比,别为了省成本在模拟电源上抠门。实测下来,供电从DC-DC直供改成LDO+LC之后,温度数据抖动从±0.3°C降到±0.02°C,效果非常直观。
UART长线一定要隔离。主控板到传感器板如果共地,地环路上的电流会直接注入模拟地,ADC输出全乱。我在这套方案里用双通道数字隔离器,成本不高,效果立竿见影。选UART接口ADC的好处这里体现出来了:两个隔离通道就够,SPI方案至少三个,而且线速高、时序要求严,隔离器还贵。
4.2 PCB布线与屏蔽层处理的几个习惯
布线上我坚持几条原则,都是踩过坑换来的:
- 参考电阻Rref要靠近REFP和REFN引脚,走线短粗。Rref的电压就是ADC的测量基准,如果这里被噪声污染,后面全白搭。
- 差分输入对要平行走线,中间不要跨过别的信号,尤其不能跨数字信号。差分对之间可以加一点间距,但别让数字线从中间穿。
- 传感器线走屏蔽电缆,屏蔽层在控制柜端单点接地,不要两端都接。两端接地容易形成工频地环路,反而引入50Hz干扰。
- 传感器接线端子加TVS和ESD保护,现场带电插拔很常见,不加保护坏一次就够回不了本。
4.3 上电时序和自校准:没踩过三个坑不算做过测温
第一个坑是上电后立刻读数,前几个数据严重偏离真实值。原因不复杂:内部基准、IDAC电流源都需要建立时间。我现在的处理是上电后至少等100ms,再把前5次转换结果全部丢弃,从第6次开始纳入平均。千万别把前面的坏数据平均进去,那会拉歪整条校准曲线。
第二个坑是连续读模式丢字节。前面说了,连续模式下3字节流一旦失去同步,温度会突然跳到离谱值。我后来彻底改用单次读模式,每次一问一答,至少不会一错错到底。
第三个坑发生在做SYSOCAL自校准的时候。ADS122U04支持系统失调校准命令,但它需要正确的输入状态,如果传感器没接好就跑校准,校准完的零点就是错的,后面测什么都是偏移的。校准设备状态必须稳定,校准期间不允许切换通道或改变PGA增益。
4.4 校准流程与实测数据对比
实验室校准流程我一般这样走:
- 用0°C冰水混合物作为第一个标准点,或者用恒温槽更稳。
- 用100°C沸水或恒温槽作为第二个标准点。
- 根据两点实际读数和标准温度,计算线性修正系数:T_corr = T_raw × K + B。
- 再用25°C和50°C的点做验证,看修正后是否落在指标内。
我这里列一组典型的实测对比数据,来说明校准的必要性:
| 标准温度 | 校准前计算值 | 校准后计算值 |
|---|---|---|
| 0°C | -0.07°C | +0.00°C |
| 25°C | +0.12°C | -0.01°C |
| 50°C | +0.18°C | +0.01°C |
| 110°C | +0.35°C | +0.02°C |
校准前110°C处误差到了0.35°C,这就是PT100非线性累积的后果。做完两点线性校准之后,全量程误差压到±0.02°C附近,满足±0.2°C的指标轻轻松松。但要注意,两点校准主要修正的是增益和零点,非线性残余还需要靠前面的查表/CVD方程处理。先做非线性校正再做线性修正,顺序不能反。
5. 除了PT100,这套前端还能怎么复用:一组值得收藏的扩展思路
5.1 换成NTC、热电偶,甚至用内部温度传感器
ADS122U04的MUX、PGA和IDAC都是可配置的,所以这前端不是只能接PT100。接NTC时,把IDAC电流调到100µA左右,PGA增益调高,用Steinhart-Hart方程或查表标定,精度可以做得比普通NTC方案高很多。接热电偶时,PGA增益要打到64或128,冷端补偿可以用ADS122U04内部集成温度传感器来参考,避免外置冷端补偿芯片。当然热电偶本身的非线性误差和冷端补偿精度会限制最终表现,但起码这套前端不用换硬件就能调过去。
5.2 多通道扩展:MUX切换和稳定时间
ADS122U04内部4输入MUX可以支持2路差分或4路单端。实际用下来要记住一件事:MUX切通道后必须等模拟前端建立稳定再读,不能切完立刻发读命令。我最初切换后直接读数,结果读到的是上一通道的残留值,后来在切换和读取之间加了足够延时才解决。多通道如果共用Rref,通道间的串扰和参考电流路径也要仔细核算,最简单的办法是每个通道都配置一遍相同的寄存器参数,确保切换后状态完全一致。
5.3 与上位机、总线的对接方式
这套组合在系统里最好用的点是“模拟前端”和“协议处理”完全解耦。RA2L1把温度解析成工程量之后,通过另一组UART加RS485收发器跑Modbus RTU,PLC和上位机直接就能读。FSP生成的UART驱动上手很快,协议状态机自己写或者用现成库都行。整个结构后期改传感器类型、改量程,只需要改前端配置,不用动上层协议,维护成本一下子下来很多。
如果你也准备做这类项目,我建议第一步先在开发板上用杜邦线把UART读数和RTD计算跑通,再做PCB。先验证通信后画板,能省掉大量查线查时序的时间。温度测量这东西,芯片选对了,计算做对了,剩下的功夫基本都花在跟干扰较劲上,这恰恰是别人最不容易复制的部分。