☰
STM32F429与ADS122U04多类型温度采集方案设计
2026/11/5 3:16:57 网站建设 项目流程

做工业温度采集的老伙计们,估计对ADS122U04IPWR不陌生——TI这颗24位、带UART接口的精密ADC,在温变、HVAC温度模组里出现的频率相当高。我手上的项目刚好是拿STM32F429NI做主控,配上它搭一套多通道温度测量模块,同时覆盖PT100、K型热电偶和NTC三类传感器。今天把这套方案从选型、硬件、软件到调试踩坑完整梳理一遍,给正在做类似东西的朋友一个可直接参考的样本。

这个组合解决的典型问题很明确:工业现场和暖通空调系统里,温度测点分散、传感器类型多样、信号需要长距离传输,而且控制器和传感器之间往往隔着不小的电气噪声。如果用常规ADC直接采,布线、抗干扰、精度都是难题。ADS122U04把高精度转换和传感器激励都集成了,STM32F429NI负责数据处理和对外通信,各干各的活,一起把“多类型温度传感器统一采集”这件事做成一个标准模组。

1. 项目概述与选型思路

1.1 这套组合解决什么问题

先说场景。工业环境里常见的温度采集需求大概分三类:

  • 测RTD(最常见是PT100/PT1000),用于电机绕组、管道表面、设备轴承等位置,测量范围通常在-50°C到+300°C,要求精度0.1°C级别。
  • 测热电偶(K型居多),用于炉温、烟气温、高温工艺段,测量范围可能到+800°C甚至更高,精度要求相对宽松但必须做冷端补偿。
  • 测热敏电阻(NTC 10K/100K),多用于HVAC的风管温度、回风温度、房间温度,对精度要求不高但成本敏感、数量多。

ADS122U04IPWR这种ADC好就好在它把这三类传感器的模拟前端全部内置了——内部有可编程增益放大器(PGA)、两个可编程电流源(IDAC)、内部参考电压、内部温度传感器。也就是说,传感器可以直接挂在ADC输入引脚上,不需要额外搭恒流源电路、仪表放大器电路,外围极其干净。

STM32F429NI在这套系统里的角色是主控和信息枢纽。它通过UART和ADC通信拿原始数据,完成温度换算、滤波、校准、断线判断,然后把结果通过RS485/Modbus、CAN或者以太网发出去。如果后续项目要带本地显示,F429NI自带TFT-LCD控制器,升级成带屏的温控面板也不需要换主控。

1.2 为什么选这两个核心芯片

选ADC的时候,我对比过ADS1220(SPI接口版)、ADS1248(8通道高配版)和国产的一些24位ADC。最终定ADS122U04IPWR,核心原因是它带UART接口,而且整帧通信带CRC校验。这一点在工业场景里比SPI有优势,后面单独讲。

另外一个原因是ADS122U04功耗低、启动快,非常适合做需要轮询多路传感器的模块。它的单次转换时间最快能到毫秒级,做8路以内的温度采集完全够用。

STM32F429NI这边,很多人会觉得用F103就够跑温度算法了,确实够,但我选F4是有具体考虑的:

  • F429NI是180MHz的Cortex-M4,带FPU。温度换算里大量用到浮点运算,特别是热电偶查表插值、RTD多项式反算,FPU能把计算时间压到微秒级。
  • 它资源丰富,8个UART、2个CAN、以太网MAC,后续做多协议网关不用换硬件。
  • 温度采集经常需要做数据记录和曲线显示,F429NI的2MB Flash、256KB RAM,加上LCD控制器,预留了很大的扩展空间。

1.3 UART接口比SPI好在哪

这是这套方案一个常被忽略的亮点。ADS122U04用的是UART命令帧协议,每次通信固定8字节,最后带一个CRC8。这和SPI最大的区别在于:SPI需要SCLK、MISO、MOSI、CS四根线,而且CS片选信号在长距离传输和电气隔离场景下容易出问题;UART只需要TX和RX两根线,波特率不高时一米两米完全没问题,要做隔离也就是两个光耦的事,非常简洁。

