尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

单片机火灾预警系统设计:从传感器检测到状态机报警

单片机火灾预警系统设计:从传感器检测到状态机报警 简介基于单片机的火灾预警系统设计与实现是一份完整的本科毕业设计文档面向电子信息、自动化及相关专业学生用于学习单片机火灾报警系统从方案设计到软硬件实现的完整流程。文档以AT89C51为主控芯片搭配MQ-2烟雾传感器与DS18B20温度传感器介绍了多传感器数据采集、非线性与线性时间序列分析预测算法以及液晶显示、声光报警等功能模块的设计思路覆盖硬件电路选型与布置、控制器单元设计、软件编程与系统调试等关键环节。资源包含1个docx文档压缩包大小2.23MB内容紧凑便于阅读和打印适合作为课程设计或毕业设计的参考模板。已有111人学习下载。文档不仅给出了整体系统框架与具体功能实现还详细分析了操作人员管理、探测器管理、预报警、火警处理等模块并对系统的性价比、结构简单、使用方便等特点作了说明能够帮助读者快速理解火灾预警系统的设计方法。对于后续开展类似项目研发、完善报警算法或撰写论文都具有较好的参考价值。1. 从传感器到声光报警火灾预警系统到底在检测什么火灾预警系统听起来是个大工程拆到单片机这一层核心其实只有三件事把烟雾浓度、温度这类物理量变成电信号用一个判据决定“该不该响”再驱动蜂鸣器、LED 和继电器去执行报警与联动。很多课程设计和毕业设计卡住的地方不在硬件连接而在判据——传感器原始值跳来跳去直接和固定阈值比较必然误报。以 51 内核为中心的方案之所以在单片机火灾预警系统设计里最常见是因为 STC89C52 这类芯片便宜、外设资料全哪怕不带 ADC 也能用电压比较器或外接 PCF8591 把模拟量读进来。这篇博文按“硬件选型 → 检测原理 → 软件状态机 → 阈值标定 → 无线升级”的顺序把一套能跑通、能演示、能答辩的系统讲清楚适合做课程设计或入门嵌入式预警产品的读者。2. 主控、传感器与执行机构的选型逻辑2.1 为什么 51 内核仍是这类设计的主流选择选主控先问需求要采集几路模拟量、要驱动什么外设、要不要联网。对于火灾预警核心外设是烟雾传感器、温度传感器、蜂鸣器、LED 和显示模块实时性和运算量要求都不高STC89C52、STC12C5608 这类 51 内核芯片完全够用。它们的优势在 I/O 充足、5V 供电和传感器模块直接兼容以及 Proteus 仿真资料丰富做课程设计的人能快速验证逻辑。需要注意一个细节AT89C52 原生不带 ADC而 MQ-2 烟雾传感器输出的是模拟电压。这个矛盾的常见解法有三种我在实际项目里按成本从低到高排序LM393 电压比较器方案把 MQ-2 的输出和一个用电位器设定的阈值比较输出高低电平直接进单片机 I/O。电路最简单缺点是阈值只能在硬件上调改判据要动螺丝刀。外接 PCF8591 芯片用 I2C 总线扩展 4 路 ADC价格两块左右代码也不复杂能把烟雾浓度做成数值。直接换带 ADC 的型号比如 STC15W408AS 内部集成 10 位 ADC少一块外围芯片但很多人的开发板是 89C52所以这个方案往往出现在自己画板时。我一般推荐第二种。它保留了 89C52 的通用性又能把“数据采集→数值处理→阈值判断”这个完整链路在代码里体现出来答辩时也更有讲头。2.2 火灾预警系统的模块划分和供电设计系统按功能拆成六个单元传感采集、主控、报警执行、显示与交互、电源。各模块选型如下表。模块推荐器件用途关键参数烟雾浓度检测MQ-2 半导体传感器检测可燃气体和烟雾加热电压 5V模拟输出 0~5V 或 TTL 电平温度检测DS18B20检测环境温度参与联动判据单总线-55~125℃12 位分辨率主控STC89C52 / STC12C5608数据采集、判定、报警控制5V 供电双 16 位定时器模拟量采集PCF8591将 MQ-2 模拟电压转为数字量4 路 ADC8 位精度I2C 接口声光报警有源蜂鸣器、LED现场声光提示蜂鸣器工作电流约 30mA需三极管驱动显示LCD1602显示烟雾值、温度、报警状态4/8 位并口5V 供电联动执行5V 继电器驱动排风扇或电磁阀继电器线圈电流约 70mA需三极管驱动供电是新手最容易翻车的地方。单片机、PCF8591 和传感器都要 5V而继电器线圈瞬间启动电流可能拉到上百毫安如果全部从同一个 LDO 取电电压跌落会导致单片机复位。常见做法是用 USB 5V 输入经过 10uF 电解电容和 104 陶瓷电容并联退耦后给整个系统供电继电器单独接电源正端由 I/O 通过三极管控制通断避免线圈反峰电压串到主控电源线上。2.3 电平匹配和驱动能力一个不能跳过的细节51 芯片的 P0 口是开漏输出外部必须接 4.7k~10k 上拉电阻才能输出高电平P1~P3 内部有上拉但驱动能力有限。驱动蜂鸣器和继电器时绝对不能用 I/O 直接串负载因为 I/O 输出电流通常只有 10~20mA带不动线圈而且感性负载关断时会产生反向电动势容易打坏引脚。标准接法是三极管或 ULN2003 做驱动级。5V | 继电器线圈 | P2.0---[1k]---C B极 | NPN 8050 | E极---GND这个电路里基极串 1k 限流电阻I/O 输出高电平导通继电器吸合输出低电平时截止。线圈两端建议反向并联一个 1N4007 二极管方向是负极接 5V 正极接集电极否则关断瞬间的反峰电压最高能到几十伏。蜂鸣器同理有源蜂鸣器是正极接电源、负极接三极管集电极这样单片机只用提供一个开关信号。3. 传感器接口电路与信号调理从 MQ-2 电压到可比较的 ADC 数值3.1 MQ-2 的检测原理和分压电路计算MQ-2 属于半导体气敏传感器内部有一个加热电阻和一块二氧化锡气敏材料。加热电阻通电后让敏感材料处于高温状态空气中还原性气体浓度升高时材料表面电导率上升等效电阻 Rs 下降。传感器模块上的模拟输出本质是一个分压电路Vcc(5V) ---- Rs(传感器) ---- A点 ---- RL(负载电阻) ---- GND | 模拟输出A 点电压 Vout Vcc × RL / (Rs RL)。洁净空气下 Rs 很大Vout 很低烟雾浓度升高Rs 下降Vout 上升。注意这个关系不是线性的MQ-2 的 Rs 和浓度在对数坐标上才接近直线所以代码里如果要换算成 ppm 需要查手册里的灵敏度特性曲线和做指数拟合。对预警系统来说绝大多数应用不需要精确浓度只需要一个“趋势 阈值”判据所以直接用 ADC 数值做比较即可这也是大多数单片机火灾预警设计里的实际做法。3.2 PCF8591 的接线方式和 I2C 时序要点PCF8591 是 8 位 ADCI2C 地址由 A0/A1/A2 引脚决定默认全接地时地址是 0x48。和 STC89C52 连接时SCL 接 P2.1SDA 接 P2.2两根线都要接 4.7k 上拉电阻到 VCC。MQ-2 的模拟输出 AOUT 接 PCF8591 的 AIN0 通道。读取时序上有一个常被忽略的控制字问题I2C 写地址后传输的第一个字节是控制字默认值 0x00 表示允许模拟输出、选 AIN0 单端输入但如果上一轮程序改了控制字下一轮读之前必须重新写一遍否则会读错通道。我在调试时遇到过数据一直是 0 的情况就是这个原因。代码里把配置和读取分成两个函数能避免这类隐性问题。// I2C 起始信号 void I2C_Start(void) { SDA 1; SCL 1; SDA 0; SCL 0; } // 从 PCF8591 的 AIN0 通道读取 8 位数据 unsigned char PCF8591_Read_AIN0(void) { unsigned char value; I2C_Start(); I2C_SendByte(0x48 1); // 器件地址 写位 I2C_SendByte(0x40); // 控制字使能模拟输出选 AIN0 单端 I2C_Start(); I2C_SendByte((0x48 1) | 1); // 器件地址 读位 value I2C_RecvByte(); I2C_Stop(); return value; }逻辑说明先发一个 Start 信号再发“地址 写位”通知 PCF8591 接下来要写控制字控制字 0x40 的含义是 bit6 置 1 使能模拟输出bit0~bit1 为 00 选中 AIN0 通道。写完控制字后再次发 Start 和“地址 读位”此时从机在 SCL 时钟驱动下把转换结果放在 SDA 上主机接收一个字节后发 Stop。整个过程主时钟频率不要超过 100kHz51 直接用软件延时模拟即可。3.3 温度传感器 DS18B20 的接入与寄生供电问题DS18B20 适合做联动判据的第二路输入它的特点是严格遵循单总线协议时序窗口要求比较高。我在代码里一般把它的延时函数写成循环等待并且调好晶振后就不再改动。硬件上数据引脚要接一个 4.7k 上拉电阻到 VCC这是保证总线空闲为高电平的前提。有一个容易踩的坑是寄生供电模式DS18B20 只有两根线GND 和数据时靠数据线上的高电平给内部电容充电转换温度时会从总线汲取瞬时大电流如果总线上拉电阻太大或线太长转换结果会读出 85℃上电默认值代码逻辑上又不好排查。我自己做板时都直接接 VCC 和 GND 三根线避开这个坑。温度读取代码使用经典的单总线时序初始化时先拉低总线 480us 再释放等待 60~240us 的应答脉冲写 1 时拉低 1~15us 后拉高写 0 时拉低 60~120us读时隙拉低 1us 后释放在 15us 内采样引脚电平。4. 软件状态机与采样滤波报警不误报的关键实现4.1 主程序结构轮询加定时中断的例行做法火灾预警软件不需要上实时操作系统前台轮询加一个定时中断就够了。主循环负责读传感器、跑判定状态机、刷新 LCD定时器 0 每 200ms 中断一次给状态机提供一个节拍基准。这种架构的好处是逻辑直观不容易出现资源竞争。void Timer0_ISR(void) interrupt 1 { static unsigned char tick; TH0 0x3C; // 重装初值, 50ms 12MHz TL0 0xB0; tick; if (tick 4) { // 累计 200ms flag_200ms 1; tick 0; } } void main(void) { Timer0_Init(); // 定时器0, 模式1, 16位 LCD1602_Init(); display_string(0, 0, FIRE ALARM); while (1) { if (flag_200ms) { flag_200ms 0; smoke_adc_raw PCF8591_Read_AIN0(); temperature DS18B20_ReadTemp(); process_data(); // 滤波、判据、状态机 update_display(); // LCD刷新 } } }这里没有把所有逻辑都塞进中断只在中断里置一个标志位。标志位放在主循环可以避免在中断里调用 I2C 读数和单总线时序这种耗时操作否则中断时间过长会破坏单总线的时序窗口。参数上200ms 的采样间隔对烟雾扩散速度来说已经足够太快反而让后续数字滤波难以去除尖峰。4.2 滑动平均滤波与连续触发消抖两道滤网的作用不同烟雾传感器的原始输出波动很大集成式传感器模块内部虽然有比较器和电容滤波模拟输出仍带有环境扰动。软件里我用两层处理一层是滑动平均削平随机噪声一层是连续触发计数防止瞬时尖峰直接触发火警。#define FILTER_WINDOW 10 #define TRIGGER_COUNT 5 #define SMOKE_THRESHOLD 150 #define TEMP_THRESHOLD 50 unsigned char adc_buffer[FILTER_WINDOW]; unsigned char buffer_index 0; unsigned char trigger_counter 0; bit alarm_flag 0; unsigned int get_smooth_value(void) { unsigned int sum 0; unsigned char i; adc_buffer[buffer_index] smoke_adc_raw; buffer_index (buffer_index 1) % FILTER_WINDOW; for (i 0; i FILTER_WINDOW; i) { sum adc_buffer[i]; } return sum / FILTER_WINDOW; } void fire_detect(void) { unsigned int smooth; unsigned int temp; smooth get_smooth_value(); temp temperature; if (smooth SMOKE_THRESHOLD temp TEMP_THRESHOLD) { trigger_counter; if (trigger_counter TRIGGER_COUNT) { alarm_flag 1; } } else { trigger_counter 0; } }这段代码的关键参数在宏定义里窗口 10 次、连续 5 次触发。窗口越长平滑效果越强但真实烟雾到达时的响应也会变慢连续触发次数的作用是剔除偶发尖峰。这里的阈值 150 是针对 8 位 ADC0~255 范围的示例值实际值必须根据传感器在洁净环境下的基线来定不能照抄。注意 get_smooth_value 里用了取余运算在 51 上取余会消耗较多指令周期更高效的写法是让 buffer_index 到上限时归零再配合一个计数变量累加和这一步留给读者自己优化。4.3 状态机待警、预警、报警三态比简单 if 更可控不写状态机直接 if 判断阈值也能跑但会出现一个问题报警后蜂鸣器需要持续响 30 秒期间如果烟雾浓度暂时低于阈值主循环又把它关了现场听到的就是断断续续的响声。更规范的做法是把系统状态分为 STANDBY待警、PRE_ALARM预警、ALARM报警三态。STANDBY滑动平均值低于阈值蜂鸣器关LED 慢闪表示系统正常。PRE_ALARM连续 3 次采样超阈值蜂鸣器短鸣提示“可疑”LED 加快闪烁。ALARM从 PRE_ALARM 升级或烟雾和温度同时超阈值蜂鸣器长鸣继电器吸合启动排风设备。此状态持续 30 秒期间即使浓度下降也不立即撤销防止抖动。状态迁移只发生在主循环的判定函数里每次执行时读取当前状态和采样结果决定下一个状态。这套逻辑比散落的 if/else 好排查答题时也能清楚讲“为什么要消抖为什么要状态保持”。状态保持时长用一个递减计数器实现就在定时器中断里 tick 的基础上去累加秒数。5. 阈值标定的三次实测法与防误报调参5.1 先测基线再设阈值直接抄示例值的后果网上很多例程里写成if(smoke 150) alarm这个数字在不同传感器、不同供电电压下的含义完全不同。MQ-2 模块上的灵敏度电位器改变的是比较器参考电压不影响模拟输出但模拟输出本身的基线电压受 VCC 波动影响5V 电源有 0.3V 纹波时 ADC 读数就能差十几个数。所以必须实测环境基线步骤如下给系统上电让 MQ-2 预热至少 30 分钟因为敏感材料需要加热到工作温度才能稳定。保持周围环境通风良好且没有烟雾连续读取 50 次 ADC 原始值求平均。记录平均值和最大值阈值初始值设为“平均值 最大波动幅度的 2 倍”。用真实烟雾源测试如果触发太灵敏就增加阈值太迟钝就降低阈值每次调整幅度控制在 5% 以内。实际测量中我常用的模拟烟雾源是几根点燃的香烟放在距离传感器 10cm 处吹气测试时注意串口打印 ADC 原始值观察从基线到报警值的时间差。如果这个时间小于 1 秒说明阈值离基线太近正常炒菜时油烟就可能误报。5.2 双判据融合用什么参数组合降低误报单靠烟雾阈值误报率高尤其是厨房、楼道这类环境。常见做法是引入温度判据作为确认条件只有烟雾浓度超过阈值的连续采样次数达到 3 次且 DS18B20 读到的温度同时高出环境温度 8℃ 以上才进入 ALARM 状态。这个“烟雾 温度”的逻辑和很多商用探测器一致具体参数参考下表。参数建议范围作用调大的代价调小的代价FILTER_WINDOW8~16平滑采样噪声响应变慢抗干扰差TRIGGER_COUNT3~8连续触发确认漏报风险误报风险SMOKE_THRESHOLD基线波动2倍烟雾判定漏报误报温度偏差量5~10℃联动确认延迟报警高温环境误报报警保持时间20~60s防止同源抖动复位慢间歇鸣响我处理过的一个典型案例是有人在预警器旁边给主板做了助焊剂清洗挥发的异丙醇蒸汽瞬间让 ADC 数值冲到几乎满量程但因为环境温度没变化双判据拦截住了这次误报。这个案例说明单传感器阈值是必要条件而非充分条件融合判据的成本在代码里只有几行收益却在实用性上体现得最明显。5.3 调试期必备把传感器原始值和状态同时输出到串口标定调参时看不到内部数据等于盲调建议在系统初始化时设置串口通信并输出结构化信息。一根 USB 转 TTL 线就能把 STC89C52 的 P3.1TXD接到电脑上数据格式建议做成逗号分隔方便直接导入串口助手或表格。void send_report(void) { unsigned char buf[32]; sprintf(buf, smoke:%d,temp:%d,state:%d\r\n, smooth_value, temperature, current_state); UART_SendString(buf); }在状态机每次迁移时顺便调用这个函数记录“从待警到预警、再升级到报警”的全过程能看到触发时间点是否合理。这段代码不做复杂的处理关键是把 smooth_value 和原始值区分开避免调参时分不清当前温度是滤波前还是滤波后的值。6. 模块化扩展给系统预留串口协议并接上 Wi-Fi 上报预警系统的价值在“人不在现场时也能收到通知”给裸机系统加无线模块是最常见的进阶路线。模块选型上ESP8266 系列使用 AT 指令、成本低适合作为从设备挂在单片机串口上。接线注意电平匹配ESP8266 的串口是 3.3V TTL而 51 的 P3.0/P3.1 输出高电平为 5V直接连接可能损伤模块。常见做法是在 RX 端串接一个 1k 电阻分压或者用两个电阻组成分压网络降到 3.3VTX 端因为模块输出本身是 3.3V、能被 51 识别为高电平但保险起见也可以加电阻限流。软件上给单片机设计一个精简的上报帧不要裸发字符串。推荐格式是固定帧头加长度加数据和校验FF 55 04 0A 2C 01 8F其中FF 55是帧头04表示后面数据长度 4 字节0A 2C是烟雾 ADC 值高字节在前01是状态字节0 待警、1 预警、2 报警最后8F是校验和做法是所有数据字节相加取低 8 位。上位机或服务端收到后先校验数据错乱直接丢弃避免脏数据导致误报。给 ESP8266 配置透传模式时提前用 USB 转串口设好 Wi-Fi 参数单片机代码里只保留一条 AT 指令序列。系统上电后依次发送ATCWMODE1连接路由、ATCIPSTARTTCP,服务器IP,8080建立 TCP 连接、ATCIPMODE1进入透传模式之后所有 send_report 内容直接成为 TCP 负载。注意透传模式下不能再发 AT 指令否则会被当成数据发送这也是一个常见坑。验证方式用电脑上的网络调试助手开一个 TCP 服务端观察收到的帧是否和串口助手里的一致。如果上报延迟超过 2 秒排查方向在 Wi-Fi 信号强度和 TCP 心跳体而不在单片机代码本身。本文还有配套的精品资源点击获取
返回列表