最近帮朋友调一套旧项目的温度采集模块,PLC那边显示屏上温度值乱跳,现场工程师换了好几根传感器线都没用。最后查到底,发现压根不是传感器的问题——原采集板用的是单片机内置的12位ADC,传感器信号在车间里拉了十来米,干扰全串进来了,换上一颗外置高精度ADC,问题当场消失。这类场景在工业和HVAC项目里很典型,也是我今天想聊的主题:用TI的ADS122U04IPWR这颗24位Δ-Σ ADC,配合STM32F411RE单片机,搭建一套稳定、抗干扰、同时支持RTD和热电偶等主流温度传感器的测量方案。
这颗ADS122U04IPWR最吸引我的地方,是把ADC的输出接口做成了UART,而不是常见的SPI或I2C。UART在长线上比SPI稳得多,布线少、抗干扰强,而且要做电气隔离时只需要隔离一对收发信号,成本直线下降。配合STM32F411RE这颗主频100MHz的Cortex-M4F,算力足够处理24位数据的滤波、线性化和冷端补偿,整体方案的性价比和可维护性都不错。
这篇文章适合正在做工业温度采集、HVAC(供暖、通风与空调)控制系统、RTD变送器,或者单纯想把ADC采样精度从“能看”提升到“能信”的开发者。我按硬件电路、软件协议、校准实测、踩坑记录几个维度展开,全程基于实际项目经验,不整虚的。
1. 先搞清楚ADS122U04IPWR这颗UART接口24位ADC的价值
1.1 为什么设计成UART接口?
选ADC之前,先弄清楚ADS122U04到底解决了什么问题。
传统的高精度ADC,包括TI自家很经典的ADS1220,用的是SPI接口。SPI在PCB板内通信完全没问题,速度快、协议简单,但信号一旦要走线缆、要穿过变频器柜、继电器柜,麻烦就来了:SPI的CLK和MISO/MOSI总线容易被干扰,线一长还容易出现信号完整性问题,布线也占地方。更麻烦的是,如果系统需要做电气隔离,SPI要隔离的通道太多,光耦或数字隔离器成本直接翻几倍。
ADS122U04IPWR把这个痛点直接解决了。它内部把转换数据通过UART输出,只需两根线(SIN和SOUT)就能完成双向通信,算上地线一共三根。接线少意味着隔离成本低,长线传输时UART比SPI稳得多。我当时的应用是把传感器模块放在车间A端,控制板放在车间B端,中间隔了十几米,UART走9600波特率,配合屏蔽双绞线,数据一次都没丢过。
另外,UART协议本身是异步的,没有共享时钟线,发射机和接收机只需要约定波特率。这在工业现场强干扰环境中,天然少了一条受干扰路径,比带时钟线的同步接口稳健。
1.2 内部架构与选型关注点
从结构上看,ADS122U04IPWR是一个完整的模拟前端,不只是一颗裸ADC。它内部包含了:
- 4通道输入多路复用器(MUX),可配置成差分或单端输入;
- 可编程增益放大器(PGA),增益1到128可调;
- 24位Δ-Σ调制器加数字滤波器;
- 两个可编程恒流源(IDAC1、IDAC2),专门给RTD提供激励电流;
- 内部基准电压源(典型值2.048V);
- 一个精密内部温度传感器,用来做热电偶冷端补偿;
- 热电偶开路检测(Burnout)功能。
先放一张参数速览表,方便快速抓重点:
| 特性 | ADS122U04IPWR | 说明 |
|---|---|---|
| 分辨率 | 24位 | Δ-Σ架构,过采样 |
| 模拟输入 | 4路 | AIN0~AIN3,差分或单端 |
| PGA增益 | 1~128 | 热电偶mV级信号直接放大 |
| 内部基准 | 2.048V | 也可外部基准 |
| IDAC | 2路可编程恒流源 | RTD激励,比例测量 |
| 数据速率 | 最高2000SPS | 可配置,支持50/60Hz抑制 |
| 输出接口 | UART | 无同步时钟线 |
| 温度范围 | -40℃~+125℃ | IPWR后缀即工业级 |
选型时最容易忽略的是基准和电流源的配合关系。如果只用内部2.048V基准,测RTD时要算好IDAC电流在参考电阻上的压降,不能超出基准范围。比如IDAC选500μA,RREF选2kΩ,基准压降就是1V,不会顶到2.048V,这是安全设计。这样做的目的,是让ADC的满量程输入范围在测量范围内留40%~50%余量,避开非线性段。
1.3 传感器兼容性:RTD、热电偶与NTC一把抓
ADS122U04IPWR能直接接三种最常见的温度传感器:
- RTD(热电阻):铂热电阻Pt100/Pt1000都能接,支持2线、3线、4线接法。这是工业和HVAC里用得最多的传感器,线性好、精度高,覆盖-200℃~850℃。
- 热电偶:K型、J型、T型都能测。原理是测量两种金属连接处的温差电动势,信号只有几十微伏每摄氏度,特别依赖PGA放大和冷端补偿。
- NTC/PTC热敏电阻:HVAC室内机、新风机里非常常见,用恒流源配合外部电阻分压就能测,电路更简单,精度取决于NTC的B值精度和校准。
也就是说,同一颗ADC,通过改配置寄存器里的MUX、PGA和IDAC设置,就能无缝切换传感器类型。这对做多通道采集板或变送器非常友好,一个硬件平台打天下。
2. 硬件电路:STM32F411RE与ADS122U04IPWR的连接细节
2.1 电源、基准与地的处理方式
电源方案先明确。STM32F411RE是3.3V供电,ADS122U04IPWR的AVDD和DVDD都接3.3V没问题,但要注意上电时序:AVDD要先稳定,DVDD不能先上电,很多ADC都有类似要求。模拟供电和数字供电不能直接拿同一根粗线拉过去,标准做法是:
- STM32的VDD从3.3V主电源直接取;
- ADS122U04的AVDD经过一级RC滤波,通常10Ω电阻串联,加10μF钽电容并联0.1μF陶瓷电容到地;
- DVDD可以从相同电源取,但尽量在靠近DVDD引脚处加磁珠或0Ω电阻隔离。
这样做的核心目的,是把ADC的模拟电源和MCU数字开关噪声隔开。24位ADC的噪声底非常低,如果数字部分在同一平面直接耦合到模拟电源,最后测出来的噪声会莫名其妙高几个微伏。
地线方面,原则是模拟地和数字地单点连接,通常就在ADS122U04的电源地焊盘附近用一个0Ω电阻连接,或者做成星形接地。实测下来,单点接地的效果比铺一大片混接更好,尤其在有电机、继电器开关的环境里。
2.2 三线/四线RTD接法及比例测量原理
RTD测量最核心的设计理念是比例测量(Ratiometric Measurement)。这句话值得反复说,因为它是整个RTD精度稳定性的基础。
所谓比例测量,就是让IDAC电流同时流过参考电阻RREF和Pt100电阻,ADC的基准电压不用内部2.048V,而用RREF上的压降,然后测量RTD的压降与RREF压降的比值。由于两个电压由同一个电流源产生,电流源的绝对值、漂移、温漂全部被抵消。只要RREF本身是低温漂、高精度的,测量结果几乎不受电流源影响。
3线RTD接法实质是:两个IDAC分别接到RTD引线的两端,目的是让流经每条导线的误差电压互相抵消。差模信号只与RTD电阻成比例,公共导线电阻引起的压降在差分测量中被减掉。4线接法更简单,两根线注入电流,另外两根SENSE线直接测量RTD两端电压,SENSE线上没有电流,导线电阻带来的误差完全消失。4线是实验室高精度标准,3线在工业现场已经够用,但要注意选择相同材质、等长的导线。
RTD激励电流的选择也值得说:Pt100常用250μA,太小信号幅度不够,太大自热误差明显。250μA在Pt100上产生的信号,0℃时是100Ω×250μA=25mV,配上PGA=16倍,得到400mV级别的ADC输入,充分利用了2.048V基准的测量范围,精度足够好。
2.3 热电偶接入与冷端补偿的电路布局
热电偶的特点是输出信号极微弱,K型约41μV/℃,而且测的是温差电动势。所谓冷端补偿(Cold Junction Compensation,CJC),是指热电偶测量端的电压总是相对于冷端(即接线端子处)的,而冷端温度会波动。要让结果等于绝对温度,必须测量冷端温度,把这个温度对应的热电动势补回去。
ADS122U04内部集成了精密温度传感器,可以直接用来做冷端补偿,省一颗外部传感器。但实际装机时要注意两点:
- 热电偶接线端子(冷端)要紧贴ADS122U04芯片,且两者尽量处于同一热质量块上,避免温差。PCB上大面积覆铜可以辅助均温,但不要让继电器、变压器这类大电流器件离它太近。
- 内部温度传感器的精度是有限制的,典型绝对精度在±0.5℃级别。如果项目要求冷端补偿误差控制在±0.1℃以内,建议外接一颗高精度数字温度传感器,比如TMP117(±0.1℃),放在冷端端子旁边。
硬件上,热电偶两脚直接接AIN2(+端)和AIN3(-端),PGA选32或64,同时开启开路检测电流。一旦热电偶断线,输出电压被拉向已知电平,软件就能立刻报出“传感器开路”。
2.4 EMC与布线:工业现场的常见坑
工业现场最大的干扰源有三个:变频器谐波、继电器开关电弧、电机换向噪声。这三样东西都能让24位ADC的读数瞬间从0.1℃跳到10℃甚至溢出。布线教训总结如下:
- 模拟输入端加一级RC低通滤波。RTD通道串100Ω~1kΩ电阻,并联1nF~10nF电容。注意电容太大会影响ADC输入建立时间,数据速率低时电容可以大一点。
- 热电偶输入本身是低电平信号,更要严防漏电流。PCB走线若较长,走线内侧不能有数字信号穿越,外围铺模拟地环行屏蔽。
- UART的SIN/SOUT走线对称平行,不要与电源线长距离并肩走。
- 电气隔离视情况而定。车间里两设备地电位差可能达几伏甚至几十伏,如果两者之间没有隔离,乱接地的后果是共模电压烧芯片。低成本方案是UART用光耦隔离或电容隔离芯片(如ISO7721),配合隔离电源,效果立竿见影。这也是选UART接口ADC的重要理由——隔离只需处理一对线。
3. 软件协议:让STM32F411RE把ADS122U04IPWR指挥明白
3.1 命令字与数据输出格式
ADS122U04的通信风格非常像“寄存器式数字传感器”——所有操作都靠UART收发命令字节。最常用的命令如下(具体字节值以最新版数据手册为准,务必核对):
| 命令 | 字节 | 功能 |
|---|---|---|
| NOP | 0x00 | 空操作,清理总线 |
| RESET | 0x06 | 软复位所有寄存器 |
| START | 0x08 | 开始转换 |
| POWERDOWN | 0x02 | 进入低功耗模式 |
| RDATA | 0x10 | 读取一次转换结果(24位) |
| RREG | 0x20+地址 | 读取寄存器 |
| WREG | 0x40+地址 | 写入寄存器 |
输出数据是24位二进制补码,最高位是符号位。UART一帧传3个字节,MSB在前。实践上几乎所有驱动都是先发RDATA命令,然后连续收3个字节拼成一个int32。
3.2 初始化配置寄存器:一个实战例子
ADS122U04通常有4个配置寄存器,分别控制输入MUX、PGA增益、数据速率、滤波器模式、基准选择、IDAC设置、开路检测、转换模式。配置流程的C代码框架如下:
uint8_t config[4] = {0}; // 配置寄存器0:AIN2=热电偶+,AIN3=热电偶-,PGA=32倍 config[0] = (0x02 << 5) | (0x03 << 2) | (0x05); // 按手头手册位定义填 // 配置寄存器1:连续转换模式,数据速率=20SPS,使能50/60Hz滤波器 config[1] = 0x00; // 需按手册位定义设置 // 配置寄存器2:IDAC1开启,输出250uA,开启热电偶开路检测 config[2] = 0x00; // 配置寄存器3:IDAC1路由到AIN0,IDAC2路由到AIN2 config[3] = 0x00;实际操作有几个要点:
- 写配置寄存器建议一次写完整组,避免中间状态产生误转换。
- 写寄存器最好在POWERDOWN状态下完成,配置完再START,否则转换可能以旧配置进行,产生莫名数据。
- 读取数据要等转换完成。最简单的办法是查询式UART读数据,配合转换周期定时器延时。
很多工程师踩过的坑,是网上的旧驱动寄存器位定义和手头新版手册对不上,结果读出完全错误的数据。严谨起见,寄存器位域必须以你手里的最高版次手册为准。
3.3 RTD温度换算的完整流程
拿到ADC的24位原始码,不能直接当温度用。前面讲了比例测量的物理基础,换算公式非常优雅:
Rrtd = (raw_code / 2^23 - 1) × RREF代码里要注意:raw_code是二进制补码,需要转成有符号int32;2^23-1即满量程理想码8388607。
完整流程是:
- 读3字节,拼成int32,做符号扩展;
- 计算电阻值Rt;
- 用Callendar-Van Dusen方程反算温度。方程对铂电阻通用:
Rt = R0 × [1 + A×T + B×T² + C×(T-100)×T³]其中R0=100Ω(Pt100),A=3.9083e-3,B=-5.775e-7,C在0℃以上为0,0℃以下为-4.183e-12。0~850℃范围C=0,方程是二次的,反解直接用求根公式;-200~0℃要带C项,做迭代或查表。工业/HVAC多数场景温度都在0℃以上,直接用二次反解精度足够。
下面这个C函数展示基本思路:
float rtd_raw_to_temp(int32_t raw, float rref) { int32_t signed_raw = raw; if (signed_raw & 0x800000) { signed_raw |= 0xFF000000; } float rt = (float)signed_raw / 8388607.0f * rref; // Pt100 正温区二次求根 const float R0 = 100.0f; const float A = 3.9083e-3f; const float B = -5.775e-7f; float disc = R0*R0*A*A - 4.0f*R0*B*(R0 - rt); if (disc < 0) return NAN; return (-R0*A + sqrtf(disc)) / (2.0f*R0*B); }工程上直接查表+线性插值更稳健。查表法不怕负温,不需要解方程,也省浮点运算。F411是M4F内核带FPU,浮点不心疼,但如果代码要移植到低端MCU,查表插值就很香了。
3.4 热电偶线性化与冷端补偿的实现
热电偶处理复杂一些,因为它测的是电势差,要得到真实温度,要走“热电动势-温度”的转换路径:
V_total = V_measured + E_cold_compensation T = f(V_total) // NIST查表或多项式具体步骤:
- 读ADC原始码,计算实际测到的热电偶电压V_measured。注意要把PGA增益滚回:V = code × Vref / (Gain × 2^23)。
- 读取冷端温度Tcjc:用ADS122U04内置温度传感器,或外置数字传感器。内置温度传感器的读法,一般是切换到内部温度测量通道,再做一次转换。
- 查冷端温度对应的标准热电动势E(Tcjc),通过查表或多项式。
- 相加得到总电动势E_total。
- 用反向多项式或查表求温度T。
NIST的ITS-90多项式在高精度要求下用分段多项式(8阶以上)。常见做法是把多项式系数压缩在const数组里,覆盖-200~1372℃(K型)。代码结构参考:
float temp_from_voltage(float voltage_mv, int type) { // 分段多项式反查温度 return t; } float cjc_temp(float voltage_mv_measured, float tcjc_c, int type) { float e_cold = volts_from_temp(tcjc_c, type); float e_total = voltage_mv_measured + e_cold; return temp_from_voltage(e_total, type); }写这块时,一定要把热电偶型号与标准分度表做一遍回归测试,务必用官方标准生成器校验系数。网上的系数抄来抄去常有印刷错位,我吃过一次亏,差了好几度。
4. 实测与校准:从“能出数”到“测得准”
4.1 噪声表现与数据速率怎么取舍
先泼冷水:ADS122U04是24位ADC,但24位是全分辨率标称值,工程上说的“无噪声分辨率”要小得多,噪声底取决于数据速率、PGA和滤波。手册里有一张噪声与数据速率关系表,这表建议收藏,每次选型都翻出来看。
以我实测经验,PGA=16、20SPS、SINC3滤波,RTD通道有效无噪声分辨率大约在18位左右,换算到Pt100测温,大约0.002℃~0.005℃跳动,这已经非常优秀。追求极致噪声就把数据速率降到5SPS,噪声还能下去一截,响应变慢一些。HVAC控制回路不差这100ms,工业高精度计量也不差这两百毫秒,所以普遍愿意牺牲速度换噪声。
如果现场存在50Hz工频干扰,一定要使能50/60Hz抑制滤波器,且数据速率选整倍数(20SPS、10SPS、5SPS都是50Hz的整数倍关系),实测能把工频干扰压下去90%以上。很多新手忽略这一点:明明用了24位ADC,读数还是跳,结果发现工频干扰没滤掉。
4.2 两点校准与多项式补偿
数学上再漂亮的公式,也架不住器件实际误差。同一批次的ADS122U04和STM32F411RE,焊在板子上之后,参考电阻RREF真实阻值、PGA增益误差、PCB压降,都会引入系统误差。工程上必须做校准。
RTD通道最基础的是两点校准:
- 把标准100Ω精密电阻接到信号输入端(模拟0℃),记录ADC读数raw_0;
- 接标准138.51Ω电阻(对应100℃的Pt100),记录raw_100;
- 对ADC读数做线性校正:offset = raw_0,gain = (raw_100 - raw_0) / 100;
- 后续温度计算就是(raw_now - offset) / gain。
实测校准后,系统绝对误差能从±2℃收敛到±0.2℃以内,前提是参考电阻RREF选型到位。
热电偶通道的重点是冷端补偿校准。做法:把热电偶探头和标准铂电阻同时放进恒温槽,对比实际温度与ADC计算温度,将差值折算为冷端温度偏移修正量。这一招把我现场遇到的一个“0℃点偏移0.8℃”问题直接修掉了。
4.3 长期稳定性与温漂处理
24位系统的精度是设计出来的,但真正考验是长期漂移。几个点值得写进维护手册:
- 参考电阻RREF是比例测量的定盘星,选金属箔/薄膜电阻,精度0.1%,温漂≤5ppm/℃,否则校准再准,温度一变误差又回来。
- 板上焊接应力会引入微弱电阻漂移,校准用的RREF要远离热源,焊完避免反复热冲击。
- 软件里做周期性自校准:通过继电器切换回路,定期切换到接地通道测偏移,切换到内部基准通道测增益,自动修正。这是高端变送器的常见套路。
4.4 HVAC与工业场景的实测差异
同一套板子,在HVAC和工业现场表现完全不同。
HVAC环境相对干净:温度范围窄(-10~50℃),电磁干扰少,电源稳定。主要矛盾是成本和功耗。ADS122U04的低功耗模式就很适合新风系统、楼宇自控里电池供电或总线供电的温度探头。
工业环境残酷得多:宽温(-40~85℃甚至更高)、强电磁干扰、长线传输。实测里,同样的配置,在工厂车间读数比实验室多跳一个数量级。解决手段通常不是改软件,而是改硬件——加输入滤波器、屏蔽线、隔离。
5. 踩坑记录:UART通信与数字滤波的几个真实问题
5.1 UART收发不稳定的排查链路
第一次调试时,STM32F411RE和ADS122U04的UART通信偶尔丢字节,一丢字节读数就变满码。排查链路是这样的:
- 先查波特率误差。STM32用内部HSI时钟时误差有±1%~2%,在较高波特率下直接导致UART字节错位。改用外部8MHz晶振后,问题明显缓解。F411RE的USART对时钟源精度敏感,这是最先该怀疑的点。
- 看波形质量。用示波器抓SIN/SOUT波形,看是否过冲、回沟。长线上串33Ω~100Ω电阻抑制反射,效果立刻提升。
- 量地电位差。万用表测两板之间地电位差,如果超过±0.5V,说明共模噪声严重,要么短粗线接地,要么上隔离芯片。我用过ISO7721隔离UART,从此没再丢过字节。
5.2 配置了PGA但读数浮动的根因
有块板子,开启PGA=128之后读数一直往上漂。最后定位是PGA的输入偏置电流在温度变化时,和输入RC滤波电阻相互作用,产生额外电压偏置。解决办法是尽量降低输入串阻,比如从10kΩ降到1kΩ,或者在软件里补偿偏置电流带来的固定偏置。低增益时几乎没感觉,高增益一开就原形毕露。
5.3 冷端补偿飘移:内置温度传感器与外置的取舍
有个项目同事图省事,直接用ADS122U04内置温度传感器做热电偶冷端补偿,结果冬天校准好的数据到夏天又偏了1℃多。查下来不是内置传感器精度不够,而是冷端温度传感器和热电偶接线端子之间的温差大,热路径设计不对。
后来在PCB上把热电偶接线端子直接靠近芯片,放在同一个热焊盘区,再补一颗外置高精度数字温度传感器做对比,发现内置传感器校准后完全够用。我的建议是:先确认热耦合路径,确保“端子温度=芯片温度”成立,再谈传感器精度。温差存在,用什么传感器都白搭。
6. 个人体会与一个实用扩展
这套方案目前稳定跑了小半年,在HVAC分户计量和工业设备状态监测两个领域都用上了。最有价值的一点是,UART接口的ADC把“高精度”和“长距离”这两个以前互相矛盾的需求,用很朴素的方式统一起来。不用SPI长距离隔离,不用额外模拟量变送器,一颗芯片加两颗MCU引脚,就能把24位精度的温度数据拉到几十米外。
最后分享一个小技巧:如果项目里既留了RTD通道又留了热电偶通道,可以在PCB上设计一个公共参考电阻网络,用两个IDAC分别驱动两个通道。这样代码里切换传感器类型时,基准值始终一致,省去二次校准。另外,调试时遇到读数全满或全零,先怀疑UART配置和寄存器字节序,别急着怀疑芯片坏了——这一条经验,每次都能少折腾半天。
如果你的项目也卡在“ADC精度上不去”或者“长距离温度传输不稳”这两个问题上,建议试试这个组合,先把本文的硬件连接和初始化流程跑通,剩下的细节,基本就是以手册为准、以实测为准的体力活了。