☰
基于ADS122U04与STM32F767的工业温度采集系统设计
2026/11/5 1:09:37 网站建设 项目流程

去年在帮着做一套工业现场温度监控系统,同时要给楼宇自控的 HVAC 机组做温度采集,手边最常用的组合就是 ADS122U04IPWR 和 STM32F767BI。ADS122U04IPWR 是一颗 24 位四通道 Δ-Σ ADC,带 UART 接口、内部 PGA 和激励电流源,非常适合把 PT100、热电偶、NTC 这些微弱信号直接变成数字量;STM32F767BI 则是主频 216MHz 的 Cortex-M7 单片机,负责跑通信协议、滤波算法、显示和联动控制。整套系统一路调试下来,把温度测量从“能测”做到了“测得准、测得稳”,这里把完整的设计思路和踩过的坑都记录下来,给后面做类似温度采集板的朋友一个参考。

不同场景对温度测量的需求其实很不一样。HVAC 里要测冷冻水供回水温度、冷却水温、风管回风温度、压缩机吸气排气温度;工业现场可能还要测轴承、电机绕组、加热炉炉膛。信号范围从 PT100 几十毫伏的变化量,到 K 型热电偶几十微伏级别的热电势,差距非常大。ADS122U04IPWR 的高位数、可配置 PGA 和多通道 MUX,加上 STM32F767BI 的算力,正好能把这些信号统一处理,不用再为每一种传感器单独做一套模拟前端。

1. 项目是怎么落地:需求拆解与选型思路

1.1 温度测量在工业和 HVAC 场景中的真实需求

做工业采集的人都知道,真正难的不是把传感器接到 ADC 上,而是把误差控制住。以 PT100 为例,0℃ 时阻值 100Ω,温度系数大约 0.385Ω/℃,如果导线电阻有 0.5Ω,两块表显示的温度就有 1.3℃ 左右的差别。这在 HVAC 的舒适性控制里还能接受,但在工业工艺监控里可能就直接意味着批次报废。所以选型时首先要明确系统需要多高的绝对精度、多好的长期稳定性、要不要满足防爆/电磁兼容认证。

HVAC 系统里温度变化速度不快,风管温度一般几十秒才稳定,压缩机排气温度变化的惯性也比压力慢很多,因此采样率不需要很高,20SPS 到 100SPS 足够。但 HVAC 对可靠性和成本敏感,传感器常常分布在几十米长的管道上,走线会经过变频器、接触器这些干扰源,所以 ADC 必须有足够的抗工频干扰能力,最好能直接带 50Hz/60Hz 抑制滤波器。工业现场则更看重宽量程和灵活性,一台设备可能要兼容 PT100、各种热电偶、4-20mA 变送器,如果每换一种传感器就换一块采集板,维护成本会成倍增加。

把需求拆开之后,适合的 ADC 大概要有这么几个特征:24 位或以上分辨率、内置 PGA、内置激励电流源、多路输入、可配置数据速率。ADS122U04IPWR 基本踩在这些点上,而且它通过 UART 输出结果,而不是传统的 SPI,这在远距离和分布式布线上反而有优势。STM32F767BI 则是因为项目里不只做温度采集,还要跑 Modbus、控制继电器、带一块液晶屏,甚至做简单的数据记录,M7 内核的资源和外设数量都比较充裕。

1.2 为什么是 ADS122U04IPWR + STM32F767BI

这个组合不是随便定的。市面上一堆 24 位 ADC,比如 I2C 接口的 ADS122C04、SPI 接口的 ADS124S08、ADS1261,还有各种国产高精度 ADC,单独拿出来都能测温度。但 ADS122U04IPWR 的特殊点在 UART 物理层,主控只需要两根线就能完成配置和数据读取,而且支持多设备地址访问,适合一个主机带多个从机测量模块。对 HVAC 这种分散式系统来说,每台空调机组放一块带 UART 的采集小板,用一条总线连回主控,布线比 SPI 的“一主多从片选线”更简单。

