资讯详情

基于ADS122U04与STM32F413的HVAC温度采集方案与工程实践

📅 2026/11/5 3:12:03 | 华诺云谱 👁 阅读
基于ADS122U04与STM32F413的HVAC温度采集方案与工程实践
半年前接手的那个冷站群控改造项目让我对HVAC温度测量彻底改观了。现场要测冷冻水进出水温度、冷却水温度、风管露点温度还要兼顾压缩机壳温和电机轴承温度传感器分散在四层楼原厂用的是PT100加模拟变送器4-20mA拉回PLC。结果是线缆一长变频器一开温度在控制面板上跳舞运维被折腾得够呛。那之后我重新搭了一套方案核心器件就是标题里这两个ADS122U04IPWRTI的24位UART接口ADC和STM32F413RHST的Cortex-M4F单片机专攻工业和HVAC应用中的温度测量。这篇文章不是芯片手册的复读而是我把这个项目从选型、硬件设计、串口驱动到温度换算、现场调试整个流程里值得抄作业的部分整理出来。适合正在做温度采集节点、楼宇自控、冷链监测、工业设备状态监控的人看如果你只想快速知道“PT100接到哪儿、代码怎么写”后两节可以直接拿去用。1. 为什么这套方案先打动我的不是精度而是串口1.1 楼宇空调温度采集的现场困境HVAC系统里温度传感器和控制器之间动不动就隔着十几米甚至几十米线。传统做法是PT100变送器转换成4-20mA这信号是模拟的一路上要经过穿线管、桥架、变频器电缆沟干扰全被捡回来了。更麻烦的是一台冷水机组要测的点位动辄十几个每个点位拉一根模拟线施工成本和故障点都翻倍。我之前还试过用SPI接口的ADC比如ADS1256搭配F103。SPI在板内通信没问题但一旦传感器线稍微长一点时钟信号和片选信号的时序就很容易被干扰飞线调试时特别痛苦。后来看到ADS122U04IPWR这个型号第一反应是“ADC还带UART”再一看手册四通道、24位、内置PGA、内置精密基准、还带两个可编程恒流源IDAC这基本就是为温度测量量身定做的。1.2 24位、四通道、自带恒流源和基准的UART ADCADS122U04IPWR里后缀的“IPWR”其实是封装和温度等级信息I表示工业温度范围PWR表示TSSOP-16封装、卷带包装。采购的时候如果只写ADS122U04供应商可能给你工业级也可能给你商业级别在这上面省事。这个芯片最特别的地方是把ADC和串口放在了一起。MCU只需要两根线TX、RX就能和它通信不需要像SPI那样还得管时钟线和片选线。对于温度采集这种“传感器可能放到设备旁边、主控放在控制柜里”的场景UART天生就比SPI适合。再往后如果你想把它变成RS-485总线随便一级转换芯片就能搞定线长能拉到几百米。芯片内部集成了四通道输入多路复用器、增益1到128的可编程放大器、2.048V内部基准源、两个IDAC电流源还有一个用于冷端补偿的内部温度传感器。换句话说做PT100、PT1000、热电偶、NTC这几种最常见的温度传感器外围基本不需要运放和基准芯片一个ADC全包了。1.3 谁适合抄这套方案和常用替代方案的账本对比先看一个替代方案对比方便你判断自己是不是属于这套方案的受众方案通道数接口外围复杂度适合场景ADS122U04 STM32F4134入/片UART低无需基准IC多点温度、分布式采集节点MAX318651路RTDSPI很低单点PT100/PT1000PCB空间极小ADS1256 外部运放8入SPI高需自己搭恒流源多通道通用数据采集板4-20mA变送器 PLC1路/变送器模拟较高需屏蔽电缆老系统改造接口固定如果你只是在PCB上测一路PT100那MAX31865确实更省事。但一旦涉及多点、多类型传感器、需要把温度数据就地数字化再回传ADS122U04这种UART接口的片子在工程上省下的时间远比你多写几行代码的时间值钱。STM32F413RH这边核心是Cortex-M4F带浮点运算和DSP指令64引脚封装多路串口带FIFO。有人会觉得测温度用8位单片机就够了但后面我要在上面做多通道滤波、查表插值、PID控制甚至顺带算个能效COP的时候F413的浮点能力就体现出价值了。而且它的USART数量够多我一个主控接了好几片ADS122U04没有压力。2. 从探头到ADC引脚的硬件设计把噪声挡在进芯片之前2.1 比例测量的核心原理用一个公式吃掉恒流源温漂温度测量最容易踩的坑是直接用IDAC电流激励RTD然后把电压送进ADC再用代码里的“VI×R”算电阻。问题在于IDAC电流本身会随温度漂移哪怕漂移0.1%PT100在100℃时也能产生接近0.1℃的误差。正确做法是比例测量。核心思想让同一个电流源既流过被测RTD又流过一颗精密基准电阻RREF。然后把RREF两端电压当作ADC的参考电压把RTD两端电压当作输入信号。这样ADC输出码值近似等于RTD阻值 ≈ RREF × (码值 / 2^23)这个公式里根本没有电流I也就是说电流源漂移被彻底抵消了。这是整套方案最核心的一步如果硬件上没按这个思路搭后面软件再怎么写都白搭。实际接线时我把IDAC1输出先接到RREF再从RREF串联到RTD最后回到地。REFP和REFN引脚跨接在RREF上AINP和AINN引脚跨接在RTD两端。RREF选精密薄膜电阻温漂系数5ppm/℃起步精度0.1%以上。2.2 RTD的两种接法四线做基准三线干现场RTD接法分为两线、三线和四线。两线在这里就不多说了除非你的引线只有几厘米。工业HVAC现场我推荐三线或四线。四线是首选基准方案一对引线走IDAC激励电流另一对引线走电压检测测量回路几乎没有电流流过线阻的影响可以忽略。我在冷站主机上用的就是四线PT100稳定性和精度都很满意。三线是HVAC现场最常用的折中方案。三根线分别接在RTD两端和补偿端利用差分输入扣除一副引线的电压降。它的前提是两根线阻尽量相等所以现场布线时要求同一根电缆里的线径、长度一致。实测下来三线接法配合比例测量在50米电缆内把误差控制在0.1℃以内没有太大难度。激励电流的选择也要讲究。PT100我用1mA功耗约0.1mW基本不产生自热误差。PT1000我会降到250µA或500µA因为PT1000在几百欧到几千欧之间同样电流下发热更明显1mA能让它自热出0.1℃以上的偏差这是很多初做温度采集的人最容易忽略的细节。2.3 热电偶和NTC的处理冷端补偿与高增益通道如果只测RTD这套方案其实只用了一半功力。ADS122U04的PGA最大增益128就是给热电偶准备的。K型热电偶信号每摄氏度只有大约41µV100℃温差不过是4mV量级不开高增益直接没法用。我的配置是热电偶通道PGA设为128参考源用内部2.048V基准开启双极性测量。冷端补偿用ADC内部温度传感器或者更稳妥的办法是在冷端附近贴一颗外部PT1000两颗传感器读数做平均可以减少冷端温度梯度造成的误差。内部温度传感器精度大约在±0.5℃对大多数HVAC应用够用但如果你追求整机误差小于±0.3℃建议用外部PT1000做冷端参考。NTC热敏电阻接入就更简单了。NTC在25℃时通常是10kΩ阻值变化范围很大用IDAC 250µA激励配一个合适的分压网络直接进ADC。线性化靠软件查表硬件上不需要额外处理。2.4 电源、保护与PCB布局的细节这块我踩过不少坑直接说结论。第一模拟电源和数字电源分开。ADS122U04的AVDD和DVDD我分别用两颗LDO供电中间用磁珠隔离。如果板上空间紧张至少也要让AVDD经过RC滤波电容加大到10µF钽电容并100nF陶瓷电容。第二参考电压引脚必须加高质量旁路电容。REFP和REFN之间我放了C0G材质的100nF电容另外加了一颗1µF电容。C0G的温漂比X7R小参考电压的稳定性直接决定整机精度这钱不能省。第三模拟输入加RC滤波。每个AIN引脚串一个1kΩ电阻对地并联100nF电容做成低通滤波器。这样能挡住从传感器线缆上进来的高频干扰让Δ-Σ调制器工作在干净的信号上。RC截止频率大概1.6kHz对温度信号来说绰绰有余。第四RTD引线从设备出来就是一根长天线雷击感应和静电都可能从这根线进来。我在端子上加了双向TVS管入门后先过TVS再过共模电感最后才进RC滤波。别嫌冗余现场一年里总有一两次感应雷让你明白这几十毫钱的价值。第五PCB布局时ADC尽量靠近端子所有模拟走线都别跨过数字信号。串口TX、RX线在离开MCU后我会各串一个22Ω电阻再走这样既限制边沿速率也能减小振铃对ADC的干扰。模拟地单点汇接到电源地不要在ADC下方开数字地缝隙。3. STM32F413与ADS122U04的串口握手最容易栽在初始化顺序3.1 先搞清楚ADS122U04的UART帧格式ADS122U04的UART协议没有时钟线靠起始位、数据位和停止位保证同步。波特率不是软件任意配的芯片有专门的配置引脚根据M0/M1的电平组合选择固定波特率我板上用的是1152008N1。通信帧结构一般由起始字节、命令字段、寄存器地址、数据字段和可选CRC组成。写寄存器用WREG命令读寄存器用RREG命令读转换结果用RDATA命令。这里我不写具体十六进制码因为不同批次和手册版本的命令表最好以你手里那本为准。我的习惯是封装成两个驱动函数写寄存器和读寄存器函数内部按手册帧格式拼字节之后所有业务逻辑都建立在它们上面。我建议你把CRC选项打开。HVAC现场有变频器UART线上偶发一个错字节是常态如果没有CRC错字节会被当成合法命令执行后果是ADC配置被改乱温度读数直接跳飞。有CRC之后错误帧会被丢弃配合超时重发系统稳定很多。3.2 初始化顺序比想象中敏感ADS122U04上电之后不能立刻急着发配置命令。我遇到过一次程序复位后马上写寄存器结果寄存器根本没写进去读回来的全是默认值但单步调试的时候一切正常。后来用逻辑分析仪对比发现是芯片内部振荡器还没稳定UART模块没有进入就绪状态。正确的初始化顺序应该是RESET引脚拉低再拉高给芯片一个明确复位等待至少10ms让内部振荡器和参考源稳定如果芯片有唤醒/同步序列先按手册发送同步字节直到收到响应用WREG命令写入全部配置寄存器用RREG命令回读逐字节比对确认配置成功启动连续转换模式等待DRDY信号或读取超时。STM32侧的串口初始化和普通USART没有区别用CubeMX生成就行。我贴一段初始化参考void MX_USART6_UART_Init(void) { huart6.Instance USART6; huart6.Init.BaudRate 115200; huart6.Init.WordLength UART_WORDLENGTH_8B; huart6.Init.StopBits UART_STOPBITS_1; huart6.Init.Parity UART_PARITY_NONE; huart6.Init.Mode UART_MODE_TX_RX; huart6.Init.HwFlowCtl UART_HWCONTROL_NONE; if (HAL_UART_Init(huart6) ! HAL_OK) { Error_Handler(); } }初始化ADC的代码框架大概是这个样子具体命令码务必对照手册void ads122u_init(void) { /* 1. 复位引脚 */ HAL_GPIO_WritePin(RESET_GPIO_Port, RESET_Pin, GPIO_PIN_RESET); HAL_Delay(1); HAL_GPIO_WritePin(RESET_GPIO_Port, RESET_Pin, GPIO_PIN_SET); HAL_Delay(10); /* 2. 发送同步/唤醒序列直到收到响应 */ ads122u_sync(); /* 3. 写配置寄存器具体寄存器数与手册一致 */ ads122u_write_reg(REG_CONFIG0, CONFIG0_VALUE); ads122u_write_reg(REG_CONFIG1, CONFIG1_VALUE); ads122u_write_reg(REG_CONFIG2, CONFIG2_VALUE); ads122u_write_reg(REG_CONFIG3, CONFIG3_VALUE); /* 4. 回读校验 */ if (ads122u_read_reg(REG_CONFIG0) ! CONFIG0_VALUE) { /* 重新初始化或报警 */ } }这里有个小技巧配置写完之后把所有寄存器再读一遍比对不要省。现场偶发干扰会破坏UART帧如果没校验你调试一整天都找不到温度漂移的原因。3.3 读数、超时与异常重连ADS122U04在连续转换模式下每隔一个转换周期产生一个新数据。读取流程是MCU发RDATA命令然后从串口收3个字节拼成一个24位码值。注意两次读数之间要有间隔别一口气狂发命令否则读到的是同一个老数据会误以为ADC没工作。读取函数的参考写法uint32_t ads122u_read_adc(void) { uint8_t cmd ADS122U_CMD_RDATA; // 以手册命令码为准 uint8_t buf[3] {0}; uint32_t code 0; HAL_UART_Transmit(huart6, cmd, 1, 10); HAL_UART_Receive(huart6, buf, 3, 50); code ((uint32_t)buf[0] 16) | ((uint32_t)buf[1] 8) | ((uint32_t)buf[2]); return code; }超时处理也重要。我用HAL_UART_Receive的最后一个参数设了50ms超时如果读不到3个字节说明芯片可能进入了错误状态。遇到这种情况我的策略是连续错3次就重新走一遍完整初始化流程并发出错误告警。实测下来这个机制能让系统在无人干预的情况下自动恢复HVAC项目尤其需要这种自愈能力。4. 温度换算是精细活RTD查表、热电偶冷端补偿与三点校准4.1 RTD线性化查表插值比纯公式更适合工程从码值得到电阻之后下一个关键步骤是电阻到温度的换算。PT100和PT1000的电阻-温度特性不是纯粹线性工业上常用的数学模型是Callendar-Van Dusen方程但直接解这个方程非常麻烦。工程上最简单的做法是查表加线性插值。把EN 60751标准表按1℃步进存成数组温度分辨率靠插值补出来。1℃步长的表足够让插值误差控制在0.01℃以内完全满足HVAC需求。查表代码量小、执行快关键是调试时能直观看出数据落在哪个区间比玄学公式好排查得多。如果你想用公式也可以参考PT100的近似计算float pt100_res_to_temp(float R) { float t (R / 100.0f - 1.0f) / 0.00385055f; for (int i 0; i 3; i) { float err 100.0f * (1.0f 3.9083e-3f*t - 5.775e-7f*t*t) - R; float der 100.0f * (3.9083e-3f - 2.0f * 5.775e-7f * t); t - err / der; } return t; }这是我常用的牛顿迭代版三次迭代就能收敛。注意这个公式只在0℃以上精度比较好0℃以下要加上四次项我的经验是直接用分段查表更省心。4.2 热电偶冷端补偿的正确打开方式热电偶测的是热端和冷端的温差电动势所以冷端温度必须补偿否则读出来的温度全是错的。具体流程三步走读冷端温度T_cold。我这里是ADS122U04内部温度传感器读出来是摄氏温度根据热电偶分度表查出T_cold对应的热电动势E_cold把ADC读到的热电偶电压V_therm加上E_cold得到总电动势E_total用E_total反查分度表得到热端真实温度T_hot。举个例子K型热电偶冷端25℃此时测得热端输出3.075mV。如果直接按3.075mV反查表会得到大约75℃而实际热端是100℃。正确做法是查表得到25℃对应电动势约1.000mV加到3.075mV上得到4.075mV左右再反查表就能得到接近100℃的结果。这个加电动势的步骤千万别漏。我在软件里把K型、J型、T型热电偶的分度表都做成了常量数组配合PGA增益和参考电压反算成电压再进入补偿流程。整个模块化之后换传感器类型就只改一个通道配置。4.3 校准操作与误差分配再好的芯片也有偏移和增益误差。我的校准流程用冰水槽和干井炉分别做零点和满量程点把PT100探头放入冰水混合物等待温度稳定记录ADC换算后的读数T0把探头放入100℃干井炉等待稳定记录读数T100按线性修正公式算出增益系数和偏移量 T_actual (T_raw - offset) / gain把gain和offset写进MCU的Flash作为校准参数。我还会加一个第三点校验比如50℃恒温槽确认线性修正后中间点的误差是否在0.1℃以内。如果中间点偏差大通常不是校准问题而是探头本身不合格或者接触热阻太大需要检查安装方式。校准后我在实验室里用四线PT100做基准整机误差在-20℃到100℃范围内能做到±0.1℃以内这对HVAC领域而言已经非常宽裕了。5. 实验室和HVAC现场实测以及我踩过的三个坑5.1 实验室里的精度表现先放一组我在恒温槽里的实测数据探头是四线PT100配置PGA1、IDAC1mA、20SPS、32次移动平均恒温槽设定温度℃方案读数℃与设定差值℃00.020.023029.98-0.025050.040.047070.010.0110099.97-0.03这个结果在HVAC场景里算是相当稳的。不过要提醒一句实验室里干净、无干扰、恒温现场情况会复杂得多。5.2 现场干扰下的实测差异我把这套方案放到冷站项目的现场旁边就是变频器和冷冻水泵。对比原来的4-20mA模拟变送器方案最直观的感受是温度曲线从“毛刺”变成了“平线”。原方案在变频器满载运行时温度显示波动大约±0.6℃换成ADS122U04就地数字化之后一个小时的温度记录曲线标准差只有0.03℃左右肉眼几乎看不出波动。原因不复杂ADC直接放在传感器旁边模拟信号只有几厘米长的走线数字信号再通过长线传给主控中间就算有干扰也很难改数据大不了被CRC丢掉重传。另外ADS122U04这种Δ-Σ ADC的内部数字滤波器对工频及其倍频有一定抑制配合前端RC滤波和TVS现场电磁环境基本构不成威胁。5.3 三个坑一个比一个隐蔽先讲通信卡死的坑。现象是设备运行几天后温度读数变得很长一段时间不更新重启后又正常。排查链路是这样的先软件打LOG发现MCU发配置命令后ADC没有任何响应再量电压供电正常最后用逻辑分析仪抓TX/RX波形发现TX正常、RX完全静默。深入查下去是PCB上RESET引脚走线紧挨着一根外设电源线上电瞬间和外部干扰时被耦合拉低芯片反复复位。解决办法很简单RESET引脚加一个10kΩ上拉到VDD并且板子上把走线挪远一点。第二个坑是自热误差。现场有两根探头一只PT100一只PT1000贴在同一根管子上读数却差0.15℃。我一开始以为是探头标定问题后来把PT1000的激励电流从1mA改成250µA温差立即消失。原因就是PT1000在1mA下电阻功耗太大自热把探头局部温度抬高了。这种事在实验室里很难暴露因为探头悬空散热好一旦贴到管道或埋墙里自热效应就明显了。第三个坑是模拟输入引脚漏电。有一批次样板在高温高湿环境测试0℃点总是漂移到0.15℃以上而且数值慢慢爬。排查到最后是PCB清洗不彻底残留助焊剂在潮湿环境下在两条相邻走线之间形成了微弱的漏电路径相当于给ADC输入并联了一个可变电阻。解决方式是生产时加强清洗工序板子完成后涂三防漆尤其覆盖模拟输入区域。这问题在HVAC的潮湿机房特别容易重演别忽略。6. 直接能抄作业的寄存器配置与采集代码6.1 寄存器配置速查表下面这张表是我在PT100三线制场景下常用的配置建议具体寄存器地址和字段定义请打开对应手册对照但配置思路是通用的配置项建议值理由输入MUXAIN0/AIN1通道选择按布局定PGA增益1RTD/ 128热电偶RTD信号幅值足够热电偶需要放大IDAC1输出1mAPT100/ 250µAPT1000兼顾信噪比与自热限制IDAC2关闭或用于三线补偿视接线方式决定参考源外部RREF比例测量抵消电流温漂数据速率20SPS温度是慢信号速率低噪声小内部温度传感器开启热电偶冷端补偿使用CRC开启现场干扰下保证通信可靠三线PT100时我会用两个IDAC分别驱动RTD两端利用差分输入扣除引线电阻。这个配置在寄存器里对应IDAC1和IDAC2的分配现场按手册设一次就固定了。6.2 温度采集主循环代码主循环里做的事情很简单按固定间隔读ADC码值转电阻转温度做滤波然后送显示或上传。核心代码大概是这样uint32_t code ads122u_read_adc(); float ratio (float)code / 8388608.0f; // 除以2^23得到比例 float r_rtd ratio * R_REF; // R_REF是外部精密电阻 float temp pt100_res_to_temp(r_rtd); // 查表/公式换算温度 temp moving_average(temp); // 滑动平均滤波滤波我用的是16点滑动平均对温度和输出频率都合适。注意滑动平均的缓冲区是全局的别在中断里和主循环同时访问否则会出现抖动。如果你需要长时间稳定记录还可以做一阶低通滤波float filtered filtered alpha * (raw - filtered);alpha取0.2左右既跟得上温度变化又足够平滑。6.3 还能怎么扩展从RS-485到多点温度场这套架构最方便的地方在于天然适合分布式测温。一个STM32F413RH有多个UART接口每个UART接一片ADS122U04一个主控就能带几个采集节点。如果控制柜和传感器距离超过几十米把MCU这边的UART转成RS-485节点之间走Modbus协议现场布线和调试都极其舒服。F413的FPU在这里也派上了用场。我把多个通道的温度数据都做了线性化修正还顺手算了冷站当前COP能效比纯粹是CPU大材小用。如果以后想加PID控制、温度趋势预测甚至做个小型的FFT看压缩机振动信号这颗芯片的资源都还宽裕。同一个前端硬件我还做成了多传感器兼容模式通过检测接入电阻范围自动判断是PT100、PT1000还是NTC然后切换到对应的激励电流和查表逻辑。HVAC项目后期运维最怕传感器型号混用这个自动识别功能帮我省了不止一次现场返工。最后分享一个小细节也是我踩过几次坑之后养成的习惯RTD引线的屏蔽层我坚持在ADC这一侧单端接地另一端悬空。两侧都接地看起来更“稳妥”实际上会在屏蔽层里形成地环路电流反而把工频干扰引到模拟地上。单端接地之后长线传感器在变频器环境下才真正安静下来。如果你做温度采集时遇到莫名其妙的50Hz噪声先查一下屏蔽层接地方式。
📝

华诺云谱内容团队

资深建站顾问 · 行业研究员

10年+企业数字化服务经验,专注智能建站、SEO优化与品牌营销,持续输出建站技巧、行业洞察与营销干货,已帮助5000+企业实现数字化增长。

你可能需要的服务

订阅华诺云谱资讯周报

每周一封,精选建站技巧、SEO与营销干货,直达邮箱。已有 8,000+ 企业主订阅,助你少走弯路。

↑