更关键的是,SPI通信一旦时序受干扰,数据位错乱,很难自动恢复;UART加上帧同步+CRC校验,一旦出错可以直接丢弃帧、重新同步,协议层就能保证通信可靠性。这在工业现场那种变频器、继电器频繁动作的电磁环境里很重要。

实测下来,我在这套系统上用9600波特率通信,线长做到1.5米(普通双绞线),连续运行一个多月,没有出现一帧误码没被检出的情况。被CRC拦下来的错误帧有一些,但协议自动恢复了,用户层面完全无感。

2. 硬件设计:从探头到主控的完整链路

2.1 三类温度传感器的接入方式

ADS122U04有4个模拟输入通道(AIN0-AIN3),可以通过寄存器配置成差分输入或单端输入。我实际接法是:

  • PT100用差分方式接到AIN0和AIN1,由IDAC1提供1mA恒流激励,流过PT100后在两个引脚之间产生电压差,这就是测量信号。选择1mA而不是2mA或者更高的激励,主要是为了控制自热效应——PT100在1mA下自热误差通常不超过0.1°C,而2mA下自热会明显增大。

  • K型热电偶用差分方式接到AIN2和AIN3。热电偶信号本身是毫伏级,不需要激励电流,接上就能测。但冷端补偿必须做,我用的是ADS122U04内部温度传感器,它会输出一个代表芯片结温的代码,结温基本等于冷端温度,这样省掉一个外接NTC,电路更简单。

  • NTC热敏电阻可以接在空闲通道上,用IDAC2提供一个小电流(比如50µA),NTC两端电压会随温度变化。这个方案适合HVAC低成本场景,而且NTC阻值高,长线传输时线阻影响小。

传感器类型 | ADC通道 | 激励方式 | 典型增益 | 测量范围 | 典型精度 PT100 | AIN0-AIN1差分 | IDAC1=1mA | 8倍 | -50~+300°C | ±0.2°C K型热电偶 | AIN2-AIN3差分 | 无激励,内部冷端补偿 | 128倍 | 0~+800°C | ±1.5°C NTC 10K | AIN0-AIN3剩余通道 | IDAC2=50µA | 4倍 | -20~+80°C | ±0.5°C

2.2 ADS122U04外围电路与供电设计

ADS122U04的外围电路比普通ADC简单,但有几点必须要做对:

  • 电源去耦:AVDD和DVDD引脚各放一个0.1µF陶瓷电容,位置尽量靠近引脚,再加一个10µF的钽电容做低频储能。虽然ADS122U04内部有电源抑制能力,但外部电容选不好,采集噪声会直接变差。

  • 参考电压:我使用内部2.048V参考,这样省掉外部基准芯片。对于24位ADC来说内部参考其实够用了,温度漂移主要影响满量程精度,而PT100和热电偶都是比率测量或小信号测量,影响有限。

  • 输入滤波:每个模拟输入引脚对地并联一个1nF电容,串一个小电阻(100Ω左右)。这个是防混叠滤波,同时也能抑制射频干扰。ADS122U04本身有50Hz/60Hz陷波选项,配合这个RC滤波,工频干扰基本进不来。

  • ESD保护:传感器线缆是从外面接到模块上的,必须考虑热插拔和静电。我在每个模拟输入引脚上加了BAT54S双二极管到电源和地,做简单的ESD钳位。工业现场用下来没有发现ADC输入端被打坏的。

供电上,ADS122U04可以2.7V到5.5V供电,我统一用3.3V,这样和STM32F429NI电平完全匹配,不需要电平转换芯片。整个模块的电源树是:外部24V进来,经过DC-DC降到5V,再用LDO出3.3V给核心电路。如果用DC-DC直接给ADC供电,噪声会很大,LDO这级不能省。

2.3 与STM32F429NI的接口连接细节

ADS122U04和STM32F429NI的连线非常简单:

  • ADS122U04的TXD接STM32的UART硬件RX引脚
  • ADS122U04的RXD接STM32的UART硬件TX引脚
  • 共地