STM32F767BI 的选型看中的是资源和算力。它内部有硬件浮点单元,跑温度查表和滤波算法非常轻松;多路 UART 可以同时接数据采集板、调试串口、Modbus 网关;内置以太网 MAC 和 LCD 控制器允许后续直接做触摸屏或联网监控。之前我也考虑过 STM32F103 之类更便宜的芯片,后来发现要在 F1 上用软件实现浮点滤波、还要同时处理多路 UART 和显示,代码优化成本很高,不如直接用 F7 把时间花在算法和控制逻辑上。

当然,这套组合也有代价。ADS122U04 的寄存器配置比普通温变芯片复杂,第一次上手时容易因为几个位没配对,导致输出数据乱跳。STM32F767BI 的电源设计和 PCB 布局也比小单片机苛刻一些,特别是 216MHz 主频下如果用劣质 LDO,模拟采集部分很容易受到数字噪声干扰。后面章节会把这些问题逐一展开。

1.3 系统整体框图与数据流

整个系统的数据链路可以分成四段:传感器、模拟前端、数字转换、主控处理。温度传感器首先经过保护滤波电路进入 ADS122U04 的输入通道,内部的 MUX、PGA 和 Δ-Σ 调制器把模拟电压转成 24 位数字码;接着 UART 以帧形式把结果发给 STM32F767BI;最后在 MCU 里做电阻/温度换算、冷端补偿、滤波、越限判断,再把数据送到显示、通信或执行机构。

这里最需要注意的是信号链上的每一个环节都可能引入误差,但效果完全不同。传感器本身决定物理精度上限,比如 PT100 在 0℃ 精度可能是 ±0.3℃,而 K 型热电偶常温附近精度只有 ±1.5℃ 左右。模拟前端的激励电流源、参考电阻和输入滤波决定了噪声底和温漂。ADC 的高位数只在前面都做得好的时候才有意义,如果外部参考电阻温漂 100ppm/℃,那么即便 ADC 有 24 位分辨率,整机精度也会被参考电阻拉低。因此在设计时,我把更多精力放在模拟链路的“一致性”和“长期稳定”上,而不是只看 ADC 位数。

2. 硬件设计核心细节:传感器输入到 ADC 再到 MCU

2.1 传感器类型与接口:PT100/PT1000、热电偶、NTC 怎么接

PT100 和 PT1000 最常用的是三线制和四线制接法。四线制是把激励电流从一对导线注入,用另一对导线把 RTD 两端的电压单独引回来,彻底消除导线电阻影响,适合实验室级测量。但工业现场为了省线,通常用三线制:一条导线接激励电流源,一条导线接参考电阻,第三条导线接公共地或者作为电压检测补偿,这样导线电阻在测量回路里相互抵消,实际误差可以控制在 0.1℃ 以内。

ADS122U04 内部有可配置的激励电流源,这给三线制接线提供了很大便利。典型做法是用内部 IDAC1 给 PT100 串联路径提供恒流,同时让这股电流也流过一颗低温漂参考电阻 RREF,以 RREF 上的压降作为 ADC 的参考电压。这样 RTD 电压和参考电压由同一个电流源建立,ADC 码值直接等于 RTD 电阻和 RREF 的比值,激励电流自身的漂移就被完全抵消了。这也是后面软件里为什么能用“码值乘以 RREF 再除以最大码值”直接算出电阻的原因。

热电偶输出的是微伏级热电势,通常接到 AIN2/AIN3 这样的独立通道,配置 PGA 增益为 32、64 或 128。由于热电偶本身没有激励电流,冷端补偿必须在靠近热电偶接线端子的位置放一颗温度传感器,可以是板载 NTC,也可以直接用 ADS122U04 内部温度传感器。NTC 则相对简单,常与固定电阻构成分压电路,激励源可以选固定电流源,也可以直接由 ADC 参考电压驱动,只要满足输入共模范围和量程即可。

2.2 激励电流、低通滤波和输入保护电路

激励电流的选取要平衡信噪比和自热效应。PT100 在 100Ω 时用 1mA 电流,电阻上压降才 100mV,ADC 输入信号太小,PGA 需要开较高增益;如果加到 2mA,在 PT100 变为 1000Ω 时压降就有 2V,可能超过 PGA 输入范围,同时电流在传感器内部产生的热量会影响测量结果。按经验,PT100 用 0.5mA 到 1mA 比较合适,PT1000 因为在更高阻值段工作,0.5mA 也很稳妥。

