☰
工业与HVAC高精度温度采集:ADS122U04+STM32L442方案详解
2026/11/5 8:38:51 网站建设 项目流程

去年在一个楼宇自控项目现场调 HVAC 机组,发现温控板上的温度数据一到换季就飘得离谱:冬天送热风时回风温度能偏到 2 度以上,夏天制冷时又是另一个方向的偏差。拆开看,板子用的还是老方案——NTC 直接进 MCU 内置 ADC,软件滤波拉满,靠标定硬撑。做工业测温的朋友应该都懂这个味儿:不是 MCU 不够好,而是模拟前端从根上就缺了一环。

后来我把整套采集链路换成ADS122U04IPWR 加 STM32L442KC的组合,用一颗带 UART 接口的 24 位 ADC 把模拟前端独立出去,MCU 只负责通信、换算和调度逻辑,问题才算真正解决。这颗 ADC 内部集成了 PGA、基准源、激励电流源和温度传感器,配合 L4 系列的超低功耗 MCU,做工业现场或 HVAC 里的高精度温度采集非常顺手。这篇就把这套方案从选型逻辑、硬件设计、通信协议、温度换算法到固件低功耗的完整过程拆开写一遍,给同样在折腾温度采集的朋友做个参考。

1. 为什么工业与 HVAC 测温要绕开 MCU 内置 ADC:这套组合的出发点

1.1 工业现场测温的三种主流传感器与各自难点

工业设备和楼宇暖通里的温度测量,说到底绕不开三种传感器,它们各自的电气特性和工程难点差别很大。

RTD 铂电阻(PT100、PT1000)是工业现场精度首选,测换热器进出口水温、管道介质温度、电机轴承温度都靠它。PT100 在 0 摄氏度时阻值 100 欧姆,温度每升高 1 摄氏度阻值大约增加 0.385 欧姆,这个变化量非常小,直接用万用表量都费劲。想要分辨 0.1 摄氏度,电阻分辨率就得做到 0.04 欧姆量级,折算到电压信号上,如果激励电流 1mA,对应的电压变化只有 40 微伏。这基本就是普通 ADC 的噪声底。

热电偶的优点是测温范围宽,能到上千摄氏度,工业窑炉、排烟温度都靠它,但输出信号是微伏级的弱电压,比如 K 型热电偶在室温附近灵敏度大约 40 微伏每摄氏度,而且是非线性的,还必须做冷端补偿。NTC 热敏电阻灵敏度最高,HVAC 里的回风温度、室内温度大量使用,胜在便宜、响应快,缺点是互换性差、线性度差,需要查表或者用方程拟合。

这三种传感器有一个共同点:输出信号都很"弱",直接塞进 MCU 的内置 ADC 是典型的小马拉大车。

1.2 内置 ADC 的短板不是分辨率,而是参考和前端

很多人一提"MCU 内置 ADC 不够用",第一反应是"位数是 12 位所以精度不够"。其实这个理解不全面。

STM32L442KC 内置的 ADC 确实是 12 位,但 12 位 ADC 本身并不是不能用,真正的问题出在两个方面。第一是参考电压:内置 ADC 的参考电压通常直接来自 VDD,而 VDD 在系统里要照顾数字逻辑、继电器、通信芯片,纹波和漂移都比较大。ADC 是比例型器件,参考电压抖动会直接进测量结果,这个误差不是你写滤波算法能滤掉的。第二是模拟前端缺失:RTD 和热电偶的信号天生就需要恒流激励、差分放大、滤波、线性化补偿,这些功能内置 ADC 一概没有。你可以用外部运放搭,但运放的偏置电压、温漂、增益误差又是一大堆需要逐一处理的问题。

所以结论很直接:做工业或者 HVAC 的可靠温度采集,不是"选一个好 MCU"能解决的,而是要先把模拟信号质量搞定。这就是为什么方案里必须有一颗像样的 ADC 芯片。

1.3 为什么选择 UART 接口的 ADC 而不是 SPI/I2C

ADC 和 MCU 之间的接口,大多数工程师第一反应是 SPI,因为速度快、用起来简单。但注意 ADS122U04IPWR 这颗 ADC 最大的差异化卖点恰恰是UART 接口,这不是 TI 拍脑袋设计的。