这里有个容易踩的坑:ADS122U04的UART引脚不是5V容忍的。如果你板子上ADC用了5V供电,而STM32是3.3V供电,那你必须加电平转换或串联电阻分压。我这边统一3.3V供电,完全避免这个问题。

另外,如果系统要做电气隔离(比如传感器在现场,主控在控制柜,两者地电位可能不同),最佳方案是在UART的TX和RX两根线上各串一个高速光耦,或者用数字隔离器。UART比SPI好隔离太多了,两条信号线加一个隔离电源就搞定。我第二版硬件就是这么做的,隔离之后采集精度几乎没受影响,但系统抗共模干扰能力明显提升。

STM32F429NI这边我用的UART7,PA8/TX、PB12/RX(也可以根据你板子实际布线选别的),波特率9600,8位数据、无校验、1位停止位。注意一点:不要开启UART的硬件流控,ADS122U04不支持RTS/CTS。

3. 软件实现:寄存器配置、协议解析与温度换算

3.1 ADS122U04的8字节UART帧协议

这可能是整套方案里最需要耐心看的部分。ADS122U04的UART协议不是简单的“发个命令、回个数据”,而是固定8字节的命令帧。每一帧都是:

字节序号内容说明
0命令字节定义操作类型
1~6参数数据根据命令不同填充,无参数就填0x00
7CRC8校验值对整个前7字节做CRC8

主要命令有:

  • 0x06:复位ADC,回到默认配置
  • 0x08:启动一次转换(RTS),之后等待转换完成再读数据
  • 0x10:读取转换结果(RDATA),返回24位数据
  • 0x20+寄存器号:读寄存器
  • 0x40+寄存器号:写寄存器

这个协议很容易出现一个理解偏差——写完寄存器后,必须再发RTS命令启动转换,然后等待转换时间(由数据速率决定),之后才能发RDATA取数据。如果上来直接发RDATA,拿到的往往是上一次的数据或者全是零。我开始调试时就卡在这里,折腾了小半天。

3.2 初始化流程与关键寄存器配置

初始化流程我整理成固定的顺序,建议照抄:

  1. 复位:发送0x06命令帧
  2. 延时10ms,等待ADC内部复位完成
  3. 写寄存器:依次写REG0、REG1、REG2
  4. 发RTS启动转换
  5. 延时等待转换完成(数据速率为60SPS时,约等20ms比较安全)
  6. 发RDATA读取24位结果

核心配置代码示意如下(STM32 HAL库风格):

static uint8_t crc8(uint8_t *data, uint8_t len); // CRC8计算函数 typedef struct { uint8_t frame[8]; } ads122u04_frame_t; void ads_send_command(uint8_t cmd, uint8_t *data, uint8_t data_len) { uint8_t i; uint8_t frame[8]; frame[0] = cmd; for (i = 1; i < 7; i++) { if (i <= data_len) frame[i] = data[i - 1]; else frame[i] = 0x00; } frame[7] = crc8(frame, 7); HAL_UART_Transmit(&huart7, frame, 8, 100); } void ads_write_reg(uint8_t reg_addr, uint8_t value) { uint8_t data[4]; data[0] = reg_addr; data[1] = value; ads_send_command(0x40 | reg_addr, data, 2); // 写寄存器命令 HAL_Delay(1); } void ads_init(void) { ads_send_command(0x06, NULL, 0); // 复位 HAL_Delay(10); // REG0: MUX选择AIN0-AIN1差分,PGA增益8倍 ads_write_reg(0x00, 0x03); // 0x03 = MUX=0000(差分AIN0-AIN1), PGA=011(8x) // REG1: 数据速率60SPS,正常模式,工频抑制开启 ads_write_reg(0x01, 0x02); // 0x02 = DR[2:0]=010(60SPS) // REG2: IDAC1输出1mA,连接到AIN2引脚作为RTD激励源 ads_write_reg(0x02, 0x24); // 具体位域按手册配置 }