RC 低通滤波是每个模拟输入通道必备的。工业现场经常有变频器、继电器拉弧产生的几百 kHz 高频干扰,如果不滤掉,会在 Δ-Σ 调制器输入端混叠成低频噪声。通常选择电阻 1kΩ、电容 0.1μF 的组合,截止频率约 1.6kHz,既能滤掉大部分射频干扰,又不会把传感器信号压掉。电容要用 C0G/NPO 材质,普通 X5R 电容在直流偏置下容值会下降,且温飘较大。如果传感器线很长,我还会在入口处加共模电感或者磁珠。

输入保护也要做,但不建议用压敏电阻直接并联在 ADC 输入上,因为漏电流在高温下会恶化测量精度。比较稳妥的做法是串联 10kΩ 到 100kΩ 的限流电阻,再用低漏电 TVS 管接到电源和地轨。这样 24V 电源误碰、静电放电、雷击浪涌都能被限制在 ADC 可承受范围内,而且不影响正常测量。做多用表温度输入时,还会加一个二极管钳位到 AVDD/AVSS,防止断线瞬间产生过压。

2.3 ADS122U04 与 STM32F767BI 的 UART 电气连接

ADS122U04 的 UART 是异步串行,数据线和时钟线就是 TX/RX 两根,直接接 STM32F767BI 的任意一组 USART。STM32F767BI 的 I/O 工作在 3.3V,而 ADS122U04 也支持 3.3V 数字电源,因此这里可以直连。为保证调试时不因杜邦线插拔打坏引脚,我在 UART 线上各串了一个 100Ω 电阻,必要时再连到 MCU 的 USART RX/TX 引脚。

通信波特率建议先用 9600 或 19200 起步,确认帧格式和 CRC 校验没问题后再提到 115200。UART 本身是异步的,如果两端波特率偏差超过 2%,长帧传输就可能出现误码。STM32F767BI 内部使用 16MHz 到 25MHz 晶振,通常误差不大,但 ADS122U04 内部的时钟精度有限,因此不要让波特率太高,尤其是用内部振荡器做多板通讯时,115200 以下更稳妥。

如果温度采集板和主控板要分开放,比如一个装在机柜里,一个装在传感器附近,UART 之间可以加数字隔离器,比如 ISO7721。隔离器放在传感器侧而不是主控侧,好处是模拟部分和数字部分彻底断开地环路,干扰问题和共模电压问题一次解决,不影响 UART 信号速度。

2.4 电源与基准电压设计要点

模拟电源 AVDD 和数字电源 DVDD 建议都由低噪声 LDO 供电,不要直接从开关电源纹波大的 12V 取。ADC 的电源抑制比在高频段并没有想象中好,一个 30mV 的开关纹波就可能通过内部比较器耦合到测量结果里。我常用 TPS7A 系列或 LP5907 这类超低噪声 LDO,把 5V 降到 3.3V,再用 10μF+0.1μF 去耦。STM32F767BI 的 VDD 可以用同一条 3.3V 电源,但模拟部分的 AVDD 建议单独去耦。

基准电压的设计是温度测量精度的核心。ADS122U04 使用外部参考电阻做比例测量时,实际上并不需要一个绝对精确的 2.048V 基准带隙,而是把 RREF 的电压当作参考。因此 RREF 的品质直接决定了整机精度,我选择 0.1% 精度、温漂 10ppm/℃ 的精密电阻,阻值根据量程选 1kΩ 或 2kΩ。如果使用内部基准,则要确保 VREF 引脚滤波电容采用高质量 X7R,并根据温漂定期校准。

模拟地、数字地在 ADC 芯片下方用一颗 0Ω 电阻或者磁珠单点连接,不要把大面积地直接连成一片,否则数字噪声会沿着地平面串进模拟前端。STM32F767BI 的高速数字引脚和 ADC 模拟输入要尽量拉开距离,至少保证 3mm 以上的间距,这在四层板上效果最明显。

3. 软件驱动与温度计算:把原始码变成可用温度

3.1 ADS122U04 寄存器配置与 UART 通信协议