工业现场有个很现实的问题:传感器和采集板之间往往隔着几米甚至几十米线缆。SPI 是同步接口,时钟线和数据线的时序在长线上非常脆弱,2 米以上就开始容易出现误码;I2C 虽然只有两根线,但速率低,而且没有差分能力,抗共模干扰能力差,工业现场电机启停、继电器吸合产生的噪声耦合进来就是灾难。

UART 是异步串行,一两根线就能跑,波特率不高时对线缆要求低得多。更关键的是,UART 在工业总线生态里非常"通用"——很多工控网关、PLC 扩展模块、串口服务器本身就带 UART,这意味着你用这套方案采集到的温度数据,可以直接对接已有的工业总线体系。另外从软件角度看,UART 用 DMA 接收非常方便,MCU 扔一个命令下去,数据准备好后自动进内存,不需要像 SPI 那样每字节都要 CPU 参与或者专门配中断。再加上 UART 本身是全双工,可以在读取转换结果的同时发送下一条命令,整条采集链路更容易做流水线化。

2. ADS122U04IPWR 与 STM32L442KC:两颗芯片各自能打的地方

2.1 24 位串口 ADC 的内部结构:PGA、基准、IDAC 一次配齐

ADS122U04IPWR 是 TI 推出的一颗低功耗 24 位 Δ-Σ ADC,TSSOP-16 封装,在这个项目里的角色是完整模拟前端加数字化输出的统一体。它的核心价值在于,传统方案里需要用分立的仪表放大器、精密基准源、恒流源、滤波器拼出来的东西,它全集成在内部了。

先说信号链路径:模拟输入经过片内多路复用器,进入可编程增益放大器 PGA,增益范围最大可以到 128 倍。这对热电偶尤其重要,微伏级信号直接放大到 ADC 能有效量化的区间。PGA 之后是 24 位 Δ-Σ 调制器,配合片内数字滤波器,输出有效分辨率非常可观。

然后是基准源。芯片内部集成 2.048V 基准,温度漂移特性对工业级测温来说是基本够用的。如果你对精度要求更苛刻,也可以把内部基准关掉、接外部精密基准,这给了设计上的灵活性。对于大多数 HVAC 和一般工业测温场景,内部基准完全够用,省掉一路基准电源设计。

更关键的是片内集成了两个激励电流源 IDAC。RTD 测量必须有恒流源供电,没有它就得自己搭镜像恒流源,温漂还不好控。这颗 ADC 的 IDAC 可以设定不同档位的电流,还能选择输出到哪个引脚,做三线制 RTD 时正好用两个 IDAC 分别激励传感器两端,从硬件上就把线阻补偿的功课做掉了。

最后,芯片内部还有一颗片内温度传感器。很多人忽略它,但它在热电偶冷端补偿里是救命的。K 型热电偶测量几百度的温度时,冷端如果在室温附近波动几度,带来的误差就是上百微伏级别,折算成温度就是好几度。用这颗内部温度传感器测冷端温度,再配合热电偶分度表做补偿,整个链路才闭环。

2.2 STM32L442KC 压低功耗与释放引脚的关键特性

STM32L442KC 属于 STM32L4 系列,Cortex-M4F 内核,主频能到 80MHz。在这套方案里它的定位是采集控制与数据后处理,对性能要求其实不高,真正看重的是三件事:

第一是功耗模式非常齐全。L4 系列有 Sleep、Stop 1、Stop 2、Standby 多级低功耗模式。Stop 2 模式下 SRAM 数据保持,电流能做到微安级别,RTC 还能继续跑。做 HVAC 里有电池供电的温湿度记录仪、或者工业上靠 4-20mA 回路取电的现场变送器,这种低功耗能力直接决定了设备能不能靠小电池撑几个月。

第二是外设接口资源够用且灵活。芯片自带多个 UART,其中一个接 ADS122U04IPWR,另一个留作调试或者接上位机,互不干扰。DMA 可以同时服务 UART 收发,接收转换结果时 CPU 可以继续跑换算逻辑。

第三是内核带 FPU。温度换算虽然用查表法也能做,但 RTD 的 Callendar-Van Dusen 公式、热电偶多项式拟合涉及不少浮点运算,有硬件浮点单元之后计算速度快很多,而且代码写起来清爽,不用整天想着用定点数去凑精度。

以 128KB Flash 加 42KB SRAM 的配置,这套采集固件、bootloader、调试协议栈全部放进去还有充裕空间。

2.3 外设规划:UART、GPIO 与引脚分配表