这里有个容易混淆的地方:REG0的MUX和PGA是放在同一个字节里的,高4位是输入多路选择,低3位是增益。如果你只用AIN0-AIN1做差分PT100输入,把高4位设为0000就行;PGA=8对应二进制011,所以整个字节就是0x03。这里面的位域关系建议对着手册标注仔细核对一遍,写错了ADC不会报错,但测出来的数据完全不对。

3.3 PT100的温度换算与二点校准

PT100换算流程是把ADC原始码一步步转成温度的。完整链路如下:

  1. 读取24位ADC原始码,注意它是二进制补码格式。STM32读取时先拼成int32_t,再处理符号位。
  2. 根据增益和参考电压换算输入电压:
Vin = (Code / 8388608) x Vref / Gain

这里8388608就是2^23,对应24位ADC的满量程正数编码。

  1. 因为IDAC电流已知是1mA,电阻值就是:
Rpt100 = Vin / 1mA
  1. 有了电阻值,再用查表法或多项式反算温度。实践中查表比直接算多项式要稳,尤其是大范围测量时,直接套简化公式在低温段误差很大。我会在STM32里放一张-50°C到+300°C、间隔1°C的PT100电阻-温度对照表,用线性插值计算,精度完全够。

然后是校准。ADC虽然标称24位,但激励电流1mA本身有误差,增益电阻也有误差,所以必须做两点校准:

  • 用标准电阻箱或精密电阻做校准点。我这里是0°C校准点(100Ω)和100°C校准点(138.51Ω)。
  • 先把两个校准点测出来的原始电阻值记下来,算出增益修正系数和偏置修正系数。
  • 公式修正:
R_corrected = (R_raw - Offset) x Gain_correction

校准完的通道,0°C那点误差能压到0.05°C以内。同一个硬件不校准、直接按理想值算的话,误差可能在0.3°C左右,对于HVAC可能无所谓,但工业上要求0.1°C精度就必须校准。

3.4 热电偶冷端补偿处理

K型热电偶的原理是热端和冷端之间温差产生热电势,所以测到的电压只代表温差,要得到真实温度必须知道冷端温度。

我的处理方式是用ADS122U04内部自带温度传感器。每次读热电偶电压之前,先读内部温度传感器通道的原始码,按芯片手册公式换算成结温:

Tj = (Code_internal / 2^15 - 0.5) x 2.048 / 0.005? // 具体系数以手册为准

把这个结温作为冷端温度T_cold,再用K型热电偶分度表算出冷端温度对应的热电势E_cold,然后:

E_hot = E_measured + E_cold

用E_hot反查分度表,得到热端真实温度。

这套算法看起来绕,但做热电偶必须这么搞。我最早图省事直接用“室温当作冷端温度”写进去,结果环境温度一变,测量值跟着漂好几度。后来老老实实做成实时冷端补偿,精度才稳定下来。

3.5 数据滤波与稳定化处理

热电偶信号经过128倍增益放大之后,末位跳动比较明显。24位ADC理论上分辨率极高,但实际噪声水平受布线、电源、前端RC参数影响,末几位经常在跳。

我在软件里做了两层处理:

  • 滑动平均滤波:窗口长度16,对连续16次转换结果取平均。这个对抑制随机噪声很有效,而且不会产生相位滞后,不像一阶低通滤波那样有明显的滞后感。
  • 突变数据剔除:如果某一帧数据和前一次采样的差值超过设定阈值(比如PT100通道差值超过5Ω,对应温度变化超过13°C),判定为干扰帧,直接丢弃。这个对现场偶发的强电磁干扰特别有用,能防止温度显示值瞬间跳一下再弹回来。

4. 实测中的典型问题与排查技巧

4.1 帧错位与CRC校验失败

这个问题是我遇到的第一个真正让人头疼的bug。一度UART收到的数据完全错乱,CRC校验一直失败,看起来ADC根本没在工作。

排查思路是:先确认硬件连线,用示波器看TXD脚上有没有波形;再看STM32的UART配置是否正确。这两项都查完没问题,最后发现是初始化时序问题——复位命令发出后,我没等足10ms就开始写寄存器,导致ADC还在复位状态,根本不响应后续命令。