第一次用这颗 ADC 的人容易被 UART 命令模式绕晕。它不像 SPI 那样直接拉低片选读数据,而是要先发读写寄存器命令,再发数据读取命令,并且每一帧都可能有 CRC 校验。我的建议是把配置过程封装成独立的驱动函数,只暴露初始化、通道切换、读取温度三个接口,后面应用层不直接碰寄存器位。

下面是一段示意性的初始化代码,寄存器地址和状态位以 ADS122U04 数据手册为准,这里重点展示整个配置流程:

static void adc122u04_write_reg(uint8_t addr, uint8_t value) { uint8_t frame[3]; frame[0] = 0x20 | (addr << 1); // 写寄存器命令格式 frame[1] = value; frame[2] = crc8(frame, 2); // 开启CRC时追加校验 uart_send(frame, 3); } void adc122u04_init(void) { adc122u04_send_cmd(0x11); // STOP,先停掉连续转换 delay_ms(5); // 选择AIN0/AIN1差分通道,内部PGA跟随输入 adc122u04_write_reg(REG_CONFIG0, 0x02); // PGA增益设为16,适合PT100满量程信号 adc122u04_write_reg(REG_CONFIG1, 0x04); // 数据速率设为20SPS,并启用50Hz/60Hz抑制 adc122u04_write_reg(REG_CONFIG2, 0x03); // 参考电压选择外部RREF比例方式 adc122u04_write_reg(REG_CONFIG3, 0x01); // 激励电流源0.5mA,分配到IDAC1 adc122u04_write_reg(REG_CONFIG4, 0x05); // 启动连续转换 adc122u04_send_cmd(0x08); }

需要注意,寄存器配置完成后,最好回读一遍确认写入成功,因为在某些异常电压下 UART 命令可能被噪声破坏。如果配置值和读回值不一致,软件应主动报警,而不是继续用错误参数跑数据,否则测出来的温度可能整体偏移好几度。

读取数据时,可以设置成连续转换模式,主控周期性地从 UART 收帧解析。ADS122U04 输出的 24 位数据需要拼成有符号整数,再除以最大码值得到电压比例。如果开启了 CRC,每帧末尾会有校验字节,接收端不通过就丢弃这一帧。我在实际项目中把 CRC 开启,宁可在现场看到少数几条丢弃告警,也不希望一次干扰直接导致温度跳变 10℃。

3.2 STM32F767BI 端 UART 收发与 DMA 实现

STM32F767BI 端用 HAL 库配置 UART 接收会比较简单,但要注意别在主循环里用阻塞方式等数据。温度采集本身不需要极高实时性,可一旦加入显示、控制、通信,主循环很容易被卡住。我一般用 DMA 接收固定长度帧,接收完成后在 DMA 完成中断里解析数据,这样 ADC 的数据更新不会阻塞其他任务。

DMA 接收的关键是要知道一帧有多长。如果设成 6 字节一帧,就配置 HAL_UART_Receive_DMA(&huart1, rx_buf, 6),每收满 6 字节触发一次中断。ADS122U04 连续转换模式下会持续发帧,主控只要不断接收即可。收到后先判断帧头或状态字节,再检查 CRC,最后把 3 字节 ADC 数位提取出来。

uint8_t adc_rx_buf[8]; volatile uint8_t adc_data_ready = 0; int32_t adc_last_raw = 0; void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) { if (huart->Instance == USART1) { if (check_frame_crc(adc_rx_buf)) { adc_last_raw = extract_signed_24(adc_rx_buf + 2); adc_data_ready = 1; } HAL_UART_Receive_DMA(huart, adc_rx_buf, 8); } }

这段代码演示了整个收发框架。工程上还要注意 DMA 缓冲区在中断里被访问的原子性,最好关中断取数或者用双缓冲。另一个容易踩的坑是 STM32F767BI 的 USART 时钟源和波特率配置,如果用内部低速时钟,误差会大,建议把 USART 时钟源设置为 PLL 分频后的高频时钟,并且用逻辑分析仪实测一帧的位宽,确认没有多或少 1μs。

3.3 RTD 电阻计算、线性化与热电偶冷端补偿

硬件采用比例测量时,ADC 的码值可以直接换算成 RTD 电阻值。假设 ADS122U04 使用的是二进制补码,24 位有符号数满量程对应 2^23,那么电阻的计算就是:

