首页 / 资讯中心 / 文章详情

基于PJ85718DM与STM32F411RE的双路温度监测方案

基于PJ85718DM与STM32F411RE的双路温度监测方案 ★ FEATURED ARTICLE
1. 项目缘起与整体设计思路嵌入式温度监测这个方向看起来简单实际上坑特别多。我最早接触这类需求是在一个HVAC控制柜的改造项目里当时的要求很朴素本地要能看到回风温度远程中控室也要能读到同一路数据而且两边的读数不能打架。最开始想用单颗数字温度芯片直接搞定结果发现本地显示和远程传输对采样频率、滤波策略、接口电平的要求完全不一样硬凑在一起要么本地跳数要么远程丢包。后来换了个思路把“感知”和“传输”拆开用一颗模拟输出的温度传感器配合STM32F411RE的ADC做本地采集再通过串口把数据推到远程节点整个系统就稳下来了。这个项目的核心就是围绕PJ85718DM和STM32F411RE搭一套双路温度监测方案。PJ85718DM是一颗模拟输出的温度传感器输出与温度成线性关系的电压信号测温范围覆盖了HVAC场景常见的-40到125摄氏度区间精度在常温段可以做到正负0.5摄氏度以内。STM32F411RE则是ST家F4系列里性价比很高的一颗Cortex-M4芯片主频100MHz带12位ADC多路USART和I2C做本地采集加远程转发绰绰有余。两者配合本地用OLED或者段码屏显示远程通过RS485或者无线模块把数据送出去一套代码同时管两路互不干扰。为什么选这个组合而不是直接上数字温度芯片这里有个很实际的考量。HVAC现场电磁环境复杂风机、压缩机、变频器全在附近数字芯片的I2C或者单总线在长线传输时容易被干扰一旦通信失败就是整颗芯片读不到数。模拟传感器输出的是电压信号STM32的ADC做多次采样取中值再配合简单的RC滤波抗干扰能力反而更强。而且模拟传感器的成本通常比数字芯片低批量做控制板的时候这个差价很可观。当然代价是占用一个ADC通道还要做校准但对于F411RE这种ADC资源富裕的芯片来说这点开销完全可以接受。整个系统的设计思路可以概括成三句话本地采集用ADC加软件滤波保证读数稳定远程传输用串口加协议帧保证数据可靠本地显示和远程上报共用同一份经过滤波的温度值保证两边一致。这个“共用同一份数据”的原则很关键我见过太多项目本地显示一个值、远程上报另一个值客户一看就懵了。实现上就是在主循环里先完成ADC采样和温度换算把结果存到一个全局变量里本地显示任务和远程发送任务都从这个变量取值从源头上杜绝了数据不一致。适合参考这套方案的人我觉得有三类。第一类是刚接触STM32和模拟传感器的新手想找一个完整的、能跑通的温度采集项目练手第二类是做HVAC、工控、环境监测的嵌入式工程师需要一套稳定可靠的本地加远程温度方案第三类是对模拟传感器校准和ADC滤波感兴趣的人这个项目里有很多可以深挖的细节。不管你是哪一类下面的内容都会从硬件连接到代码实现再到问题排查一步步讲清楚。2. 核心器件解析与硬件连接要点2.1 PJ85718DM的工作特性与选型理由PJ85718DM这颗传感器资料不算特别多但用下来感觉是一颗被低估的器件。它的输出是模拟电压典型接法是VCC接3.3V或者5VGND接地OUT引脚直接进STM32的ADC输入。输出电压和温度的关系是线性的常温下每摄氏度对应固定的毫伏变化具体斜率要看数据手册不同批次可能有细微差异所以校准这一步不能省。它的测温范围覆盖了HVAC应用里绝大多数场景从冷库的低温到出风口的较高温度都能测精度在常温段表现不错线性度也还可以不需要做复杂的非线性补偿。选它而不是选常见的数字温度芯片除了前面说的抗干扰和成本因素还有一个原因是它的响应速度。模拟输出的传感器没有通信握手和转换等待ADC采一次就是一次采样率可以做得很高。这对于需要快速捕捉温度变化的场景很有用比如监测换热器出口温度的时候温度变化很快数字芯片的转换周期可能跟不上模拟传感器配合高速ADC就能抓住这些瞬态变化。当然高采样率也意味着数据量大需要配合滤波算法这个后面会详细讲。有一点要特别注意PJ85718DM的输出阻抗和STM32的ADC输入阻抗要匹配。如果传感器输出阻抗偏高而ADC采样时间设置得太短采样电容充不满读数就会偏低。我一般会把ADC的采样时间设到最长的那个档位比如239.5个ADC周期给采样电容足够的充电时间。这个设置看起来不起眼但实际调试的时候采样时间不够导致的读数偏差能有好几度很多人会误以为是传感器坏了。2.2 STM32F411RE的ADC与串口资源配置STM32F411RE的ADC是12位的参考电压通常用VDDA也就是3.3V。12位意味着满量程4096个刻度3.3V分下来每个刻度大约0.8毫伏。PJ85718DM的输出斜率如果是每摄氏度10毫伏左右那温度分辨率就是0.08摄氏度完全够用。实际用的时候我不会只看单次采样而是做多次采样取平均或者取中值这样有效分辨率还能再提高一点。ADC的时钟配置也要注意F411RE的ADC时钟来自APB2最高不能超过36MHz分频系数要算好超频了读数会飘。串口方面F411RE有好几路USART我一般用USART2做远程通信因为它的引脚和调试用的USART1不冲突方便同时接调试器和通信模块。波特率根据传输距离和线材质量来定短距离用115200没问题长距离或者干扰大的场合降到9600更稳。数据格式用8位数据位、无校验、1位停止位这是最通用的配置。如果远程节点也是STM32可以开硬件流控但大多数情况下软件协议里加个帧头帧尾和校验就够了。本地显示我通常用I2C接口的OLED0.96寸或者1.3寸的都行驱动简单占用引脚少。I2C的时钟频率设400kHz刷新率足够。如果现场温度低OLED响应会变慢这时候可以降到100kHz。显示内容不用太花哨温度值、单位、状态指示就够了。有人喜欢加曲线图但小屏上曲线图反而看不清具体数值不如直接显示数字来得实在。2.3 硬件连接与抗干扰布局接线这块模拟部分和数字部分要分开走。PJ85718DM的输出线尽量短如果传感器离板子远用屏蔽线屏蔽层单端接地。ADC输入端加一个0.1微法的电容到地滤掉高频噪声再并一个10微法的电容稳住低频。这两个电容的位置要尽量靠近ADC引脚远了效果打折扣。电源方面传感器的供电和STM32的模拟供电最好来自同一个LDO避免不同电源之间的地电位差影响读数。地线处理是个容易被忽视的点。模拟地和数字地在板子上要分开铺最后在ADC下方或者电源入口处单点连接。如果混在一起铺数字部分的开关噪声会串到模拟地上ADC读数就会跳。我吃过这个亏当时读数一直在正负两度之间跳查了半天才发现是地线没处理好。后来改成单点接地跳变立刻降到正负0.2度以内。这个经验值得记下来硬件布局上多花十分钟软件调试能省一整天。RS485或者无线模块的接线也要注意。如果用RS485A和B线要双绞终端加120欧姆匹配电阻。如果用无线模块天线周围要净空别铺铜也别走线。通信线和模拟线不要平行走交叉的话尽量垂直交叉。这些规则听起来老生常谈但现场出问题的时候十有八九就是这些细节没做到位。3. 温度采集与滤波算法的实现细节3.1 ADC采样配置与温度换算ADC的初始化代码用CubeMX生成比较省事但有几个参数要手动改。首先是把连续转换模式打开或者用定时器触发单次转换我倾向于用定时器触发采样周期固定方便做周期性的滤波。触发频率设成100Hz左右也就是每10毫秒采一次这个速率对温度这种慢变量来说绰绰有余还能留出足够的CPU时间做其他事。DMA要开起来让ADC数据自动搬到内存数组里不占用CPU。DMA的缓冲区设成16或者32个元素的数组存满一半触发中断在中断里做数据处理。温度换算的公式很简单就是线性方程。先读出ADC的原始值转换成电压再根据传感器的斜率换算成温度。这里有个细节ADC的参考电压不一定是精确的3.3VLDO的输出可能有偏差所以最好用万用表量一下实际的VDDA把实测值代入公式。我一般会在代码里留一个宏定义方便不同板子调整。换算的时候用浮点数还是定点数F411RE有FPU浮点运算很快直接用float就行代码可读性好精度也够。如果对速度有极致要求可以用定点数但温度采集对速度不敏感没必要折腾。校准是绕不开的一步。我的做法是准备两个温度点一个冰水混合物接近0度一个温水接近40度把传感器放进去等读数稳定后记录ADC原始值算出实际的斜率和偏移。这两个点不用太精确因为传感器本身的精度就那样校准主要是消除电路上的系统误差。校准系数存在Flash里上电的时候读出来用。如果批量生产可以每块板子单独校准也可以抽测几块取平均看成本要求。3.2 中值滤波与滑动平均的组合策略滤波这块我试过很多种方案最后稳定下来的组合是中值滤波加滑动平均。中值滤波负责干掉脉冲噪声比如附近继电器吸合瞬间产生的尖峰滑动平均负责平滑随机噪声让读数看起来稳定。具体做法是DMA缓冲区存满32个ADC值后先对这32个值排序取中间的几个求平均作为一次有效采样然后再把连续8次有效采样做滑动平均得到最终的温度值。这样两级滤波下来读数非常稳响应速度也还能接受温度突变的时候大概一两秒就能跟上。排序算法用简单的冒泡或者插入排序就行32个元素的数据量很小F411RE跑起来毫无压力。滑动平均的窗口大小可以调窗口越大越稳但响应越慢窗口越小响应快但可能还有轻微跳动。我一般用8实测下来在稳定性和响应速度之间平衡得比较好。如果现场干扰特别大可以把窗口加到16代价是温度变化时读数跟上得慢一些。这个参数没有标准答案要根据实际场景调。有个坑要提醒一下滑动平均的初始值处理不好会导致上电后读数慢慢爬升。我的做法是上电后先连续采满整个窗口的数据再开始输出或者把窗口内所有元素的初始值设成第一次采样的值。前者更准确后者更快出数。如果对启动时间没要求用前者。如果要求上电立刻显示用后者但前几秒的读数可能不太准可以在显示上做个标记等稳定后再去掉。3.3 本地显示与远程上报的数据一致性前面提过本地显示和远程上报必须用同一份数据。实现上就是在主循环里维护一个全局的温度变量ADC处理完更新这个变量显示任务和发送任务都读这个变量。显示任务可以每200毫秒刷新一次发送任务每1秒发一次两者互不干扰。这里要注意变量的读写保护如果显示和发送在不同中断里要用临界区或者原子操作。我一般把ADC处理放在主循环里显示和发送也用主循环的定时器调度不用中断这样就避免了竞争问题。远程上报的数据帧格式我习惯用这样的结构帧头两个字节比如0xAA和0x55然后是温度值的整数部分和小数部分各一个字节接着是校验和最后是帧尾。校验和用前面所有字节的累加和取低八位简单有效。接收端收到帧后先找帧头再验校验和都通过了才解析数据。这种格式虽然简单但可靠性足够而且调试的时候用串口助手一看就明白。如果传输距离远可以加个序号字节接收端发现序号不连续就知道丢包了。本地显示的内容我一般包括当前温度、单位符号、以及一个通信状态指示。通信状态可以用一个小图标或者文字表示比如“OK”或者“ERR”。如果远程发送失败本地显示上能看出来方便现场排查。这个细节很多项目不做出了问题只能靠猜加上之后维护效率高很多。4. 远程通信协议与数据可靠性保障4.1 串口通信的帧设计与校验机制远程通信的可靠性一半靠硬件一半靠协议。硬件上前面说了双绞线、匹配电阻、屏蔽层这些做到位能解决大部分问题。协议上帧结构的设计要能应对丢包、误码、粘包这三种常见情况。丢包靠序号检测误码靠校验和粘包靠帧头和帧长。我的帧结构里帧头是固定的两个字节接收端状态机在空闲状态一直找帧头找到后进入接收状态按固定长度收完一帧再验校验和。这样即使中间有干扰导致帧头错位状态机也能在下一帧重新同步。校验和用累加和还是CRC累加和实现简单对随机误码的检出率一般但对突发误码还行。CRC8或者CRC16检出率更高但计算稍微复杂一点。F411RE有硬件CRC单元用起来很方便如果对可靠性要求高建议上CRC16。我一般用CRC8因为温度数据帧很短CRC8够用了而且软件实现也就几行代码。如果传输环境特别恶劣比如变频器旁边那就上CRC16别省这点计算量。帧长度我设计成固定的这样接收端状态机简单不用处理变长帧。温度值用两个字节表示一个字节整数一个字节小数范围覆盖-128到127度小数精度0.1度对HVAC场景足够了。如果要做高精度可以用四个字节表示浮点数但帧就长了传输效率降低。权衡下来两个字节的定点表示最合适。4.2 通信超时与重连策略远程通信不可能永远不出问题线断了、模块死机了、电源波动了都可能让通信中断。所以超时和重连机制必须有。我的做法是发送端每发一帧就启动一个超时计时器如果在一定时间内没收到接收端的应答就重发重发三次还没应答就标记通信故障本地显示上给出提示然后隔一段时间再尝试重连。接收端如果超过一定时间没收到有效帧也标记通信故障并且可以触发一个报警输出比如点亮一个LED或者拉低一个继电器。超时时间设多少这取决于波特率和传输距离。115200波特率下一帧十几个字节传输时间不到2毫秒加上接收端处理时间超时设50毫秒很充裕。9600波特率下一帧要十几毫秒超时设200毫秒比较稳妥。重连间隔我一般设5秒太短了频繁重连浪费资源太长了故障恢复慢。这个参数可以根据实际需求调。有个细节要注意重连的时候不要直接把通信故障标志清掉要等连续收到几帧有效数据再清。否则偶尔一帧通了又断标志位来回跳显示上看着很乱。我一般要求连续收到3帧有效数据才认为通信恢复正常。这个“连续3帧”的阈值也可以调看你对误判的容忍度。4.3 多节点场景下的地址分配如果远程不止一个节点就需要地址机制。每个节点有一个唯一的地址发送帧里带上目标地址接收端只处理发给自己的帧。地址可以用拨码开关设置也可以用软件配置存在Flash里。拨码开关直观现场改地址不用重新烧程序但占引脚。软件配置省引脚但改地址要连电脑。我一般用拨码开关4位拨码可以设16个地址对大多数HVAC场景够用了。多节点的时候还要考虑总线冲突。如果多个节点同时发送总线上的数据就乱了。解决办法有两种一种是主从模式主机轮询从机只应答不主动发另一种是令牌环拿到令牌的节点才能发。主从模式简单可靠我一般用这种。主机依次给每个从机发查询帧从机收到后把温度数据回给主机。这样总线上任何时候只有一个节点在发不会冲突。代价是轮询周期随节点数增加而变长如果节点很多可以分组轮询或者提高波特率。地址分配的时候留一个广播地址比如0xFF主机可以用广播地址发一些公共命令比如校准、复位。从机收到广播帧不回复只执行命令。这样批量操作的时候很方便不用一个个节点去设。5. 常见问题排查与实操避坑经验5.1 温度读数跳变与漂移的排查思路读数跳变是最常见的问题原因可能有很多。第一步先看跳变的幅度和频率。如果是大幅度、低频跳变比如每隔几秒跳一次多半是电源或者地线的问题用示波器看ADC输入引脚和VDDA有没有周期性的纹波。如果是小幅度、高频跳变比如读数一直在正负0.5度之间快速抖动那是噪声加强滤波或者加RC电路。如果是缓慢漂移比如开机后读数慢慢往一个方向偏那是温漂或者校准问题检查传感器的供电是否稳定校准系数是否准确。我遇到过一次很典型的跳变读数每隔10秒左右跳一下幅度大概2度。查了半天发现是附近有个继电器每隔10秒吸合一次吸合瞬间的电磁干扰串到了ADC输入上。解决办法是在传感器输出和ADC之间加了一个RC低通滤波截止频率设到10Hz左右跳变就没了。这个案例说明排查跳变的时候一定要结合现场的时序看看跳变和什么事件同步。还有一个容易忽视的点是ADC的参考电压。如果VDDA不稳定所有ADC读数都会跟着变。用万用表量VDDA可能看不出来因为万用表响应慢要用示波器看交流纹波。如果纹波大在VDDA和地之间并一个10微法加0.1微法的电容通常能改善。5.2 远程通信丢包与误码的定位方法远程通信出问题先分清楚是丢包还是误码。丢包是帧根本没收到误码是收到了但校验不过。丢包通常是硬件问题线断了、接触不良、匹配电阻没接、波特率不匹配。误码通常是干扰问题线太长、没屏蔽、附近有干扰源。定位的时候先在发送端用示波器或者逻辑分析仪看波形确认信号质量。如果波形畸变严重那就是硬件问题。如果波形很好但接收端还是收不到那可能是接收端配置问题比如波特率、数据位、停止位对不上。我习惯在协议里加一个错误计数器接收端每收到一个校验失败的帧就计数加一发送端定期读取这个计数器。如果误码率突然升高说明现场出现了新的干扰源可以及时排查。这个计数器在调试阶段特别有用能帮你快速判断问题是持续性的还是偶发的。还有一个坑是串口的地线。如果两个节点分别供电地线之间可能有电位差这个电位差会叠加在信号上导致误码。解决办法是用隔离型RS485模块或者把两个节点的地线连起来。但地线连起来可能引入地环路反而更糟。所以长距离通信我一般直接用隔离模块省心。5.3 常见问题速查表现象可能原因排查方法解决措施读数大幅度周期跳变附近大功率设备干扰示波器看ADC输入和电源纹波加RC滤波改善屏蔽和接地读数小幅高频抖动随机噪声观察抖动幅度和频率加强软件滤波加去耦电容读数缓慢漂移温漂或校准不准恒温环境下长时间观察重新校准检查供电稳定性远程通信完全不通接线错误或波特率不匹配检查线序和串口配置纠正接线统一波特率远程通信偶发误码干扰或地电位差看误码计数器测地线电位差加屏蔽用隔离模块上电后读数爬升滑动平均初始值问题观察上电后前几秒的读数预填充窗口或延迟输出多节点通信冲突多个节点同时发送抓总线波形看冲突改主从轮询模式低温下显示异常OLED响应变慢降低I2C时钟频率降到100kHz或更低这张表是我自己调试过程中慢慢攒出来的基本上覆盖了八成以上的常见问题。遇到问题先查表能省不少时间。当然现场情况千变万化表里没有的就要靠逻辑分析一步步排查了。5.4 几个容易被忽视的实操细节第一个细节是ADC的采样时间。前面提过采样时间不够会导致读数偏低。具体设多少要看传感器的输出阻抗和ADC的采样电容。F411RE的ADC采样电容大概是几皮法如果传感器输出阻抗是几十千欧那时间常数就是几百纳秒采样时间至少要设到几个微秒才够。我一般直接设到最长的239.5个周期反正温度采集不差这点时间。第二个细节是串口发送的阻塞问题。如果用HAL库的阻塞发送函数发送一帧的时间CPU什么都干不了。115200波特率下发十几个字节大概1毫秒多影响不大但如果波特率低或者帧长就会影响其他任务。解决办法是用DMA发送或者中断发送把CPU解放出来。我一般用DMA发送配置好之后CPU只管往缓冲区写数据发送由DMA完成。第三个细节是Flash的擦写寿命。校准系数存在Flash里如果频繁写Flash会坏。所以校准系数只在校准的时候写一次平时只读不写。如果运行过程中需要保存一些参数比如通信地址可以用EEPROM或者带电池的RAM别老写Flash。第四个细节是看门狗。嵌入式设备在恶劣环境下可能死机看门狗是最后一道防线。F411RE有独立看门狗和窗口看门狗我一般用独立看门狗在主循环里定期喂狗。喂狗周期要算好太短了正常运行时也会复位太长了死机后恢复慢。我一般设1秒左右的超时主循环里每100毫秒喂一次留足余量。6. 系统联调与现场部署的实战记录6.1 实验室联调的标准流程实验室联调我一般分四步走。第一步只调ADC不接传感器用一个可调电压源模拟传感器输出看ADC读数是否线性、是否稳定。这一步能排除ADC配置和硬件连接的问题。第二步接上传感器在室温下看读数是否合理然后用手捏住传感器看读数是否上升用酒精棉擦拭看是否下降确认传感器工作正常。第三步调本地显示确认显示值和ADC换算值一致。第四步调远程通信用两个板子对发确认数据帧能正确收发。每一步都要记录数据特别是第一步的线性度测试我会取十几个电压点记录ADC读数和理论值的偏差画个曲线看看。如果偏差在正负1个LSB以内说明ADC没问题。如果偏差大检查参考电压和采样时间。这个记录在后期排查问题的时候很有用能快速判断是硬件问题还是软件问题。联调的时候我习惯在代码里加一个调试模式通过串口输出原始的ADC值、滤波后的值、换算后的温度值、以及通信状态。调试模式下数据刷得快方便观察。正式部署的时候把调试输出关掉减少串口占用。这个开关用一个宏定义控制编译时决定不占运行资源。6.2 现场安装的注意事项现场安装和实验室完全是两回事。实验室里温度恒定、电源干净、没有干扰现场什么都有。安装位置的选择很关键传感器要放在能代表被测区域温度的地方避开热源、冷源、阳光直射和气流死角。比如测回风温度传感器要放在回风管道中间不能贴着管壁。测室外温度要放在百叶箱里避免阳光直射和雨水。线缆的敷设也要注意。模拟信号线和通信线要分开走不能捆在一起。如果必须交叉垂直交叉。线缆要固定好避免振动导致接触不良。接头处要处理好防水防尘。我见过一个现场传感器接头没做好防水下雨天进水读数直接跳到满量程。后来重新做了防水接头问题解决。电源方面现场如果有大功率设备建议给控制板单独一路电源或者加个隔离电源模块。共模干扰大的场合模拟部分和数字部分用隔离电源分开供电通信也用隔离模块。这样成本高一些但稳定性提升明显。如果预算有限至少在电源入口加个TVS管和共模电感能挡掉大部分浪涌。6.3 长期运行的数据观察与维护建议设备装上去只是开始长期运行的稳定性才是考验。我一般会建议客户定期记录温度数据比如每天同一时间记录一次观察有没有异常漂移。如果发现某个节点的读数和其他节点偏差越来越大可能是传感器老化或者校准漂移需要重新校准。校准周期一般一年一次环境恶劣的话半年一次。通信方面定期检查误码计数器和重连次数。如果误码率逐渐升高可能是线缆老化或者接头氧化需要检查线路。如果重连次数突然增多可能是附近新增了干扰源需要排查。这些数据如果能在远程中控室里看到维护效率会高很多。所以我在协议里除了温度数据还会把通信状态、误码计数、重连次数这些诊断信息一起上报。固件升级也是个要考虑的问题。现场设备装上去之后如果发现bug或者要加功能不可能每次都派人去现场烧程序。所以最好预留远程升级通道通过串口或者无线模块把新固件传过去。F411RE的Flash够大可以做双区备份升级失败还能回滚。这个功能前期做进去后期省大事。7. 方案扩展与个人实操体会这套方案的基础版就是本地采集加远程上报但实际项目中往往需要更多功能。比如加个继电器输出温度超限的时候触发报警或者启动风机。F411RE的GPIO足够多加继电器驱动电路很简单。再比如加个历史数据存储用SPI Flash或者SD卡把温度数据存下来方便事后分析。这些扩展都不难核心的采集和通信框架不用动往上加就行。如果要多路温度监测PJ85718DM可以接多颗分别进不同的ADC通道。F411RE的ADC有多路输入配合DMA可以轮流采样。多路的时候要注意通道切换后的稳定时间切换后第一次采样丢弃从第二次开始取。这个细节不注意的话通道之间的读数会互相影响。我个人在实际操作中的体会是嵌入式温度监测这个方向硬件和软件各占一半。硬件上把电源、地线、滤波做好软件上把采样、滤波、通信协议做好基本就稳了。最怕的是硬件凑合、软件补锅最后补不过来。所以如果让我重新做一遍我会在硬件布局上花更多时间把干扰源和敏感线路隔离开这样软件能简单很多。最后分享一个小技巧调试ADC的时候如果怀疑读数不准可以先短接ADC输入到地看读数是不是接近0再短接到VDDA看读数是不是接近满量程。这两个测试能快速判断ADC本身有没有问题。如果短接到地读数不是0检查参考电压和地线。如果短接到VDDA读数不是满量程检查参考电压和采样时间。这个测试简单但很有效我每次调新板子都会先做这一步。
阅读完成 · 觉得有帮助?
咨询建站