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

基于PJ85718DM与PIC18F56K42的嵌入式温度监测系统设计与实现

基于PJ85718DM与PIC18F56K42的嵌入式温度监测系统设计与实现 ★ FEATURED ARTICLE
1. 项目缘起与整体设计思路嵌入式温度监测这件事说起来简单做起来全是细节。我最早接触这类需求是在一个环境控制类项目里当时的要求很朴素本地要能看到实时温度远程也要能拿到数据而且整套东西得稳定跑在工业现场那种电磁环境复杂、供电质量一般的场景下。后来陆续做了几个类似的项目方案换过好几轮从最开始的纯模拟传感器加运放到后来的数字传感器加无线模块再到最近这套基于 PJ85718DM 和 PIC18F56K42 的组合算是把本地与远程温度监测这个需求吃透了不少。先说说标题里这两个核心器件。PJ85718DM 是一颗红外温度传感器信号调理芯片配合热电堆传感器使用负责把微弱的模拟信号放大、滤波、数字化最终通过 I2C 接口输出温度数据。PIC18F56K42 则是 Microchip 旗下 PIC18 系列的一款 8 位单片机带 12 位 ADC、多路 UART、I2C、SPI还有充足的外设资源特别适合做这种传感器采集加通信转发的活儿。两者搭配一个管本地高精度非接触测温一个管数据处理和远程通信调度分工明确。为什么选这个组合而不是更简单的方案我试过直接用带数字接口的温度传感器比如某些 I2C 输出的型号省事是省事但测温范围窄、响应慢遇到需要非接触测量的场景就抓瞎。也试过用模拟热电堆加运放加外部 ADC 的方案精度能调但电路复杂、温漂难控批量生产时一致性很差。PJ85718DM 把调理电路集成进去出厂就校准好了省了我大量调试时间。PIC18F56K42 选它是因为外设够用、价格合适、开发工具链成熟而且 5V 供电在工业现场抗干扰能力比 3.3V 系统强不少。整套系统的设计思路是这样的PJ85718DM 负责采集本地目标温度通过 I2C 把数据传给 PIC18F56K42单片机做两件事一是驱动本地显示比如段码屏或小尺寸字符屏二是通过 UART 接无线透传模块或者 RS485 收发器把温度数据打包发到远程监控端。远程端可以是一个上位机软件也可以是一个云平台看具体项目需求。整个链路的关键在于数据采集的稳定性、通信协议的可靠性以及现场安装时的抗干扰处理。这个方案适合谁参考我觉得三类人可以看看一是做 HVAC 控制器的嵌入式工程师需要集成温度采集功能二是做工业设备状态监测的开发者想加一路非接触测温三是电子爱好者或者学生想学 I2C 传感器和 UART 通信的实际用法。不管你是哪类下面的内容都会从选型理由、电路细节、代码实现到调试经验一步步拆开讲。2. 核心器件解析与选型考量2.1 PJ85718DM 到底解决了什么问题热电堆传感器输出的信号非常微弱通常在几十微伏到几百微伏每摄氏度而且输出阻抗高容易受干扰。如果直接用单片机的 ADC 去采基本采不到有效信号噪声就把有用信号淹没了。PJ85718DM 内部集成了低噪声斩波放大器、16 位 ADC、DSP 校准引擎还有温度补偿算法。它把热电堆的冷端温度也一并测量然后通过内部算法算出目标温度直接输出数字量。我实测下来这颗芯片在 0 到 300 摄氏度范围内精度能到正负 1 摄氏度以内分辨率 0.02 摄氏度刷新率可以配置最快大概 10Hz 左右。对于 HVAC 场景比如风管温度监测、房间人员存在检测、设备表面温度监控这个性能完全够用。它的 I2C 地址可以通过引脚配置方便一条总线上挂多个传感器做多点测温。注意PJ85718DM 需要配合热电堆传感器使用不是单独一颗就能测温的。选型时要确认热电堆的视场角、滤波窗口波长范围跟你的应用匹配。比如测人体温度用 5.5 微米到 14 微米波段的测高温物体用窄带滤光的。2.2 PIC18F56K42 的外设资源分配PIC18F56K42 的引脚数有 28、40、48 几种封装我常用 40 脚的 PDIP 或者 TQFP手工焊接和调试都方便。它有三个关键外设在这个项目里必须用上MSSP 模块配置成 I2C 主机用来读 PJ85718DMEUSART 模块配置成异步串口接无线模块或 485 芯片还有一个定时器做系统时基负责周期触发采集和通信超时管理。时钟方面我用的是内部 64MHz 振荡器省了外部晶振但串口波特率要求准的话建议还是外接一个 16MHz 晶振分频后给系统时钟波特率误差小。PIC18F56K42 的 I2C 支持标准模式 100kHz 和快速模式 400kHzPJ85718DM 最高支持 400kHz我一般跑 100kHz线长一点也稳。内存方面这颗片子有 4KB RAM 和 128KB Flash跑裸机程序绰绰有余。我习惯把温度数据做环形缓冲存最近 64 个采样点方便做滑动平均滤波。EEPROM 用来存校准参数和通信地址掉电不丢。2.3 本地与远程的职责划分本地部分的核心任务是实时显示和超限报警。显示我一般用 4 位段码 LCD 或者 0.96 寸 OLED前者便宜省电后者信息量大。报警用蜂鸣器加 LED阈值可以通过按键设置存在 EEPROM 里。远程部分的核心任务是数据上报和远程配置。上报周期可以设比如 1 秒一次或者 10 秒一次看网络条件。远程端可以下发指令修改报警阈值、校准偏移量、上报周期这些参数。这种本地加远程的架构好处是即使网络断了本地依然能正常工作不会因为远程服务器挂了导致现场失控。HVAC 应用里这点很重要冬天管道冻裂或者夏天机房过热本地必须能独立报警。3. 硬件电路设计与关键参数计算3.1 PJ85718DM 的外围电路PJ85718DM 的外围电路不复杂但有几个地方容易出错。电源引脚必须加 100nF 和 10uF 电容靠近芯片放置。I2C 总线的上拉电阻我一般用 4.7k 欧姆如果总线电容大或者线长超过 30cm降到 2.2k 欧姆。热电堆传感器的输出直接接到 PJ85718DM 的差分输入引脚中间不要加任何滤波电容否则会影响响应速度。芯片的 VDD 我用的 3.3V跟 PIC18F56K42 的 5V 系统之间加了一个电平转换芯片I2C 总线上用 MOS 管做双向电平转换成本低效果好。实操心得PJ85718DM 的底部散热焊盘一定要焊到地平面而且周围铺铜要足够大。我早期有一版板子没注意这个芯片自身发热导致冷端温度测量偏高测温结果整体偏了 2 到 3 摄氏度。后来加了散热过孔和铺铜问题解决。3.2 PIC18F56K42 的最小系统单片机最小系统包括电源、复位、时钟、调试接口。电源我用 5V 输入加 TVS 管防浪涌再加 LC 滤波。复位电路用 10k 上拉加 100nF 电容简单可靠。调试接口是 ICSP5 根线用 PICKit 系列工具就能烧录和在线调试。串口我留了两路一路接无线透传模块一路接 RS485 收发器通过跳线选择。RS485 那边加 120 欧姆终端电阻用跳线或者拨码开关控制接入。3.3 通信接口的电气参数无线透传模块我常用 3.3V 供电的跟单片机 5V 串口之间需要电平转换。最简单的方法是用电阻分压但波特率高的时候波形会变差我推荐用专用的电平转换芯片或者 MOS 管方案。RS485 收发器用 5V 供电的型号比如常见的半双工芯片A/B 线加 TVS 管和共模电感防止现场浪涌打坏芯片。波特率我一般设 9600 或者 19200工业现场干扰大低波特率更稳。参数取值说明I2C 上拉电阻4.7k 欧姆短距离总线电容小I2C 速率100kHz稳定性优先串口波特率9600bps工业现场抗干扰采集周期200ms兼顾响应和滤波上报周期5s可远程配置报警阈值默认上限 60 度下限 5 度存 EEPROM4. 固件实现与核心代码解析4.1 I2C 读取 PJ85718DM 的时序要点PJ85718DM 的 I2C 协议是标准的寄存器读写。上电后先等 10ms 让芯片内部稳定然后写配置寄存器设置采集速率和滤波强度接着发启动转换命令等转换完成标志置位后读温度数据。温度数据是两个字节高字节在前低字节在后组合成 16 位有符号数乘以 0.02 得到摄氏度值。// I2C 读取 PJ85718DM 温度示例 uint8_t buf[2]; i2c_start(); i2c_write(PJ85718DM_ADDR 1); // 写地址 i2c_write(REG_TEMP_H); // 温度高字节寄存器 i2c_restart(); i2c_write((PJ85718DM_ADDR 1) | 1); // 读地址 buf[0] i2c_read_ack(); buf[1] i2c_read_nack(); i2c_stop(); int16_t raw (buf[0] 8) | buf[1]; float temp raw * 0.02f;这段代码里i2c_restart很关键不能省。有些传感器支持直接读但 PJ85718DM 必须重启总线再发读地址。另外读第二个字节时要发 NACK然后发停止条件否则总线会卡住。4.2 滑动平均滤波与异常值剔除原始温度数据会有波动特别是现场有气流或者热源移动的时候。我一般做两级处理先剔除异常值再做滑动平均。异常值判断用中值滤波取最近 5 个采样点的中位数如果当前值跟中位数偏差超过 5 摄氏度就丢弃。滑动平均窗口取 8 个点这样响应速度还能接受数据也平滑。#define FILTER_WINDOW 8 float temp_buf[FILTER_WINDOW]; uint8_t buf_idx 0; float filter_temp(float new_temp) { // 中值剔除 float sorted[5]; // ... 取最近5个点排序取中值 ... if (fabs(new_temp - median) 5.0f) { return last_valid_temp; // 丢弃异常值 } temp_buf[buf_idx] new_temp; buf_idx (buf_idx 1) % FILTER_WINDOW; float sum 0; for (int i 0; i FILTER_WINDOW; i) { sum temp_buf[i]; } return sum / FILTER_WINDOW; }注意滑动平均窗口不是越大越好。窗口大了数据平滑但响应慢HVAC 控制里如果温度变化快滞后太大会导致控制振荡。我一般根据被控对象的惯性来调风管温度用 8 到 16 个点房间温度用 4 到 8 个点。4.3 串口通信协议设计远程通信协议我设计得很简单帧头两个字节 0xAA 0x55然后跟设备地址、命令字、数据长度、数据区、校验和。校验和用累加和取低八位简单够用。设备地址用来区分同一总线上多个节点。命令字包括上报温度、设置阈值、读取阈值、校准偏移、重启设备这些。// 打包上报帧 void pack_report_frame(uint8_t *buf, uint8_t addr, float temp) { buf[0] 0xAA; buf[1] 0x55; buf[2] addr; buf[3] CMD_REPORT_TEMP; buf[4] 4; // 数据长度 int16_t temp_raw (int16_t)(temp / 0.02f); buf[5] (temp_raw 8) 0xFF; buf[6] temp_raw 0xFF; buf[7] 0; for (int i 0; i 8; i) { buf[7] buf[i]; } }接收端解析的时候先找帧头再读长度然后收完整帧算校验和对了才处理。如果校验错就丢弃等下一帧。这种协议虽然简单但现场跑下来很稳比那些带转义、带重传的复杂协议省事得多。4.4 本地显示与按键处理本地显示我用的是 4 位段码 LCD驱动芯片用 HT1621 或者类似的通过 SPI 或者普通 IO 模拟时序。显示内容就是当前温度值单位摄氏度超限的时候闪烁。按键三个设置、加、减。短按设置键进入阈值设置模式加减键调数值再按设置键保存并退出。长按设置键 3 秒恢复默认阈值。按键处理用状态机在主循环里每 10ms 扫描一次做 20ms 消抖。长按检测用计数器超过 300 次扫描就算长按。这个逻辑简单但有效我用了很多年没出过问题。5. 远程通信与数据上报实现5.1 无线透传模块的配置要点无线透传模块我一般选支持透明传输的配置好波特率、信道、空中速率就行。空中速率不要设太高250kbps 比 2Mbps 稳距离也远。模块的供电要干净加 LC 滤波否则发射瞬间电流突变会拉低电压导致单片机复位。我遇到过这个问题后来在模块电源脚并了一个 470uF 电解电容加 100nF 陶瓷电容问题消失。模块的串口跟单片机之间如果模块是 3.3V 的单片机是 5V 的TX 线用电阻分压RX 线直接连或者加电平转换。分压电阻用 1k 和 2k分压后 3.3V 左右模块能识别。波特率设 9600跟模块配置一致。5.2 上报周期与心跳机制上报周期我设成可配置的默认 5 秒。远程端可以下发指令改成 1 秒到 60 秒之间的任意值。除了周期上报还加了一个心跳机制如果 30 秒内没有收到远程端的任何指令设备会主动发一个心跳帧确认链路还通。如果连续 3 次心跳都没回应设备进入本地独立运行模式不再等待远程指令但继续上报直到收到回应。这个机制在实际项目里很有用。有次现场网络故障远程端挂了但设备还在正常采集和本地报警没有因为远程失联导致整个系统瘫痪。5.3 数据存储与断网续传PIC18F56K42 的 EEPROM 有 1KB我划出 512 字节做断网续传缓存。每条记录 8 字节存时间戳和温度值能存 64 条。网络正常时上报成功后清空缓存。网络断开时采集数据先写缓存等网络恢复后按顺序补发。时间戳用单片机内部定时器累加单位秒精度要求不高。实操心得EEPROM 写入次数有限大概 10 万次。如果上报周期 5 秒断网一小时也就写 720 次问题不大。但不要每条数据都写 EEPROM先在 RAM 里攒够 8 条再一起写减少擦写次数。我一般用页写入一次写 8 字节效率高。6. 常见问题与排查技巧实录6.1 温度读数跳变或不准这是最常见的问题。排查顺序是这样的先看电源纹波用示波器测 PJ85718DM 的 VDD 引脚纹波超过 50mV 就会影响精度。然后看热电堆传感器的视场里有没有干扰源比如手靠近、气流吹过、附近有发热设备。再看 I2C 波形用逻辑分析仪抓一下看时序对不对有没有丢帧。最后看软件滤波参数窗口太小或者异常值剔除阈值太松都会导致跳变。我遇到过一回读数每隔几秒跳一次查了半天发现是无线模块发射时电源跌落导致 I2C 通信出错。后来在模块电源加了大电容问题解决。所以电源质量永远是第一位的。6.2 I2C 通信失败I2C 失败的原因很多我整理了一个排查表现象可能原因解决方法完全无应答地址错、供电没上、上拉电阻没接查地址引脚、测电压、补上拉偶尔 NACK总线电容大、速率高降速率、减小上拉电阻数据错位时序不对、中断打断关中断读、检查 restart总线卡死从机拉低 SDA 不放加总线恢复逻辑发 9 个时钟总线恢复逻辑我一般这么写如果 SDA 一直被拉低就把 SCL 配置成推挽输出发 9 个时钟脉冲然后发停止条件再重新初始化 I2C。这个逻辑放在错误处理里每次通信失败调用一次。6.3 串口通信丢包或误码串口丢包先看波特率误差。PIC18F56K42 用内部振荡器时波特率误差可能到 2% 以上超过 3% 就容易误码。换成外部晶振误差降到 0.1% 以内。然后看线缆RS485 用双绞线A/B 不要接反屏蔽层单端接地。无线模块的话看空中速率和距离距离远了降速率。还有一点容易忽略串口接收中断里不要做耗时操作比如浮点运算、EEPROM 写入。我习惯在中断里只把数据存到环形缓冲主循环再处理。这样不会丢字节。6.4 设备频繁复位复位原因查一下 RCON 寄存器能区分上电复位、看门狗复位、欠压复位。如果是欠压复位查电源和滤波电容。如果是看门狗复位查程序里有没有死循环或者阻塞操作。我一般把看门狗超时设 2 秒主循环里每 500ms 喂一次狗。如果某个操作可能超过 2 秒比如 EEPROM 页擦除就在操作前先喂狗操作后立刻再喂一次。7. 现场安装与抗干扰经验7.1 传感器安装位置的选择PJ85718DM 加热电堆的模块安装位置直接影响测量效果。测风管温度时传感器要伸进风管内部但不要正对气流方向否则气流冲刷会导致读数偏低。我一般让传感器轴线跟气流方向成 45 度角既保证响应速度又减少冲刷影响。测房间温度时装在离地 1.5 米左右避开窗户、门、出风口和热源。注意热电堆传感器的窗口怕灰尘和油污。HVAC 现场如果灰尘大要加防尘罩但防尘罩会降低响应速度需要权衡。我一般用金属网罩网孔 0.5mm 左右既能挡大颗粒又不影响红外透过。7.2 电缆屏蔽与接地传感器到主板的电缆如果超过 20cm一定要用屏蔽线。屏蔽层在主板端单点接地传感器端悬空。I2C 的 SDA 和 SCL 走双绞线跟电源线分开走不要平行走太长。RS485 的 A/B 线也必须双绞屏蔽层同样单端接地。接地电阻要小于 4 欧姆现场如果接地不好宁可不接屏蔽层也不要两端接地形成地环路。7.3 电源防护与滤波工业现场的电源质量参差不齐我一般在前端加 TVS 管、压敏电阻、共模电感、LC 滤波。TVS 选 18V 的压敏电阻选 14V 的共模电感用 10mH 的。后级再用 LDO 稳压到 5V 和 3.3V。LDO 的输入输出电容用 10uF 钽电容加 100nF 陶瓷电容效果比单纯用电解电容好。8. 固件升级与远程维护8.1 通过串口升级固件PIC18F56K42 支持 Bootloader我一般用串口升级。Bootloader 占 4KB Flash上电后先跑 Bootloader如果 500ms 内收到升级指令就进入升级模式否则跳转到应用程序。升级指令包括进入升级、擦除、写入、校验、跳转这几个命令。上位机把 HEX 文件解析后按帧发送每帧 64 字节带校验和。这个功能在现场很有用不用拆机就能升级。但要注意升级过程中不能断电否则设备变砖。我一般加一个升级标志在 EEPROM 里升级前写标志升级成功后清标志。如果上电发现标志还在说明上次升级失败自动进入 Bootloader 等待重新升级。8.2 远程参数配置与校准远程端可以下发指令修改报警阈值、上报周期、温度偏移量。偏移量用来校准传感器比如现场比对发现读数偏高 1.5 度就下发偏移量 -1.5 度设备把偏移量存 EEPROM每次采集后加上偏移再显示和上报。这个功能很实用因为传感器安装位置不同读数跟标准温度计总有偏差现场校准一下就能对上。校准指令我设计成带密码的防止误操作。密码存在 EEPROM 里默认 123456可以远程修改。收到校准指令后先验密码对了才执行。9. 实际项目中的性能数据与优化9.1 采集精度与响应时间实测我在实验室用标准黑体炉做了对比测试PJ85718DM 在 20 到 100 摄氏度范围内跟标准值的偏差在正负 0.8 摄氏度以内。响应时间方面从传感器接触目标到读数稳定到最终值的 90%大概需要 3 到 5 秒取决于目标温度和视场角。这个响应速度对于 HVAC 应用足够了因为空气温度变化本身就慢。优化响应时间的方法减小滤波窗口、提高采集速率、增大热电堆视场角。但滤波窗口小了数据会跳采集速率高了功耗增加视场角大了容易受背景干扰。我一般取折中采集速率 5Hz滤波窗口 8视场角根据安装距离选。9.2 通信距离与稳定性测试无线透传模块在空旷环境下9600 波特率、250kbps 空中速率可靠通信距离大概 200 米。有墙壁遮挡时降到 50 到 80 米。RS485 用双绞线9600 波特率可靠通信距离 1200 米。我一般根据现场情况选通信方式室内短距离用无线室外长距离用 485。稳定性方面我连续跑了 72 小时压力测试每 5 秒上报一次总共 51840 帧丢帧 3 帧丢帧率 0.006%。丢帧主要发生在无线模块切换信道的时候后来把信道固定丢帧率降到 0。9.3 功耗优化与电池供电考虑如果现场没有市电要用电池供电功耗就得优化。PIC18F56K42 在 64MHz 下运行电流大概 10mAPJ85718DM 连续采集模式大概 1mA无线模块发射时瞬间 100mA 以上。优化方法降低单片机主频到 16MHz电流降到 3mAPJ85718DM 改成单次采集模式采集完就休眠平均电流 100uA无线模块改成定时唤醒上报完就休眠。这样整体平均电流能降到 5mA 以下用 2000mAh 电池能跑 400 小时左右。实操心得电池供电时不要用 LDO 稳压LDO 的静态电流虽然小但效率低。直接用 DC-DC 降压效率能到 85% 以上。但 DC-DC 的开关噪声会影响传感器要在 DC-DC 输出加 LC 滤波或者给传感器单独用 LDO 供电。10. 后续扩展与个人体会这套方案跑了好几个项目稳定性没得说。后来我又做了些扩展比如加了一路湿度传感器通过 I2C 挂到同一条总线上PIC18F56K42 轮流读两个传感器数据一起上报。还加了一路继电器输出温度超限时直接控制风机或者加热器不用等远程指令。这些扩展都很简单因为 PIC18F56K42 的外设资源还有富余。我个人在实际操作中的体会是嵌入式温度监测这个活儿硬件设计占六成软件占三成剩下那一成是现场调试。硬件设计里电源和接地是重中之重软件里通信协议和错误处理是关键现场调试就是耐心加经验。PJ85718DM 和 PIC18F56K42 这个组合我不敢说是最好的但在我做过的项目里是性价比和稳定性平衡得比较好的一个。如果你也在做类似的东西希望上面这些细节能帮你少走点弯路。
阅读完成 · 觉得有帮助?
咨询建站