选型定了之后,引脚分配是第一个要落地的细节。我在这个项目里的分配逻辑如下,核心思路是把 UART 与调试、唤醒、供电检测引脚分开,避免冲突和后期改板:

功能MCU 引脚外设说明
ADC UART TXPA2USART2_TX接 ADS122U04IPWR 的 RX/CMD 脚
ADC UART RXPA3USART2_RX接 ADS122U04IPWR 的 TX/SDO 脚
ADC 复位控制PB0GPIO 输出上电后手动复位 ADC,保证状态确定
ADC DRDY 检测PB1GPIO 输入(EXTI)转换完成信号,触发读取
调试串口 TXPA9USART1_TX接 USB 转串口工具,输出调试日志
调试串口 RXPA10USART1_RX预留升级/命令入口
唤醒定时RTC—STOP2 模式下周期唤醒

这里要特别说一下 DRDY 的接法。ADS122U04 是 UART 接口,转换完成的事件在帧结构里有体现,但如果靠轮询命令去查状态,一来费 CPU,二来时序不确定。把 DRDY 引到 EXTI 输入,用上升沿或者下降沿中断通知 MCU 去读数据,整个采集流程干净利落,MCU 大部分时间可以睡觉或者干别的活儿。

3. 硬件设计:传感器接入、电源供给与 PCB 布线的关键细节

3.1 电源设计:给 24 位 ADC 一口干净的水

24 位 ADC 的分辨率很高,但这只是理论上的东西,工程上能不能兑现,电源是第一道关口。我见过不少项目,原理图照着参考设计画的,结果指标差一大截,查到最后十有八九是电源没做好。

ADS122U04IPWR 的模拟电源 AVDD 和数字电源 DVDD 要分开对待。实际项目里如果系统里已经有开关电源 DCDC,那就绝对不要直接拿 DCDC 的输出给 AVDD 供电。开关电源的纹波通常是几十毫伏起步,这在 24 位采集链路里是灾难级的干扰。我的做法是:DCDC 先出 5V,后面跟一颗低噪声 LDO 出 3.3V 给模拟部分,LDO 的输出端放 10uF 钽电容加 100nF 陶瓷电容组合去耦。

去耦电容的位置也有讲究,100nF 小电容必须尽量靠近 AVDD 引脚,走线要先经过小电容再到芯片,否则高频噪声滤波效果等于零。模拟地和数字地在 MCU 和 ADC 的底部单点汇接,千万别在 PCB 上大面积铺成一个地,否则 DCDC 的地电流会直接变成 ADC 参考地的噪声源。

还有一个细节容易被忽略:如果传感器的激励电流从 IDAC 出来,最终会经过 RTD 回到地,这个电流回路的地不能跟数字地混在一起。三线制 RTD 的低端要单独走模拟地线回到 ADC 附近的地参考点,这样才能保证激励电流造成的压降不会串到数字电路里。

3.2 传感器接入电路:RTD 三线制、热电偶与 NTC 三种接法

RTD 三线制接法是这套方案里最有价值的部分。PT100 的引线若有两根 10 欧姆的导线电阻,就等同于给传感器串了 20 欧姆的额外电阻,按 0.385 欧姆每摄氏度算,直接产生超过 50 摄氏度的误差,所以线阻必须补偿。三线制的做法是:PT100 的两端分别接 ADC 的 AINP 和 AINN,另外一端再引一根线接到参考地,同时把两个 IDAC 电流源分别接到这两条传感器引线上。

ADS122U04IPWR 接 PT100 时,典型做法是用一个 IDAC 输出 1mA 电流,从 AINP 引脚流入,经过 PT100 后从 AINN 流出,回到地。测量 AINP 和 AINN 之间的电压,得到的电压值除以激励电流就是 PT100 的阻值。两个 IDAC 的作用更多是抵消导线压降,让测量不受引线电阻变化影响。这里的关键点是两根引线的电阻必须尽量一致,否则补偿就不彻底,实际项目中传感器引线最好用同样规格、同样长度的线。

热电偶接法就简单得多,热电偶两根线直接接 ADC 的差分输入,不用激励电流。但有两个重点:一是热电偶信号源阻抗很低,但仍然建议在 ADC 输入端加一个 RC 低通滤波器,截止频率设置在几百赫兹,滤掉工频和工业现场的电磁干扰;二是冷端必须可靠地与 ADC 的测温参考点热耦合,也就是热电偶的冷端要紧贴 PCB 板或者 ADC 芯片附近,让片内温度传感器读到的温度能代表真正的冷端温度,这个"热耦合"做好了,冷端补偿才有效。