更隐蔽的帧错位问题出现在快速读写时。ADS122U04命令帧是连续8字节,如果你发送间隔不稳定,或者中间插入了别的UART中断,很容易造成帧内字节错位。解决方法是:

  • 所有操作ADS122U04的代码段关闭相关UART中断
  • 发送命令和等待响应之间用阻塞式延时,不要依赖RTOS调度
  • 每次启动转换后,固定延时20ms再读,给ADC充足的转换时间

如果发现CRC连续失败超过3次,我会主动发一次复位命令重新初始化ADC,恢复成功率很高。

4.2 读数跳变与工频噪声

PT100通道实测读数在±10个LSB左右跳变,换算成温度大约是0.03°C,对工业应用来说完全可接受。但如果跳变幅度突然变大,通常是这几个原因:

  • 电源出问题了。DC-DC噪声直接耦合到ADC的模拟电源上。我后来把LDO输出到ADC的电源线上加了一个磁珠,跳变明显变小。
  • 传感器线太长,没有用屏蔽线。PT100长线在工业环境下会捡到共模噪声,建议用屏蔽双绞线,屏蔽层单端接地。
  • 采样率和工频陷波没配好。ADS122U04有50/60Hz数字滤波选项,国内的现场电选50Hz陷波,选60Hz的话对50Hz工频抑制效果会差一些。

4.3 传感器断线检测与故障上报

温度传感器断线在HVAC和工业现场太常见了——接线端子松动、线缆被老鼠咬断、探头腐蚀开路。如果不做断线检测,ADC会把悬空输入测出莫名其妙的温度,可能触发误报警。

我实现的断线检测策略分传感器类型:

  • PT100断线:恒流源还在,但电流通路断了,输入引脚电压会被拉向供电轨。这时ADC读数会接近正满量程或负满量程,偏离正常温度范围。程序里如果读到PT100电阻值小于10Ω或大于500Ω,直接判定断线。
  • 热电偶断线:热电偶开路时输入阻抗极高,PGA输入偏置电流会把信号拉到一个极端值,读数同样会快速冲到满量程。判定条件也是超范围。
  • NTC短路/断线:短路时阻值接近0,读数会走下限;断线时激励电流找不到回路,读数走上限。

断线检测不能只看单次结果,要连续三次超限才上报故障,防止瞬时干扰误判。上报方式我做了两个:本地状态指示灯闪烁,同时Modbus寄存器里的故障状态位置1。

4.4 在HVAC和工业场景中的实测表现

这套模组在两类场景里都实际跑了挺长时间。

HVAC场景是楼宇空调机组的回风温度、送风温度、盘管进出水温度,总共6个点,其中4个PT100、2个NTC。Modbus RTU轮询周期1秒,实际温度显示波动在±0.1°C以内,完全满足楼宇自控要求。一个有意思的发现是,现场有几台变频器启动瞬间,Modbus偶尔会丢包,但温度数据从没出过错——UART隔离通信的优势在这里体现得很明显。

工业场景是一台设备上的轴承温度和电机绕组温度监测,K型热电偶和PT100混用,通过RS485接到控制柜里的触摸屏。连续运行一个多月,所有通道数据稳定,断线检测成功触发过两次(都是接线端子松动),直接报警提示维护。

5. 写在最后的实用建议

这套方案做下来,我最大的体会是ADS122U04 + STM32F429NI的组合真正把“模拟前端设计”的复杂度降下来了。以前做多路温度采集,光是恒流源、仪表放大器、基准电压这些模拟电路就得花大量精力,现在ADC一颗芯片全包了,软件反而成了主要工作量。UART协议虽然比SPI麻烦一点,但换来的是可靠性,绝对值。

最后分享一个小技巧:如果你打算把这套代码复用到别的STM32型号上,重点检查两个地方——UART的DMA缓冲区对齐方式,以及CRC8的查表实现。ADS122U04的CRC算错一帧,整个通信就断一次,而这个细节恰恰是最容易看手册时忽略的。如果你也正在做类似的温度采集项目,照着这套思路搭一遍,应该能省下不少调试时间。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询