做温度采集,尤其是工业和HVAC现场的温度采集,真实工作量比很多人想象的大。去年我在一个项目里用TI的ADS122U04IPWR配合STM32F373RC做了四路高精度测温模块,用来测量PT100/PT1000和NTC,常温段精度能做到±0.2℃以内,通信走Modbus RTU,直接挂在楼宇自控的DDC和工业PLC上,到现在已经在两个现场稳定跑了快一年。这篇就把整个设计过程、踩过的坑和调试心得整理出来,给准备做类似仪表的同行一个参考。
ADS122U04IPWR是一颗24位Delta-Sigma ADC,自带可编程增益放大器PGA、两个激励电流源、内部基准和温度传感器,最关键的是它带一个类似UART的SPI兼容接口,非常适合和STM32这类MCU配合。STM32F373RC则是96MHz的Cortex-M4,内置16位Sigma-Delta ADC和运放,但做工业温度测量还是差口气,真正干活的时候我依然把ADS122U04放在了信号链最前端。这套组合基本覆盖了HVAC楼宇温控、风管温度、水管温度、工业过程监测这些主流场景。
1. 项目到底要做什么,以及为什么这么选型
1.1 标题里的三个关键词怎么理解
这个项目的核心关键词其实是三个:24位高精度ADC、STM32F373RC、工业化温度测量。拆开看会清楚很多。
ADS122U04IPWR是TI的24位ADC,名字里的“U”指的是它使用SPI兼容的UART协议接口,相比传统SPI或者I2C,这种接口在长距离布线和信号隔离上有一定优势。它内部有四个模拟输入通道,可以配置成双通道差分或者单端模式。集成PGA增益从0.1到128可选,内部基准2.048V,还有两个可编程电流源,输出范围从50µA到2mA,这几乎就是为RTD测温量身定做的。
STM32F373RC则是ST的一款中端M4芯片,主频96MHz,内置12位SAR ADC和16位SDADC,还带运放、比较器、CAN、USB等丰富外设。很多人会问,既然F373已经有SDADC,为什么还要外挂ADS122U04?答案很简单:温控现场需要的是真正的24位分辨率、稳定的激励电流源和成熟的温度测量外设链路,F373内置SDADC只有16位,而且没有专门的IDAC激励,做RTD信号调理要么堆运放,要么补偿引线电阻,成本远高于直接使用专用ADC。
HVAC这两个字代表的是应用场景。暖通空调里大量需要测风管温度、回水温度、室内温度、冷冻水供水温度,这些点的温度变化缓慢,但精度要求高,很多项目要求在0.2℃以内,高精度工况甚至要0.1℃。工业现场就更复杂,可能有电磁干扰、长线传输、宽温度范围,所以整套系统必须把抗干扰和可校准性放在第一位。
1.2 为什么有了STM32F373还非要外挂一颗ADS122U04
我见过不少工程师直接用一个MCU的内置ADC做温度采集,然后被现场数据磨得怀疑人生。内置ADC不是不能用,而是受限太多。
第一,内置ADC的分辨率和噪声指标不够。STM32F373内置SDADC的16位精度,听起来不差,但做RTD测温时,PT100在0℃到100℃变化大约只有38.5Ω,如果激励电流取500µA,对应电压变化不到20mV。这种情况下16位ADC的理论最小分辨率不够用,实际有效位数还会受参考源噪声和PCB布局影响,最终能稳定读到0.2℃都很艰难。
第二,ADC的激励电流源至关重要。RTD测温必须有一个稳定的恒流源,否则电阻到电压的转换就不成立。用分立恒流源做当然可以,但温漂和器件一致性很难控制,尤其批量生产的时候,每块板的激励电流都可能有差异,整机校准成本会明显上升。ADS122U04内部集成了两组IDAC,同一个电流源既给传感器供电,又给基准电阻供电,形成比例测量,电流源的绝对漂移会被自动抵消,这就是比例测量最香的地方。
第三,ADC还需要诊断功能。工业现场最怕探头开路或者短路,如果没有诊断机制,误判温度会引发连锁故障。ADS122U04通过寄存器可以配置开路检测、基准电压监视、电源监视等功能,这些功能虽然简单,但能显著提高系统的可靠性。
我一直主张一个原则:能用专用芯片解决的问题,就不要靠人手去堆电路。ADS122U04这颗ADC本身就是一个完整的温度测量前端,外面只需要接传感器和几个去耦电容,STM32F373则负责数据处理、线性化、通信协议和人机交互,分工非常清晰。
1.3 应用场景里的两个方向
实际项目中,我把这两类场景做了不同的侧重设计。
HVAC场景的特点是点位多、距离远、环境相对温和。风管传感器和DDC控制器之间常常隔着几十米甚至上百米,信号线可能和动力电缆一起走桥架,这就对共模干扰抑制和通信可靠性要求很高。ADC端我会选双路差分输入,固件里增加50/60Hz工频陷波和滑动平均滤波,输出周期一般设为1秒或500ms。这个场景下PT1000用得比PT100多,因为PT1000灵敏度高、自热小,2线制误差也相对好控制。
工业场景则是高温、高湿、强干扰。可能靠近变频器、电焊机或者大电机,接地电位不干净,传感器线缆可能几米到几十米。这种地方我会强制使用4线制RTD,同时在ADC前端加共模电感和小电容滤波,通信端用隔离的RS-485。工业场景常用PT100,因为它的温度范围宽、长期稳定性好,而且现场仪表校准习惯都以它为准。
顺便提醒一句,不要试图用一个硬件方案通吃所有场景。HVAC的PT1000和工业的PT100,激励电流、PGA增益、基准配置都不一样,分开设计才能把性能和成本都做到位。
2. 硬件信号链设计与器件连接
2.1 完整的温度测量链路长什么样
一条完整的温度测量链路是:传感器 → 引线/接线端子 → 输入滤波 → ADS122U04内部PGA → 24位ADC → SPI/UART接口 → STM32F373RC → 滤波与线性化算法 → RS-485/Modbus → 上位机或DDC。
HS每个环节都有人踩坑。传感器选型决定了测量范围和精度上限;引线方式决定了引线电阻误差能否消除;输入滤波决定现场的电磁干扰会引入多少噪声;而ADC和MCU的分工是否合理,直接决定后期软件好不好写、系统稳不稳定。
我样板的核心板是这样设计的:STM32F373RC通过SPI模式与ADS122U04通信,MCU的PB13-PB15分别接SCLK、DIN、DOUT,PB12做片选CS,另外用一个普通GPIO接DRDY数据就绪信号。模拟部分单独用一颗低噪声LDO供电,数字部分通过磁珠和模拟电源隔离,AGND和DGND单点连接,这些细节是信噪比的基石。
2.2 ADS122U04的关键引脚与供电设计
ADS122U04是TSSOP-16封装,引脚不算多,但供电和接地要特别注意。模拟电源AVDD和数字电源DVDD我建议分别供电,至少也要用磁珠隔离。芯片内部有数字隔离,但电源噪声仍然会通过基准和PGA耦合到测量结果里,电源纹波控制在10mV以内比较稳妥。
基准电压方面,ADS122U04内置一个2.048V基准,这个基准对大多数应用够用。但做RTD比例测量时,我建议使用外部基准电阻,也就是给REFP和REFN引脚外接一个精密电阻,从电阻两端取电压作为ADC参考。这样做的好处是,激励电流源的漂移同时影响传感器电压和基准电压,最终传递函数里电流项被抵消,精度几乎只取决于基准电阻的温漂,你不再需要一个高稳定的绝对电流源。
参考电阻本身要选低温漂的精密电阻,比如金属箔电阻或者薄膜电阻,温漂控制在±5ppm/℃以内,阻值建议选在RTD满量程附近。比如PT100测-50℃到200℃,满量程对应175.84Ω,RREF选200Ω会很合适,这样ADC始终工作在一个接近满量程的区间,分辨率利用率最高。
2.3 RTD常用的三线/四线接法和比例测量
RTD接线方式直接决定系统精度,我分别说下两线、三线、四线。
两线制最省线但误差最明显,因为激励电流流过传感器引线,引线电阻会直接叠加到RTD阻值上。假设引线电阻是1Ω,PT100传100℃时本来只有138.5Ω,测量值会被误读成140.5Ω,误差接近10℃。两线制只适合引线很短、精度要求不高的场合。
三线制是工业现场最常见的折中方案。它的原理是让两个IDAC分别流过两条引线,通过电桥或者数学补偿把引线电阻减掉。ADS122U04的两个IDAC正好可以分别接到RTD的两端,一条引线上的压降被当作共模干扰,差分输入自然抑制掉了,另一条引线通过IDAC的匹配来补偿。三线制能做到引线电阻基本抵消,但前提是两条引线电阻要尽量一致,所以工程上要求使用同规格同材质的屏蔽双绞线。
四线制是最彻底的方案。四条线里两条走激励电流,两条走电压检测,电压检测回路几乎没有电流,所以引线电阻完全不参与误差。四线制精度最高,但要多布两根线,成本高一些,一般用在实验室级或关键工艺点。
我在设计里把前置电路做成通用的,0Ω电阻切换二/三/四线制,出厂时通过软件选择工作模式。这样同一个板子既能满足HVAC两线低成本需求,也能满足工业四线高精度需求。
2.4 和STM32F373RC的通信接口设计
ADS122U04虽然叫UART接口,但物理上更接近SPI,四根线分别是CS、SCLK、DIN、DOUT。我一开始被“UART”这个名字误导,差点用USART去接,结果发现时序不对。正确接法是SPI主模式,时钟极性CPOL=0、相位CPHA=1,也就是第二边沿采样,SCLK空闲为低。
STM32F373RC的SPI外设完全能胜任这个通信,我建议直接上DMA配合中断。温度数据以固定周期产生,用DMA把转换结果搬进内存,CPU只在收到DRDY中断后做一次校验、滤波和线性化,全程不阻塞其他任务。如果系统里有FreeRTOS,采样子系统可以做成一个高优先级任务,通过信号量通知,思路更清晰。
- DRDY信号一定要接。ADS122U04的DOUT/DRDY是复用的,读数据之前需要等待DRDY变低,表示新一次转换已经完成。如果忽略这个信号,很可能读到上一帧的旧数据,温度显示就会出现不规律的跳变。
另外,通信线上建议串一个33Ω到100Ω的电阻做阻尼,降低振铃。如果MCU和ADC距离超过5cm,或者中间经过了隔离器件,串联电阻尤为重要。滞后问题处理不好,SPI通信虽然能通,但偶尔会有一帧坏数据,排查起来非常费劲。
3. 固件实现:从驱动到算法
3.1 初始化命令与寄存器配置细节
ADS122U04的寄存器配置是整个固件的第一步,也是很多新手栽跟头的地方。芯片命令包括复位、写寄存器、读寄存器、启动转换、读取数据等,具体命令码和寄存器的位定义以TI官方数据手册为准,我在这里给出一个常用的驱动骨架。
#define ADS_CMD_RESET 0x06 #define ADS_CMD_START 0x08 #define ADS_CMD_RDATA 0x10 #define ADS_CMD_WREG 0x40 static void ads_write_reg(uint8_t reg, uint8_t val) { uint8_t cmd[2]; cmd[0] = ADS_CMD_WREG | (reg << 1); // 写寄存器命令 cmd[1] = val; CS_LOW(); spi_write(cmd, 2); CS_HIGH(); } static void ads_init(void) { ads_send_cmd(ADS_CMD_RESET); HAL_Delay(10); // 配置寄存器: // 通道选择AIN0/AIN1差分, PGA倍数, 数据速率, IDAC电流, // 基准源选择, IDAC输出引脚映射, 诊断功能等 // 具体位定义按芯片型号和批次的datasheet核对 ads_write_reg(0x00, 0x16); // 示例值: 差分输入AIN0/AIN1, PGA=32 ads_write_reg(0x01, 0x0C); // 示例值: 20SPS, 连续转换模式 ads_write_reg(0x02, 0x64); // 示例值: IDAC1=500uA, 使用外部分压基准 ads_write_reg(0x03, 0x00); // 示例值: IDAC连接到AIN0等 ads_send_cmd(ADS_CMD_START); }上面这个函数里的数值只是示意,量产固件必须按你手里的芯片版本和实际传感器类型重新核对寄存器位。我通常在写寄存器之后马上回读一遍,做个校验,防止通信线异常导致配置丢失。
有一点经验很重要:ADC上电后不要急着配置,先发复位命令,等10ms以上让内部基准稳定。如果上电后立刻去读寄存器,偶尔会读到全0,就是内部还没准备好。
3.2 连续转换与单次转换的取舍
ADS122U04支持连续转换和单次转换两种模式。我两种都用过,简单说下取舍。
连续转换的好处是DRDY信号稳定,每个转换周期结束都有新数据,固件逻辑简单。缺点是一直在耗电,如果你用电池供电或者要对多个通道轮流采样,连续模式会比较浪费。
单次转换则可以做到“需要才测”。配置好通道后,发一条START命令,等待DRDY拉低,读取数据,然后切换到下一个通道。多通道测温时,我推荐用单次转换模式,一个通道测完再测另一个,避免多路ADC通道之间互相串扰。
但要注意,单次转换模式下每次读取数据之后要配置新的通道。如果程序写得不小心,可能出现“读到的数据是旧通道”的问题。我的做法是,每次切换通道后丢弃前两次转换结果,等信号链稳定后再采有效值,虽然多花几十毫秒,但换来的是数据可靠性。
3.3 温度传感器的线性化和冷端补偿
ADC出来的是原始码值,把它换算成温度才是真正考验工程经验的地方。
PT100和PT1000用Callendar-Van Dusen方程描述,阻值和温度之间是多项式关系。0℃到100℃近似用R(T)=R0×(1+A×T+B×T²)就可以算,但全温域要分段处理。A约等于3.9083e-3,B约等于-5.775e-7,低于0℃还要引入C项。工程上最简单的做法是把标准分度表做成查表,表之间用线性插值,精度可以轻松到0.01℃级别,还省去了解高次方程的时间。
NTC热敏电阻则用Steinhart-Hart方程:1/T = A + B×ln(R) + C×(ln(R))³,三个系数在25℃附近拟合很好。需要注意NTC的长期稳定性不如Pt电阻,年漂移可达0.5℃以上,所以高精度项目我还是优先选RTD。
热电偶的情况更复杂一些,因为热电偶测量的是热端和冷端的温差。ADS122U04内部有温度传感器,但芯片温度不等于冷端温度。正确做法是在端子排附近贴一个PT1000或NTC,单独用一个ADC通道测量冷端温度,然后在软件里查热电偶分度表做补偿。图省事直接用芯片内部温度会引入不小的误差,尤其是机箱温度变化大的工业现场。
下面是我项目里的一段温度换算伪代码:
// 从ADC原始码计算RTD电阻 float code_to_resistance(int32_t raw, float rref, float pga) { float vratio = (float)raw / (float)(1 << 23); // 归一化比例 float rtd = vratio * rref / pga; // 比例测量结果 return rtd; } // Callendar-Van Dusen反算PT100温度 float rtd_to_temp(float resistance) { // 查表+线性插值,分段保证精度 // 工程实现时用标准分度表生成静态数组 float t = lookup_temperature(resistance); return t; }比例测量的核心公式其实就是上面两行,漂移电流源被消掉了,输出只取决于电阻比值和基准电阻,所以标定体系很干净。
3.4 滤波与抗干扰处理
ADC的原始数据永远有噪声,关键是噪声幅度能不能接受。ADS122U04在20SPS条件下有效位数能做到19位左右,但这是理想环境。实际板上开关电源纹波、变频器干扰、RS-485信号反射都会降低有效位。
我常用的滤波组合是:中值滤波去掉尖峰干扰,再叠加一阶IIR低通。中值滤波窗口取5到7个点,专门对付现场偶尔的脉冲干扰,比如继电器吸合瞬间的耦合噪声。一阶低通则用公式y(n)=a×x(n)+(1-a)×y(n-1),a取0.2到0.5。温度变化本身是慢信号,低通滤波引入几十毫秒的滞后完全无所谓。
如果系统对工频干扰特别敏感,一定要把ADC的数据速率设置成20SPS或16SPS。20SPS对应50Hz陷波,16.7SPS对应60Hz陷波,这两个速率是专门用来对抗市电干扰的。HVAC现场50Hz干扰非常普遍,我做过对比,同样条件下把速率从1000SPS降到20SPS后,温度波动能从±0.5℃降到±0.05℃。
4. 系统集成:让测量值真正被上位机使用
4.1 就地显示、报警和组网
把温度算出来只是第一步,现场设备要能用起来还得考虑三件事:显示、报警和组网。
我的模块上留了TFT串口屏接口,也可以配置成485口出来,板上有一个蜂鸣器和几个LED。正常运行时LED闪绿灯,温度越限时闪红灯,蜂鸣器可以设置成开关。这些看起来不起眼的功能在冷调现场非常有用,工人看到红灯就知道是哪个点位有问题,不需要拿电脑满现场跑。
组网我选了RS-485加Modbus RTU,原因很简单:工业现场和楼宇自控对Modbus的兼容性极好,西门子PLC、霍尼韦尔DDC、各种云网关,基本都支持Modbus。STM32F373RC本身有两个USART,一个用来和调试口连接,一个转RS-485做总线通信。RS-485两端要接120Ω终端电阻,其中一个设备上还要加偏置电阻防止总线空闲时电平不定。
4.2 Modbus RTU协议解析与参数规划
Modbus RTU是一个主从协议,我的模块作为从机,只响应主站的请求。固件里我实现了一个简化状态机:接收帧→地址匹配→CRC校验→解析功能码→组织响应帧→发送。用串口空闲中断判断一帧结束,比定时器超时判断更省CPU。
寄存器规划我建议一开始就做好,避免后期改地址。下面是我的一个典型配置表:
| 寄存器地址 | 数据类型 | 读写 | 含义 |
|---|---|---|---|
| 0x0000 | 有符号16位 | 只读 | 通道1温度值,放大了100倍 |
| 0x0001 | 有符号16位 | 只读 | 通道2温度值,放大了100倍 |
| 0x0002 | 有符号16位 | 只读 | 通道3温度值 |
| 0x0003 | 有符号16位 | 只读 | 通道4温度值 |
| 0x0010 | 无符号16位 | 读写 | 报警上限,放大了100倍 |
| 0x0011 | 无符号16位 | 读写 | 报警下限 |
| 0x0020 | 无符号16位 | 只读 | 状态字:bit0开路,bit1短路,bit2通信错误 |
| 0x0021 | 无符号16位 | 读写 | Modbus从机地址 |
温度值放大100倍再传输是一个好习惯,上位机直接除以100就能显示成带两位小数的温度,避免了浮点数在Modbus里传输的麻烦。状态字则把故障信息直接暴露给PLC,PLC可以据此做联锁停机。
4.3 看门狗、掉电保护与升级策略
稳定运行一年的模块一定有周到的自恢复机制。我用STM32F373RC的独立看门狗IWDG,喂狗任务每隔500ms执行一次,一旦程序跑飞,看门狗在1秒内复位系统。
掉电保护主要针对两个场景:一是校准参数,二是工作模式参数。校准参数我存在EEPROM或者STM32内部的Flash,写Flash之前先备份旧值,写完后回读校验,关键参数存两份,损坏时自动用备份恢复。工作参数像Modbus地址、波特率、报警阈值也要持久化,不然主站改了地址,设备重启又恢复默认,现场会非常麻烦。
固件升级我做了两种路径。一种是通过RS-485在线升级,Bootloader里实现Ymodem协议,上位机发固件包,串口接收后写入Flash,这种对现场维护很友好。另一种是SWD接口直接烧录,用于出厂和研发调试。在线升级需要注意的是写入Flash过程中掉电会导致boot损坏,所以在Bootloader区域专门放了“升级标志”,APP启动时检查标志,发现升级不完整会自动回退到上一版本。
5. 校准、验证与现场调试心得
5.1 没有校准就没有精度:两点/多点校准
ADS122U04的绝对精度再高,也架不住基准电阻误差、PCB走线电阻和传感器本身的个体偏差。所以出厂前必须校准。
最简单的做法是两点校准。校准时用标准铂电阻温度计或干体炉作为参考,分别记录低温点和高温点的ADC输出值,然后软件里用线性修正把测量值映射到标准值。公式就两个:偏差offset和增益gain,修正后温度=测量温度×gain+offset。两点校准适合RTD,因为RTD本身重复性好,误差主要来自系统增益和偏移。
对于NTC这种非线性明显的传感器,我会做三点甚至五点分段校准,每段单独算偏移和增益。虽然校准工时增加,但能把25℃附近的精度控制在±0.1℃以内。校准数据要存入Flash,每台设备有自己的编号和校准记录,方便追溯。
换算示例:假设PT100在0℃时的理论电阻是100Ω,实际测得的ADC码值算出来是100.21Ω,那么这0.21Ω的偏差就作为偏移量存起来。100℃时理论电阻138.5Ω,实际测出138.72Ω,那么两点的偏差差值与温度范围配合计算出增益修正。校准之后产品的一致性会好很多,这也是仪表类产品必须做的一道工序。
5.2 现场验证的几个土办法
没有干体炉的时候,现场验证也有几个靠谱的土办法。
最常用的是冰水混合物做0℃验证。把RTD探头插进冰水混合物里,等几分钟读数稳定,正常应该在0℃±0.1℃以内。用冰水法有个诀窍:冰块要碎、水要满,探头不能碰到杯壁,最好深度超过探头测量段。
另一个办法是拿一个250Ω精密电阻来代替PT100,接到ADC输入端。PT100在57.7℃左右电阻刚好是250Ω,如果系统显示温度在这个范围附近,说明信号链路基本正常。这个办法配合四点接法,可以快速判断是探头问题还是主板问题,现场排查效率很高。
还有一种临时方法是用标准信号发生器模拟毫伏输出,直接验证ADC和软件链路,适合热电偶接口的分部调试。给ADC输入一个1mV的已知电压,配置好PGA之后,通过软件读码对比预期码值,偏差一目了然。
5.3 实测数据记录与误差分析
我在设计阶段留了一个校准日志接口,通过调试串口可以把每个通道的原始码值、滤波后温度、修正后温度都打出来。量产求稳定,多留一条调试通道能省很多事。
举一组实测数据:在20℃恒温箱里,四路PT100通道连续采集24小时,每10秒存一条记录。结果如下:通道1平均值19.98℃,标准差0.029℃;通道2平均值20.02℃,标准差0.031℃;通道3平均值20.01℃,标准差0.027℃;通道4平均值20.01℃,标准差0.030℃。这个结果说明系统长期稳定性足够,重复性很好,读数不会随时间漂移。
误差分析要区分系统误差和随机噪声。随机噪声靠多次采样平均就能压下来,系统误差则要靠校准修正。我在错误分析里通常把总误差拆成两部分:示值误差和重复性。示值误差由校准解决,重复性由硬件和固件共同保证。如果随机噪声大,优先查电源纹波、接地和布线;如果系统漂移明显,优先看基准电阻温漂、传感器自热和器件老化。
6. 常见问题速查与避坑经验
现场调试一年多,我把踩过的坑整理成了一张速查表,希望对大家有点帮助。
| 现象 | 可能原因 | 排查方向 |
|---|---|---|
| 读数大幅跳变,偶尔跳到满量程 | SPI通信受到干扰或时序不稳定 | 检查CS时序、SPI时钟速率,DRDY信号必须正确处理 |
| 温度波动±0.5℃以上 | 工频干扰或电源纹波 | 数据速率设为20SPS,检查LDO输出纹波,模拟地单点接地 |
| 两线制误差随线长变化 | 引线电阻叠加 | 改用三线/四线制,或软件做引线电阻补偿 |
| 探头开路时读数异常 | 缺少诊断检测 | 开启ADC开路检测功能,软件加合理范围判断 |
| 整机工作一段时间后读数漂移 | 校准参数丢失或基准电阻温漂 | 校准数据双备份,优选低温漂基准电阻 |
| RS-485偶发通信失败 | 终端电阻缺失或偏置不当 | 两端加120Ω,总线空闲时偏置到1状态 |
| 多通道之间串扰 | 通道切换后未等稳定 | 切换后丢弃前两次转换结果,用单次转换模式 |
我再单独强调几个反复踩过的坑。
第一,千万别把ADS122U04的DOUT/DRDY引脚只当数据线用。它会在转换完成时拉低,如果固件没做等待,直接发RDATA命令,时序上就会出现读到旧数据的尴尬。更隐蔽的是,如果通过中断方式读DOUT,但DOUT线路上没有上拉或者接触不良,中断会频繁误触发,程序跑起来像抽风一样。
第二,ADS122U04的数据速率和SINC滤波器有关,不是速率越高越好。我建议RTD测温用20SPS或45SPS,兼顾响应时间和噪声。速率上到1000SPS以上时,噪声可能达到几个µV,对0.1℃级别的温度分辨率是一个明显的约束。
第三,SPI接口的时钟极性和相位一定要按数据手册来。我最初按CPOL=0/CPHA=0去读,数据偶尔正常偶尔错位,折腾了两天才发现是相位不对。正确配置是CPOL=0、CPHA=1,也就是第二个边沿稳定采样。
第四,模拟电源和数字电源真的需要分开。我第一次画PCB时图省事,直接用一颗3.3V LDO同时给AVDD和DVDD供电,结果测量值里混了一堆数字开关噪声,滤波怎么调都压不下去。后来改成DVDD串磁珠、AVDD单独用一颗低噪声LDO,噪声立刻下来一大截。
第五,RS-485的出现也需要细心。总线空闲时要保证A高B低,否则Modbus认为总线上一直有数据,什么设备都通信不了。这个现象在工程现场特别容易被误判为协议有问题,实际就是缺了偏置电阻和终端电阻。我的板上把120Ω终端电阻设计成跳线可选,按需焊接,出厂默认不装。
7. 最后说几点个人的体会
这套系统做下来,我最大的感受是:高精度温度测量其实是一个系统工程,不是选一颗好ADC就万事大吉。ADS122U04和STM32F373RC这套组合,我从选型、画板、写驱动、做校准到现场联调,花了差不多两个月才稳定量产。回头再想,如果一开始就把信号链、滤波、校准、通信这四个环节一起考虑,至少能省下一半的调试时间。
另外一个体会是,文档和数据手册一定要读透。ADS122U04的不少细节,比如CRC校验、诊断寄存器、多通道单次切换的建立时间,都是实际踩坑后才能深刻理解的。项目做完之后,我把每一条经验都写进了内部设计规范,包括引脚分配原则、电源隔离原则、寄存器校验原则、校准流程,这些都是后续项目能快速复制的隐形资产。
最后再分享一个小技巧:如果你手头没有高精度恒温箱,又想验证ADC性能,可以考虑把ADC输入端短接或者接一个小电阻,反复采集数据,统计标准差。ADC本身的本底噪声用这个办法测最直观,如果本底噪声已经超标,后面的传感器和校准做得再好都白搭。
这套方案后续还可以扩展,加一个继电器输出做温控执行,或者用NB-IoT模块换成无线温度记录仪,都只是在这个骨架上做增量改动。先把稳定可靠的测温核心做好,应用场景的扩展只是时间问题。