NTC 接法最省事。ADS122U04 的 IDAC 直接给 NTC 供恒流,NTC 另一端接地,测 NTC 上的电压即可。当然 NTC 本身阻值随温度变化非线性,后续要靠 Steinhart-Hart 方程或者查表换算。不过 HVAC 场景里 NTC 测量范围一般不宽,0 到 50 摄氏度范围内用多项式拟合也够用。

3.3 PCB 布局与防护:单点接地、屏蔽和防浪涌

工业现场的 PCB 防护可以分为两个层面。第一层是抗干扰布局。ADC 芯片正下方的 PCB 要铺完整的地铜皮,不要有走线穿过,这是给内部模拟电路提供一个干净的参考平面。传感器信号走线要尽可能短,而且两根差分走线要平行等长,最好旁边铺地铜保护。如果传感器线缆要从 PCB 外面引进来,接口处放一个共模电感或者至少串联 10 到 100 欧姆的电阻,再对地并一个 1nF 电容,把长线引入的共模噪声挡在 ADC 之前。

第二层是浪涌和静电防护。工业现场最怕的不是稳态噪声,而是设备启停、雷击感应产生的浪涌。我在传感器端子处加了 TVS 管,对地做钳位,同时串联电阻限制浪涌电流。这个防护等级不需要做到认证级别,但至少让板子在普通电机的干扰下不死机、不烧 ADC。对于 HVAC 里的温控器,这种工况其实很常见——压缩机一启动,母线上能蹦出几百伏的尖峰,没有防护的板子一次就废了。

还有一个布线的坑:很多工程师喜欢把 ADC 的模拟地和数字地彻底分开,然后用 0 欧姆电阻连一下。这个做法在低频模拟里没问题,但注意0 欧电阻的位置要靠近 ADC,别放到板子另一头去,否则中间那段"地"就成了天线。

4. UART 通信打通:初始化序列、寄存器配置与转换数据解析

4.1 上电复位与通信帧结构

拿到新板子最先做的事不是写应用代码,而是先打通 UART 链路,确认能跟 ADC 对话。这里有一个很多人踩过的坑:ADS122U04 上电之后必须先复位才能可靠通信。复位的做法可以给 MCU 一个 GPIO 去拉 ADC 的复位脚,也可以直接发送复位命令。我实际项目中用了 GPIO 复位,原因很简单,就是想让 MCU 完全掌握上电时序,避免上电瞬间通信乱掉。

复位之后要等待一小段时间让内部振荡器稳定,然后再发配置命令。UART 通信的帧格式建议以数据手册为准,这里只说工程上的要点:每条命令包含地址字节(多片级联时用于寻址)、命令字节和数据字节;如果开启了 CRC,帧尾还要加校验字节。开启 CRC 的成本只是软件里多一段计算,换来的是工业现场可靠性明显提升,建议一定开着。

UART 波特率我用的是 115200,这个速率下几米线缆完全没问题,而且 MCU 端波特率误差能控制在很小范围内。需要注意的是,ADC 内部 oscillator 的精度是有限的,MCU 端 UART 的波特率绝对不能随便配,最好先用逻辑分析仪或者示波器确认实际波形,否则时序边缘上容易偶发误码,这种偶发问题最难查。

4.2 寄存器配置:一组可直接参考的初始化序列

ADC 的配置最终落在几个寄存器里。下面这段是我在项目里实际用的初始化逻辑,不是全部寄存器位定义(以数据手册为准),而是配置思路加典型值,接线不同时你需要对应调整:

  • CONFIG0 寄存器:选择输入通道 MUX、PGA 增益、转换模式和滤波器设置。做 RTD 时 PGA 增益设 8 倍或 16 倍,做热电偶时 PGA 增益设 32 倍或 64 倍;
  • CONFIG1 寄存器:配置数据速率、工作模式(连续转换或单次转换)、IDAC 相关选项。低功耗场景一定要用单次转换模式,测完立刻睡觉;
  • CONFIG2 寄存器:设置两个 IDAC 电流源的大小和输出引脚。RTD 用 1mA 或者 0.5mA,热电偶不用 IDAC;
  • CONFIG3 寄存器:内部温度传感器开关、基准源选择、VREF 内部开关等。

带注释的伪代码大概是这样的:

