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

资讯详情

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

基于51单片机的烟雾温度火灾报警系统设计与实现

基于51单片机的烟雾温度火灾报警系统设计与实现 简介这套基于单片机的火灾报警系统设计与实现资料面向单片机初学、课程设计及电子竞赛人群完整演示了烟雾与温度双参数监测的报警方案。系统以烟雾传感器和单片机为核心可实时采集烟雾浓度和环境温度并在显示模块上同步呈现同时支持按键修改报警阈值当浓度或温度超限时触发声光报警。硬件设计包括烟雾信号采集、单片机最小系统、按键阈值设置、显示与蜂鸣器报警电路软件设计按模块拆分涵盖初始化、采集处理、显示刷新、按键扫描和报警判断等子程序便于理解各功能如何协同工作。压缩包内共36个文件容量约4.27MB以C/H源码、obj/lst等编译工程文件、SchDoc/PDF原理图、hex可烧录文件及实物照片为主可对照电路图、代码和实物进行联合调试。资源已有3264人学习。通过该资源可掌握传感器信号处理、单片机接口设计、报警阈值逻辑等项目级技能获得的完整工程模板与源码结构能为课程设计或竞赛开发提供直接参考。1. 项目整体设计与器件选型思路手头这套基于单片机的火灾报警系统是我在实验室从零开始搭的一套完整方案包含原理图设计、51单片机源代码、实物焊接调试三个完整环节。先说说这套系统到底能干什么它通过烟雾传感器和温度传感器实时采集环境数据一旦烟雾浓度或温度超过设定阈值系统就会驱动蜂鸣器报警、LED灯光闪烁同时把当前状态显示在LCD屏幕上实现一个标准的火灾预警闭环。做这个项目之前我先明确了一个核心定位这套东西不是做产品而是做教学和原理验证所以器件选型全部走成熟、便宜、资料多的路线。主控芯片我选了STC89C52RC理由很直接51内核的生态太成熟了寄存器手册写得很直白中断、定时器、串口这些外设用起来不会像32位芯片那样让初学者卡在初始化配置上。如果你手头有其他51系列芯片比如AT89S52、STC12系列这套代码基本可以直接迁移只是时钟和串口初始化部分要按数据手册微调。传感器的选型是这个系统最关键的决策点。烟雾检测我用的是MQ-2气敏传感器模块它内部有一个二氧化锡半导体气敏元件当环境中可燃气体或烟雾浓度升高时元件表面电导率会发生变化从而改变输出电压。MQ-2的好处是灵敏度可调、响应速度快、模块上直接集成了比较器LM393和电位器既可以输出数字信号DO也可以输出模拟信号AO非常灵活。温度检测我选了DS18B20单总线协议只需要一根数据线就能跟单片机通信测温范围-55℃到125℃精度0.5℃完全满足火灾报警场景的需求。显示部分用的是LCD1602这是51单片机项目里最经典的显示器件16像素乘以2行足够显示两路传感器的实时数据和报警状态。这套方案的选型思路很明确所有器件都是市面上流通量最大、Datasheet最全、教程最多的型号。我见过不少新手一上来就选带IIC接口的OLED或者高精度数字温湿度传感器但这类器件对时序要求更高一旦出了问题排查起来非常痛苦。对于火灾报警系统这种逻辑并不复杂的项目传感器取模拟量、MCU做阈值判断、外设做声光显示思路越简单越不容易出错。2. 硬件电路原理图解析2.1 信号采集链路从传感器到单片机引脚整个硬件系统的信号流向是这样的MQ-2模块的AO引脚输出模拟电压接到单片机的P1.0ADC通道0DS18B20的数据引脚接到P3.7LCD1602的RS、RW、EN分别接P2.0、P2.1、P2.2数据口D0到D7接P0口需要外接上拉电阻蜂鸣器接P1.1LED报警灯接P1.2另外预留了一个继电器接口接P1.3用来控制排风扇或者电磁阀。MQ-2传感器在电路上需要重点说明的是它的工作电压和预热问题。MQ-2的加热丝需要5V供电加热电流在150mA到180mA之间所以不建议直接从单片机引脚的IO口取电必须从5V电源端单独走线。我在原理图里专门加了一个100uF电解电容和104瓷片电容并联的电源滤波网络放在MQ-2模块的供电引脚旁边这个细节非常关键因为MQ-2的加热丝在低温启动瞬间会有比较大的浪涌电流不加滤波电容的话可能会导致单片机上电复位异常。DS18B20的上拉电阻是另一个高频踩坑点。单总线协议要求数据线上必须接一个4.7k欧姆的上拉电阻到VCC否则通信会不稳定出现温度读数跳变或者直接读不出来。我在原理图上把这个电阻明确标注出来就是为了防止有人画PCB时漏掉。如果你用的是寄生供电模式还需要在数据线和VCC之间再接一个MOS管做强上拉但我这套设计采用外部供电方式就不需要这么复杂了。2.2 执行单元与电源设计蜂鸣器驱动电路我用了NPN三极管S8050做开关放大。为什么不能直接把蜂鸣器接到IO口上因为51单片机的IO口灌电流能力大约只有10mA到20mA而有源蜂鸣器的工作电流通常在25mA到35mA之间直接驱动会导致单片机IO口电压被拉低影响整个系统的稳定性严重时还会烧毁IO口。三极管基极串联一个1k欧姆电阻限流集电极接蜂鸣器负极蜂鸣器正极接5V电源发射极接地这样用很小的基极电流就能控制蜂鸣器的通断。蜂鸣器两端我还反并联了一个二极管IN5819用来吸收感性负载关断瞬间产生的反向电动势保护三极管不被击穿。电源部分整套系统统一使用5V供电我推荐用USB供电或者7805稳压模块。如果用7805输入电容选220uF输出电容选104和100uF的组合这样可以有效抑制纹波。我曾经遇到过因为电源纹波过大导致DS18B20读温度偶尔出现85℃这个错误值的情况排查了很久最后发现是电源的问题。后来在电源输出端加了LC滤波问题就消失了。这里也提醒各位单片机系统出问题不要总是怀疑代码很多时候硬件供电才是根源。3. 软件设计与源代码关键实现3.1 主程序架构与任务调度软件部分整个工程基于Keil C51开发环境代码结构分成5个模块主程序main.c、LCD显示驱动lcd1602.c、温度传感器驱动ds18b20.c、烟雾浓度采集与报警逻辑control.c、延时函数delay.c。这种模块化设计看起来好像多花了时间但实际上对后期调试非常友好出了问题直接定位到对应的驱动文件就行不用在一个几千行的main.c里翻来翻去。主程序的核心逻辑是一个不断循环的检测和判断流程void main(void) { unsigned char smokeValue 0; // 烟雾浓度对应的ADC采样值 float temperature 0; // 当前温度值 Lcd12864_Init(); // 实际项目里可根据屏型号换成 Lcd1602_Init() Ds18b20_Init(); Buzzer_Init(); while (1) { smokeValue MQ2_GetValue(); // 读取烟雾传感器ADC值 temperature Ds18b20_GetTemper(); // 读取温度值 Alarm_Process(smokeValue, temperature); Display_Process(smokeValue, temperature); delay_ms(200); // 循环间隔200ms } }整个主循环的间隔我控制在200ms这个时间设定是经过考虑的。火灾报警系统需要一定的响应速度但也不需要每毫秒都刷新200ms的轮询周期既能保证异常情况在0.2秒内被发现又能留出足够的时间让ADC采样稳定、LCD显示不闪屏。如果你觉得响应速度不够快可以把delay改成50ms但要配合LCD显示刷新逻辑做调整否则屏幕会明显闪烁。3.2 烟雾浓度采集与报警阈值判定烟雾浓度采集用到的是ADC0804模数转换芯片8位分辨率输出范围0到255对应0V到5V的模拟输入电压。为什么在用STC89C52还要外挂ADC芯片因为51单片机本身不带ADC模块这是它跟STM32最大的差距。ADC0804的时序并不复杂CS拉低使能WR拉低启动转换转换完成后INTR引脚拉低此时读取DB0到DB7就能得到数字量。核心读取函数unsigned char MQ2_GetValue(void) { unsigned char value 0; ADC0804_CS 0; // 片选使能 ADC0804_WR 0; // 启动转换 ADC0804_WR 1; while(ADC0804_INTR); // 等待转换完成INTR变低 ADC0804_RD 0; value P0; // 从P0口读取8位数据 ADC0804_RD 1; ADC0804_CS 1; return value; }阈值判断的逻辑是这样设计的先对烟雾采样值做5次连续采样去掉最大值和最小值取中间三次的平均值然后再跟设定的报警阈值做比较。为什么要做滤波因为MQ-2本身存在一定的输出波动如果直接用单次采样的值做判断很容易出现烟雾浓度恰好处于临界值附近时蜂鸣器反复鸣叫的情况。我实测过不加滑动滤波时报警信号会间隔性地一响一停加上滤波之后整个系统就稳定多了。火灾报警的双重判定条件是这套软件设计的核心亮点只有烟雾浓度超过阈值且温度超过50℃时才判定为一级火灾报警单条件触发时只提示预警状态。这样设计的目的是降低误报率毕竟单纯炒菜的油烟也可能让烟雾传感器数值飙高但温度不会同时升高到50℃。当然你可以在代码里用宏定义这个判定模式改成“或”逻辑来提升灵敏度这个根据项目需求调整就行。3.3 DS18B20时序操作与温度读取DS18B20的驱动最考验对时序的理解。它是单总线通信所有操作都严格依赖时序初始化时序、写时序、读时序。采样间隔和时序延迟如果不符合要求就会出现数据错误。核心代码如下bit Ds18b20_Init(void) { bit presence 0; DQ 1; delay_us(2); DQ 0; delay_us(480); // 拉低总线480us以上产生复位脉冲 DQ 1; delay_us(60); // 释放总线等待从设备应答 presence DQ; // 读取存在脉冲0表示有设备应答 delay_us(420); return presence; }这里必须用微秒级延时C51里用_nop_()或者自己写一个简单的循环来实现。我见过不少人在Keil里直接用delay_ms(1)代替微秒延时结果温度读数要么是0要么是85这就是典型的时间参数不匹配问题。如果你用的是12MHz晶振一个机器周期是1us_nop_()正好是一个机器周期写时序的时候用它做基础延时单位非常合适。DS18B20读取温度的完整流程是复位后发送0xCC跳过ROM匹配因为总线上只挂了一个DS18B20再发送0x44启动温度转换等待转换完成默认12位精度需要750ms后再复位发送0xCC和0xBE读取暂存器得到的16位数据中低4位是小数部分高5位是符号位中间7位是整数部分。实际使用中如果需要0.5℃的分辨率把低4位直接忽略、右移4位得到整数温度就足够了。4. 实物搭建、调试与排坑实录4.1 PCB布局与焊接要点画PCB的时候我踩过一个比较深的坑就是MQ-2传感器位置放得太靠近蜂鸣器。MQ-2本身是一个开放式结构的传感器气体需要自由流通才能准确检测而蜂鸣器在工作时会带动周围空气振动无形中影响了传感器附近的气流导致烟雾浓度读数上下波动。后来我把MQ-2挪到板子边缘、蜂鸣器放到对角位置问题才解决。所以布局时气敏传感器一定要远离任何可能产生气流扰动的器件。焊接顺序也有讲究。我建议先把电源部分的元件焊上包括电源插座、滤波电容、7805、LED电源指示灯然后通电用万用表确认5V输出电压正常再焊接主控芯片座、晶振、复位电路。等最小系统工作正常了再逐步焊接LCD接口、传感器模块、蜂鸣器驱动电路。这种分模块焊接的方法可以最大限度降低“焊完一上电全板冒烟”的惨剧概率。这里分享一个很多教程不会讲的细节STC89C52的复位电路。常规设计是10uF电解电容串联10k电阻接一个按键P0口需要外接10k排阻做上拉。如果你忘了加P0口上拉电阻LCD1602在显示的时候会出现一个非常诡异的现象——背光亮了但屏幕就是不显示字符。因为P0口内部没有上拉电阻输出高电平的驱动能力极弱解决方式就是加排阻或者直接用P2口接LCD数据线实测P2口是可以直接驱动LCD1602的虽然官方手册里P2口是准双向IO口但驱动能力和P0完全不同。4.2 常见问题与排查技巧速查表我把这套系统从画原理图到实物调试过程中遇到的坑整理成了一张速查表基本涵盖了新手做这类项目可能遇到的90%的问题。现象可能原因排查路径LCD1602背光亮无字符P0口未加上拉电阻检查排阻是否焊接开机时调节LCD对比度电位器DS18B20显示85℃或0℃时序延时不对或未接上拉电阻用逻辑分析仪或示波器对比时序确认4.7k上拉蜂鸣器不响或声音嘶哑三极管驱动电流不足或反向二极管焊反测基极电压是否0.7V左右二极管方向烟雾报警频繁误触阈值设置不合理或传感器未预热MQ-2通电5分钟后调试调高阈值或加滑动滤波ADC读数一直255或0ADC0804片选/读写时序引脚接错用万用表测传感器的AO引脚是否随气体浓度变化系统一上电就复位电源滤波不充分加大电解电容给传感器独立供电特别强调一点MQ-2传感器刚通电的前几分钟输出值会有一个明显的漂移过程这是气敏元件内部加热丝在工作、元件表面温度正在稳定所致不是故障。我发现不少同学拿示波器测MQ-2输出看到电压在缓慢变化就以为板子有问题结果折腾了半天只是没等预热。建议调试前先让传感器通电稳定5分钟以上再校准这是做这类气敏项目的基本操作习惯。4.3 报警阈值标定技巧报警阈值的设定是整个项目的灵魂。每个使用环境不同MQ-2的基准输出电压也就不一样在空气质量好的环境里可能只有0.3V在空气略有油烟的环境里可能到了1.0V。所谓标定就是让系统先学习当前环境下的“正常烟雾值”然后在此基础上叠加一个增量作为报警阈值。低成本做法是在代码里定义一个偏移量#define SMOKE_ALARM_OFFSET 40 #define TEMP_ALARM_VALUE 50 unsigned char smokeBase 0; void Calibrate_Baseline(void) { unsigned char i; unsigned int sum 0; for(i 0; i 10; i) { sum MQ2_GetValue(); delay_ms(100); } smokeBase sum / 10; } void Alarm_Process(unsigned char smoke, float temp) { if(smoke smokeBase SMOKE_ALARM_OFFSET || temp TEMP_ALARM_VALUE) { Buzzer_ON(); LED_ON(); } else { Buzzer_OFF(); LED_OFF(); } }这样每次开机先让系统自动采集10次平均值作为基准值再把阈值设定在基准值叠加偏移量的位置。如果是用于厨房这种油烟本来就偏大的环境把偏移量适当调高到60到80减少误报如果是用于机房这种本身就要求高敏感度的场景偏移量可以降到20。我在实际使用中发现只用烟雾阈值和只用温度阈值判断都有明显缺点。烟雾传感器对明火产生的烟感很灵敏但对电烤炉这类无烟热源完全没反应DS18B20测温准确但火灾发生初期温度上升到50℃需要一定时间。两者结合使用是最稳的方案也正是这套系统采用双重判断的原因。4.4 实物调试的核心流程拿到焊接好的板子后我的调试流程是先用万用表短路档检查电源正负极之间有没有短路这一步能救回不少板子确认无误后插上USB电源看电源指示灯是否亮量一下7805输出是不是5V。然后下载烧录程序STC89C52用STC-ISP软件通过串口烧录设置晶振为12MHz如果板子上用的是11.0592MHz晶振要改对应频率。最小系统跑起来之后我习惯先单独测试每个外设。先测LCD1602因为我写了一个专门的测试程序让屏幕全显“A”正常的话整个屏幕会显示一片“A”字符再测DS18B20看显示的室温跟温度计是否一致误差在正负1℃内都算正常最后测MQ-2用一个打火机的气体口靠近传感器不用点火只释放丁烷气体看ADC数值是否明显升高直到触发报警。这一步千万注意测试时不要在传感器旁边直接点火尤其是扣下打火机但没有电子打火点的瞬间气体直流出来如果没控制好浓度会让MQ-2输出持续饱和需要等很久才能恢复。5. 源代码结构与扩展方向这套系统完整的源代码工程包含以下文件main.c主循环和状态机调度lcd1602.c/hLCD1602底层驱动走4位模式节省IO口ds18b20.c/hDS18B20驱动包含CRC校验control.c/h报警判定逻辑、阈值标定delay.c/h微秒和毫秒延时如果你希望把系统做得更接近实际产品我建议在以下三个方向做扩展。第一个方向是在现有基础上增加GSM或Wi-Fi模块火灾报警信息可以通过串口发送到远程平台实现远程报警第二个方向是接入更高精度的ADC芯片比如12位的ADS7824提高烟雾浓度数据的分辨率方便分析缓慢变化的趋势第三个方向是把主控升级到STM32用RTOS做多任务调度让传感器采集、显示刷新、报警处理并行运行从根本上提升系统的响应能力。同时给你一个提醒如果在其他平台复现这套代码ADC读取、LCD的引脚映射、DS18B20的时序延时这几个点一定要结合自己的芯片手册重新确认特别是延时函数晶振频率不一样延时时间就不一样。这几个地方是我在移植过程中最容易出问题的部分也是各位如果照着这个方案复现很容易栽跟头的地方。这个项目的完整度比较高从硬件原理图到软件代码都能跑通实物也稳定运行了很久非常适合作为单片机课程设计、毕业设计或者想深入了解传感器采集和嵌入式逻辑实现的练手项目。如果有任何环境差异的问题优先从电源和时序两个方向排查大概率能找到原因。本文还有配套的精品资源点击获取
返回列表