R_rtd = code × RREF / 2^23

只要 RREF 足够稳定,这个公式对激励电流源的绝对值不敏感。对应代码可以这样写:

float ratio_to_resistance(int32_t code, float rref) { return ((float)code / 8388608.0f) * rref; }

算出电阻之后还要把电阻换算成温度。PT100 在 0 到 850℃ 范围内可以用 Callendar-Van Dusen 公式,但直接解方程比较麻烦,工程上更快的办法是查表和二分法。我预生成一张 1℃ 间隔的电阻-温度表,固件里用二分查找加线性插值,计算一次不到 1μs,精度可以做到 0.1℃ 以内。

热电偶的软件处理比 RTD 多一个冷端补偿步骤。先把冷端温度查成对应的热电动势 e_cold,再把它加在实际测得的热电势 e_hot 上,得到修正后的热电势 e_real,最后按热电偶分度表把 e_real 换算成被测温度。由于热电偶的非线性非常明显,直接用线性公式会差出几度,必须查表或多项式拟合。冷端温度可以从 ADS122U04 内部温度传感器读取,也可以外接 NTC,但 NTC 要贴在热电偶冷端接线上,而不是贴到主控芯片附近,这个位置错误很常见。

3.4 滤波与抗干扰:滑动平均+限幅+IIR

ADC 原始数据即使在高分辨率下,也还会有低频噪声和偶发尖峰。我是按“限幅-平均-低通”三级来处理:先把明显超过物理极限的尖峰点剔除,再滑动平均抑制高斯噪声,最后用一阶 IIR 平滑输出,避免曲线过于生硬。

滑动平均的程序很简单,关键在窗口大小。窗口太大会导致温度变化响应慢,HVAC 里也许还能接受,但工业保护联锁要求快速反应,所以窗口长度取 8 比较合适。一阶 IIR 的系数则要按采样周期和期望响应时间计算,比如 20SPS 采样,alpha 取 0.3 时,响应时间约 15 个采样周期,也就是 0.75 秒,对大多数温度控制够用。

#define FILTER_WIN 8 float filter_sum = 0; float filter_win[FILTER_WIN]; uint8_t filter_idx = 0; float temp_filter(float new_temp) { filter_sum += new_temp - filter_win[filter_idx]; filter_win[filter_idx] = new_temp; filter_idx = (filter_idx + 1) % FILTER_WIN; return filter_sum / FILTER_WIN; }

要注意滤波不能替代硬件屏蔽。如果现场干扰严重,把滤波系数调得很深,温度显示是稳定了,但真实温度突变时系统反应会迟滞,极端情况下会导致保护逻辑误判。所以我开发时习惯在界面上保留一个“原始值”页面,专门用于调试时对比滤波前后数据,干扰排查全靠它。

4. HVAC 与工业场景的实测问题与排查实录

4.1 现场常见的错误接线和传感器故障判断

用这套方案跑了两个项目后,我发现大多数“不可理喻”的问题其实发生在接线端。PT100 的开路故障会读出接近正满量程或负满量程的乱码,因为输入悬空时 PGA 输入端没有电流回路,电压漂到上限附近;热电偶接反则表现为冷端补偿后温度反而下降,正常加热时读数越来越低。

想要快速分辨故障类型,可以在固件里加一个简单的合理性检查:PT100 电阻在 -50℃ 到 300℃ 之间对应多少欧姆,如果 ADC 换算出的电阻值明显超过这个范围,就置一个“传感器异常”标志。热电偶可以检查热电势的变化率和极性,如果几分钟内温度变化速率超过物理极限,也应直接告警,而不是把异常数据送到控制环里。

我印象最深的是某次 HVAC 风管温度传感器显示 -55℃,换了新传感器也一样。后来查出来是传感器线缆内部断芯,断点处的氧化层产生了类似热电偶的接触电势,而 ADC 通道又恰好配置成热电偶模式,把这个寄生电势当成了真实信号。从那以后,我在硬件额定范围外做了软上限和断线检查,不再盲信 ADC 数据。

4.2 电磁干扰导致的跳码问题