static void ads122u04_init(void) { // 1. 复位 ll_gpio_set_pin(RESET_PIN, 0); delay_ms(10); ll_gpio_set_pin(RESET_PIN, 1); delay_ms(5); // 2. 配置 PGA 增益和输入通道 // AINP = AIN0, AINN = AIN1, PGA = 8x, 单次转换模式 uint8_t cfg0 = 0x00; // 按你的 MUX 接线调整 cfg0 |= (0 << 6) | (1 << 4); // PGA 增益 8 倍 ads_write_register(0x00, cfg0); // 3. 配置数据速率和 IDAC uint8_t cfg1 = 0x00; cfg1 |= (0x04 << 1); // 数据速率约 20 SPS ads_write_register(0x01, cfg1); // 4. 配置 IDAC 电流源 uint8_t cfg2 = 0x00; cfg2 |= (0x06 << 5); // IDAC = 1.0 mA cfg2 |= (0x1C >> 2); // IDAC 输出引脚选择,按接线调整 ads_write_register(0x02, cfg2); // 5. 开启内部温度传感器(热电偶冷端补偿要用) uint8_t cfg3 = 0x00; cfg3 |= (0x01 << 6); // 内部温度传感器使能 ads_write_register(0x03, cfg3); }

这段代码给你一个基本的框架,实际用的时候要对着寄存器映射把每一位算清楚,别照抄。你只要记住一个原则:配置的顺序是先复位、再配置、最后启动转换,顺序不能乱。

4.3 读取转换结果:字节序、符号扩展与 CRC 处理

配置完成之后,发送启动转换命令,等 DRDY 中断来了之后读取转换结果。ADS122U04 的转换结果通常是 24 位二进制补码,在 UART 帧里是高位在前还是低位在前要看手册,我在项目里读出来的是三个字节,需要自己拼装成 32 位整数再右移八位加上符号扩展。

读数据时的时序细节对精度影响很大。因为用单次转换模式,DRDY 来了必须尽快读,不要拖太久。MCU 端用 DMA 接收最稳,配一个空闲中断,一帧数据收完自动进内存,CPU 连中断都不用频繁触发。CRC 校验放在 DMA 回调里做,校验失败直接丢弃这一帧,等下一次 DRDY 再读,绝不硬着头皮用错误数据。

有一个细节容易忽略:读转换结果这个动作本身会触发 ADC 开始下一次转换(或者结束本次转换)。所以读取命令发早了会拿到上一次的数据,发晚了又可能拖慢节奏。最好的做法是在 DRDY 中断里立刻发读取帧,保证读取窗口对齐。

5. 从原始码到真实温度:RTD、热电偶与 NTC 的换算与校准

5.1 RTD 的阻值到温度换算:查表法与线性插值

拿到了 ADC 的原始码,工作只完成了一半,把原始码换算成温度才是真正体现工程水平的部分。

先说原理链路。以 PT100 三线制为例,ADC 测量的是 AINP 与 AINN 之间的电压,这个电压等于 IDAC 电流乘以 PT100 电阻(忽略理想的线阻补偿之后)。因此:

R_pt = V_measured / I_idac

这里的 V_measured 是从 ADC 原始码换算出来的真实电压。换算公式是:

V = (ADC_Code / 8388608.0) * V_REF / PGA_Gain

24 位二进制补码的满量程对应正负 V_REF 除以 PGA 增益,这个数必须算准,很多人最后温度偏差大就是这一步的小数点位置错了。

得到 R_pt 之后,温度计算有两种路线。第一种是查表加线性插值,IEC 60751 标准有 PT100 的分度表,把 0、10、20、30 摄氏度……对应的电阻值存在 Flash 里,实测电阻落在哪两个点之间就用线性插值。这个方法的优点是速度极快、不用浮点库,缺点是表格占空间,而且插值本身会引入微小误差,不过对 HVAC 应用完全够用。

第二种是Callendar-Van Dusen 公式,数学上更精确,计算量略大。对 0 摄氏度以上,简化形式是:

R( T ) = R0 * ( 1 + A*T + B*T^2 )

其中 A、B、C 是标准系数。STM32L442KC 带 FPU,直接用 float 算没问题。我的建议是:测温范围窄、精度要求不是变态高就查表,范围宽就公式。实际项目里我更常用查表加插值,因为可控性更好,而且表格是标准数据,不会因为公式简化出现边界偏差。

5.2 热电偶冷端补偿:让内部温度传感器物尽其用

热电偶的输出电压取决于测量端和冷端的温差,而不是绝对温度。你测到的 40 微伏每摄氏度只是灵敏度,要得到真实的测量端温度,必须知道冷端温度再补偿。

ADS122U04 的内部温度传感器在这里派上用场。让 ADC 内部温度传感器先输出一个温度值 T_cold,然后在读取热电偶电压 V_thermo 之后,查阅该热电偶类型的分度表,把冷端温度对应的电压加回去,得到补偿后的电压,再反查温度。用 K 型热电偶举例子:

V_compensated = V_measured + V_expected_at( T_cold ) T_hot = lookup_temperature( V_compensated )

工程实现上有两个坑。第一个是分度表的数据密度。K 型热电偶在室温段 1 摄氏度对应的电压变化大约 40 微伏,如果表里每 10 摄氏度才给一个电压值,线性插值的误差不能忽视。我项目中用的是每 1 摄氏度一行的表,Flash 多占几十 KB,但精度踏实。第二个坑是冷端温度传感器的延迟。ADC 内部温度传感器是芯片自身的温度,和热电偶冷端实际温度之间存在热阻,如果板子刚上电,芯片还在发热,读到的冷端温度会偏高。实际处理时,我会在冷端补偿前先做一阶低通滤波,时间常数设成 10 秒左右,让冷端温度平滑变化,这样补偿后的数据稳定得多。

5.3 NTC 的 Steinhart-Hart 公式与查表工程实践

NTC 的阻值与温度的关系不是线性的,但可以用 Steinhart-Hart 方程描述:

1/T = A + B*ln(R) + C*(ln(R))^3

A、B、C 三个系数由 NTC 厂商提供,或者用三个已知温度点反推。算出 T 之后减去 273.15 就是摄氏度。

实际工程里我一般不直接跑浮点对数运算,因为对数函数在 MCU 上偏慢。做法是提前在 PC 上算好温度-电阻映射表,比如从 -40 到 120 摄氏度、每 0.1 摄氏度一个点,然后存成一个 const 数组。运行时拿实测电阻值去数组里二分查找,再线性插值。这样 MCU 端只有几十条指令,功耗和延迟都好看。HVAC 场景里 NTC 精度不需要跟 PT100 比,0.5 摄氏度的误差完全能接受。

5.4 校准方法与精度预算:用精密电阻箱替代冰水浴

软件换算做完了,下一步是校准。很多新手喜欢用冰水浴和沸水来做两点校准,这在实验室里没问题,但在工程现场太麻烦,而且沸点受大气压影响,温度并不是精确的 100 摄氏度。

我更推荐用精密电阻箱来校准。电阻箱能给出非常精确的阻值,比如 100 欧姆、138.51 欧姆、175.84 欧姆,这些恰好对应 PT100 的 0、100、200 摄氏度。把电阻箱接到 ADC 输入,让系统测出来的温度值和电阻箱设定值对比,记录偏差,然后做两点增益校准和偏移校准。

误差预算方面,我习惯在项目一开始就列一张表,把每一项误差来源和量级估算清楚:

误差来源典型量级影响
ADC 内部基准温漂个位 ppm/摄氏度量级全量程比例误差
PGA 增益误差0.02% 量级全量程比例误差
IDAC 电流精度与温漂0.1% 量级RTD 测量的比例误差
传感器导线电阻不匹配取决于接线零点偏移
ADC 量化噪声与有效位与数据速率有关温度波动
NTC 分度表插值误差0.1 摄氏度量级绝对误差

做完校准之后,正常情况下这套系统能做到 0.2 摄氏度以内的误差,HVAC 和大多数工业温度监测的需求都能覆盖。

6. 固件工程落地:模块结构、低功耗节奏与实测中的典型坑

6.1 固件模块划分:采集、换算、调度三层职责

固件写得不清晰,后期调试就是灾难。我把代码分成三个模块:

  • adc_uart 层:封装 UART 收发、CRC 校验、寄存器读写、原始数据解析。对外只暴露ads_read_temperature()、ads_read_internal_temp()这样的接口,不让上层代码看到任何寄存器操作;
  • temperature 层:传感器数据后处理。输入是原始码,输出是物理温度,内部查表、插值、冷端补偿都在这层完成。这一层和硬件完全解耦,方便在 PC 上先用同一套算法做仿真验证;
  • app_schedule 层:测量节奏管理、数据滤波、报警判断、日志输出、低功耗状态切换。真正的业务逻辑都在这层。

模块分清楚之后,最大的好处是可以在 PC 上直接调试换算算法。拿同样的原始码数据,在 PC 上跑一遍 C 代码,跟板子上跑的结果对比,出现偏差就是移植问题,排查范围很小。

6.2 低功耗测量节奏:Stop2 模式与 RTC 定时唤醒

HVAC 温控器这类设备通常不要求连续采样,30 秒或者 1 分钟测一次温度,完全够用。这个特性可以转化成相当可观的功耗优势。

我的节奏设计是:RTC 设定 30 秒周期性唤醒 MCU,MCU 从 Stop 2 模式唤醒后,给 ADC 发启动转换命令,等待 DRDY,读数据,做换算和滤波,然后立刻再次进入 Stop 2。整个测量过程大约 80 到 120 毫秒,其余 29.9 秒都在睡觉。

功耗可以简单估算一下:

测量状态电流约 3mA,持续时间 0.1s 休眠状态电流约 2uA,持续 29.9s 平均电流 = (3mA * 0.1s + 2uA * 29.9s) / 30s ≈ 12uA

干电池供电的话,2000mAh 电池理论能用十几年,实际上要考虑电池自放电,但一年以上轻轻松松。这个功耗水平比很多专门的低功耗测温芯片方案还要省,原因就是整个系统没有多余的外设一直通电。

有一点必须提醒:ADC 本身在测量间隔内也要进入低功耗模式。单次转换模式下,ADS122U04 测完会自动进入关断状态,电流降到很低。你只要确保 MCU 休眠前把 UART 的 RX 引脚配置成带唤醒中断的状态,或者干脆用 RTC 唤醒 MCU 之后再主动初始化通信即可。千万不要让 ADC 一直以连续转换模式跑着,那样功耗全部白省。

6.3 实测数据与四个经典坑:自热、线阻、波特率、基准

这套方案我实际打样测试过,室温稳定环境下,用电阻箱给定 100 欧姆输入(0 摄氏度),连续采 100 次,温度值稳定在正负 0.03 摄氏度以内;用恒温槽给定 50 摄氏度,实测 49.94 到 50.06 摄氏度之间跳动。对于 HVAC 场景,这个精度已经非常宽裕。

但测试过程中也确实踩了不少坑,挑四个最典型的说:

坑一:IDAC 自热效应。激励电流流过 RTD 本身会产生热量,导致传感器自身温度高于被测介质。用 1mA 电流做 PT100 时,在空气中自热大约会造成 0.1 摄氏度的偏移,在液体中会小一些。解决的思路有两个:一是尽量用 0.5mA 档位,二是校准的时候把激励电流设为最终运行的电流。这个误差是系统性的,校准可以吃掉大部分。

坑二:三线制两根引线电阻不一致。我用不同长度的线做测试,两根引线差了 2 欧姆,温度偏移超过 5 摄氏度和之前的分析完全对上。后来统一换成等长线缆,误差立刻消失。讲道理的事情在工程现场往往就是输在细节上,传感器引线材质和长度必须严格一致。

坑三:UART 波特率误差的偶发误码。MCU 内部 RC 振荡器精度不够时,UART 偶发乱码是最难查的。现象是十分钟才错一帧,你盯着看它又正常了。解决办法是 MCU 端启用外部晶振,同时把 UART 波特率误差控制在正负 2% 以内,实测 115200 波特率下稳定跑三天无一帧 CRC 错误。

坑四:内部基准在宽温下的一致性。内部基准的温漂是固定属性,只要做了校准,恒温下精度没问题。但当环境温度跨度很大的时候,基准温漂会被线性放大成温度误差。有一次我把板子从 25 摄氏度的室内拿到 10 摄氏度的室外,温度读数整体偏了 0.3 摄氏度。后来在固件里加了一个基于实测环境温度的二次补偿项,才把这个偏移压下去。如果你要覆盖宽温应用,建议认真评估是否改用外部基准源。

最后分享一个我常用的现场调试技巧:给固件留一个"原始数据透传"模式。需要用串口把 ADC 原始码、内部温度传感器读数、换算后的温度三者同时打印出来。一般偏差问题看一眼这三组数据就能判断是硬件问题、换算问题还是通信问题。这个习惯帮我省过无数次现场排查的功夫,做工业测温的朋友可以试一下。

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

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

立即咨询