工业现场最大的敌手是变频器和接触器。它们产生的干扰频带非常宽,轻则让 ADC 最后 2-3 位乱跳,重则整帧数据 CRC 错误。第一次遇到时我以为是供电问题,后来用示波器量 ADC 输入引脚,才看到几百毫伏的高频毛刺。这些毛刺在 24 位 ADC 面前会被放大得非常明显。

处理电磁干扰要分两步走。硬件上,传感器线要换成屏蔽双绞线,屏蔽层只能一端接地;ADC 输入走线远离大电流走线,并且加大 RC 滤波电容;如果干扰来自地环路,就加数字隔离器或者把模拟地与机箱地隔离。软件上,把数据速率降到 20SPS,启用 50Hz 工频抑制滤波器,然后再加上前面说的滑动平均。这两步做完,大部分跳码问题都能消失。

还有一个容易忽略的点:STM32F767BI 的高速数字信号本身也是噪声源。有一次我在调试时发现 ADC 读数在 LCD 刷新瞬间会跳一下,单独测模拟部分又没问题。后来把 ADC 的 AVDD 用磁珠和 DVDD 分开,并把 SPI/LCD 走线移到另一面,现象就消失了。所以不能只怪外部干扰,内部布板和供电耦合往往才是幕后黑手。

4.3 漂移问题:ADC 自校准与零点修正

长期漂移比随机干扰更隐蔽。开机前几个小时内温度读数缓慢变化,可能是 ADC 或运放刚开始工作时的热漂移;几个月内发生漂移,则往往是参考电阻老化、PCB 受潮漏电,或者传感器本身劣化。对于工业应用,我会在每次上电时做一个自校准:输入通道短接,记录零点偏移;再通过内部校准命令修正失调。

ADS122U04 配置里可以启用内部失调校准和增益校准,但要注意校准命令执行期间不要切换通道,并且要在稳定的电源环境下进行。如果现场供电波动大,校准结果反而会引入新误差。实践经验是:凌晨低负载时段执行一次校准,保存校准系数到 STM32F767BI 内部 Flash 的备份区,重启后自动叠加到计算结果上。

参考电阻的漂移问题最好在设计阶段就规避。选用 10ppm/℃ 以下的精密电阻,并且把 RREF 尽量靠近 ADC 的 REF 引脚,远离发热元件。PCB 上预留两颗校准电阻的焊盘,量产时用自动化设备做两点校准,把增益系数写入每台设备的 MAC 地址区。这种做法的成本增加很小,但能保证不同批次设备的温度读数一致,尤其适合批量出 HVAC 控制器和工业采集器的场景。

4.4 长距离传输与隔离问题

当传感器离主机超过 10 米时,直接模拟走线不是好选择。我曾经试过用普通屏蔽线从 20 米外接 PT100 到 ADC 板,虽然三线制补偿了大部分线阻,但现场的变频器噪声和共模电压仍然让读数不稳定。后来改为在现场放置一块小的采集板,通过隔离 UART 传给主机,信号质量立刻改善。

具体做法是每台设备上用一个 ADS122U04 做模拟前端,就近采集传感器信号,然后通过 UART 驱动隔离器,再走 RS-485 总线回传。STM32F767BI 作为总线主站接收各从站数据,统一做记录和控制。这样每个采集点只处理自己的模拟信号,总线传输的是已经数字化的温度值,抗干扰能力与直接传模拟电压完全不同。虽然单板成本高了一点,但调试和后期维护的复杂度大幅下降。

再补充一个我踩过的坑:隔离器两侧的电源必须独立,不能共地。如果隔离器输出侧和 MCU 还是共用一个 3.3V,那么隔离实际上只增加了延时,没有斩断地环路。至少要保证模拟侧电源和数字侧电源分别用两颗 DC-DC 或 LDO,否则现场雷击浪涌时照样会烧毁主控板。这个细节在很多方案文档里都不会写,恰恰是长期可靠性的关键。

在我自己的项目上,我坚持把隔离放在传感器侧而不是总线侧,这样后续排查问题会非常清晰:传感器板只负责模拟采集,总线板只负责通信,哪边异常直接换哪块。这套 ADS122U04IPWR 加 STM32F767BI 的思路,从原型到量产迭代了三轮,目前已经稳定跑了大半年,至少在温度测量这条赛道上,是我用过性价比最合适的组合。

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

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

立即咨询