单片机烟雾报警系统毕业设计:从MQ-2传感器到C51阈值标定
2026/9/20 0:22:04 网站建设 项目流程

简介:这是一份面向电子信息工程、自动化等相关专业毕业生的毕业设计文档,围绕AT89S52单片机烟雾报警系统,解决家庭小户型火灾报警需求。文档完整给出从方案论证、硬件电路、Protel/Proteus仿真到C语言软件调试的全过程,详细讲解DS18B20温度传感器与MQ-2烟雾传感器的选型、采集电路设计、显示与报警模块实现,以及系统整体联调方法,能帮助读者快速建立单片机测控系统的完整设计框架。系统在成本、安装与报警准确性上具有明显优势,可扩展至商业或工业场景。资源包共1个doc文件,约2.31MB,内容包含中英文摘要、目录、各章节设计方案、传感器原理分析、硬件原理图、软件流程图及调试思路,结构清晰、排版规范,可直接作为毕业设计说明书参考模板。已有173人学习该资料,适合正在做单片机类毕设或课程设计的学生使用。

1. 单片机烟雾报警系统:毕业设计怎么把“响铃”做成“可靠”

毕业设计里最常见也最稳的设备题目,就是单片机烟雾报警系统。它原理不深、器件好买、指标可量化,答辩时能把传感器原理、阈值标定、抗干扰设计讲清楚,就比单纯演示响铃得分高。但实际项目里的坑往往不在“能响”,而在“该响的时候响,不该响的时候别响”:做饭油烟误报、传感器上电预热时电压漂移、继电器抖动反打蜂鸣器,这些才是出现在验收现场的高频事故。这篇博客从传感器选型、硬件电路、C51采集代码到阈值标定和现场排错,把一套能落地的单片机烟雾报警系统方案讲透,适合正在做单片机毕业设计或课程设计,也想把系统做到“可用”而不是“能演示”的读者。

2. 传感器选型与检测原理:烟雾报警系统的“鼻子”怎么选

2.1 气敏电阻、离子式与红外光电式,毕业设计选哪种

烟雾报警系统的核心是烟雾传感器。目前主流方案有三类:催化燃烧式、半导体气敏电阻式、红外光电式,另外少数场合会用离子式传感器。毕业设计里,最常见且最可靠的选型是半导体气敏电阻,典型型号是MQ-2、MQ-7、MQ-135,其中MQ-2对烟雾、液化气、丁烷的灵敏度曲线最平缓,量程覆盖300~10000ppm,适合做家庭烟雾报警的演示与验证。

气敏电阻的检测原理是:传感器内部的二氧化锡(SnO2)加热到200~300℃后,表面吸附氧气形成势垒。当还原性气体或烟雾颗粒接触表面时,会改变载流子浓度,使电阻下降。MQ-2的输出端通常接一个负载电阻RL,通过电阻分压就能得到随烟雾浓度变化的电压信号。这个电压信号可以直接送ADC采集,也可以经过电压比较器转成开关量。

红外光电式传感器更适合检测大颗粒烟尘,比如火灾初期的白烟,但对酒精蒸汽、水雾不敏感。离子式传感器灵敏度最高,但含有放射源,现在家用和教学场景已很少采用。毕业设计不建议碰离子式。

2.2 MQ-2传感器模块的加热电压与负载电阻怎么定

MQ-2模块有两种常见形态:一种是裸传感器加外围电阻,另一种是集成的烟雾传感器模块。模块上一般已经集成好比较器(如LM393),输出DO数字量和AO模拟量。裸传感器接法更考验硬件基本功,答辩时也更好讲。

下面是裸传感器与单片机ADC的经典接法参数:

参数典型值说明
加热电压 VH5V ± 0.2V给传感器内部加热丝供电,必须稳定
回路电压 VC5V与RL串联形成分压
负载电阻 RL4.7kΩ~10kΩ决定输出电压的静态工作点
预热时间上电后3~5分钟传感器内部电阻稳定前,输出漂移很大
灵敏度调节10kΩ电位器调节比较器翻转点,模块上通常标配

我一般会把RL选在5.1kΩ,这样静态时AQ口电压大约在1.5~2V,烟雾浓度上升时电压升高,ADC的采集范围可以覆盖整个线性区。有些资料建议RL选1kΩ,但那针对的是高浓度燃气,用在烟雾报警上容易导致刚有一点烟就饱和。

2.3 数据手册里的灵敏度指标怎么看

MQ-2的数据手册里有一张典型的灵敏度特性曲线,横坐标是气体浓度,纵坐标是传感器电阻Rs与洁净空气中电阻R0的比值。读这张图有三个要点。

第一,R0本身不是固定值,它受湿度、温度、老化程度影响。所以实际做产品时,上电后需要先做基线校准,把洁净空气下的ADC读数记录为R0,而不是直接套手册里的绝对值。

第二,曲线在对数坐标系下几乎是一条直线,这说明在较宽的浓度范围内,传感器输出近似符合幂函数关系。用单片机做线性插值可以,但要明确告诉你:烟雾报警系统的核心需求是“阈值判断”,不是“精确测浓度”,所以没必要在ADC端做复杂的非线性补偿。

第三,响应时间(t90)通常在10秒以内,恢复时间在30~60秒。这意味着程序里的报警判断不需要毫秒级实时,反而需要加入延时去抖,避免烟雾浓度在阈值附近抖动时反复触发。

3. 硬件电路与STC89C52最小系统:烟雾报警系统的硬件骨架

3.1 最小系统电路与器件清单

STC89C52RC是51单片机里的常青树,Flash容量8KB,内置10位ADC(实际有效精度约8~9位),片内4KB EEPROM,适合直接跑烟雾报警系统。最小系统只需要五部分:电源、复位电路、晶振电路、下载电路和IO口引出。关键器件清单如下:

器件规格/型号数量作用
单片机STC89C52RC1主控
晶振11.0592MHz1定时器、串口波特率基准
复位电路10μF电容 + 10kΩ电阻1组上电可靠复位
电源5V/1A稳压模块(如LM2596)1给传感器和单片机供电
蜂鸣器5V有源蜂鸣器1报警输出
LED红色/绿色各1报警与运行状态指示
继电器5V单路继电器模块1驱动排风扇或电磁阀

电源部分是硬件里最容易出问题的一环。MQ-2传感器的加热丝瞬间电流在150mA左右,如果和单片机的5V共用一条细导线,加热丝的电压波动会直接影响ADC参考电压。我一般做法是:先用稳压模块输出5V,然后分成两路,一路直接给传感器供电,另一路经过LC滤波再给单片机供电。ADC的参考电压直接取滤波后的VCC,不要用单片机的AVref引脚接导线,否则采样值会跟着电源抖动。

3.2 传感器信号进ADC还是进比较器

MQ-2模块的AO口输出的是模拟信号,有两种接入方式。

方式一:AO口直接接单片机的ADC输入引脚。STC89C52的P1.0~P1.7复用为ADC通道,可以实时读取烟雾浓度数值。这种方式的好处是阈值可以随时改,不需要动硬件;显示浓度、串口打印、报警记录都方便。

方式二:模块DO口接外部中断或普通IO。DO口内部已经通过LM393比较器做了一次翻转,烟雾浓度超过电位器设定值时,DO输出低电平。这种方式适合没有ADC资源的单片机,但阈值调整需要拧电位器,不太直观。

我的建议是:如果做毕业设计,优先选方式一,用ADC实时采集浓度值,然后把阈值写死在程序里,或者用按键调整存入EEPROM。答辩时给评委现场调阈值,比拧电位器更专业。

3.3 声光报警与继电器驱动电路

蜂鸣器有两种:有源蜂鸣器内部带振荡电路,给高电平就响,驱动电流约20mA;无源蜂鸣器需要外部提供2~4kHz方波才能发声。烟雾报警系统建议用有源蜂鸣器,程序更简单。驱动方式上,直接用单片机IO口控制蜂鸣器三极管驱动电路。

继电器模块用于在报警时联动排风扇或切断燃气电磁阀。需要特别注意:继电器线圈是感性负载,断电瞬间会产生反向电动势,必须在继电器线圈两端并联一个续流二极管(如1N4007),否则可能损坏单片机IO口或复位电路。使用集成继电器模块时,还要注意模块的“高电平触发”和“低电平触发”跳线,和单片机IO口默认电平匹配。

4. 软件实现与阈值标定:用C51写烟雾报警系统的采集与判断

4.1 ADC采样初始化与多通道选择

STC89C52的ADC模块通过特殊功能寄存器控制,核心配置就两步:打开ADC电源,选择采样通道。下面是一段可直接用的C51代码。

#include <reg52.h> #include <intrins.h> #define ADC_POWER 0x80 #define ADC_FLAG 0x10 #define ADC_START 0x08 #define ADC_SPEED 0x60 sfr ADC_CONTR = 0xBC; sfr ADC_RES = 0xBD; sfr ADC_LOW2 = 0xBE; #define SMOKE_CH 0 // P1.0 接 MQ-2 模块 AO 口 #define TEMP_CH 1 // 预留第二通道 unsigned int get_adc(unsigned char ch) { ADC_CONTR = ADC_POWER | ADC_SPEED | ch | ADC_START; _nop_(); _nop_(); _nop_(); _nop_(); while (!(ADC_CONTR & ADC_FLAG)); ADC_CONTR &= ~ADC_FLAG; return (unsigned int)(ADC_RES * 4 + (ADC_LOW2 & 0x03)); }

代码说明:ADC_CONTR是控制寄存器,ADC_POWER位打开ADC电源,ADC_SPEED设置为90个时钟周期采样一次,保证采样稳定性。启动转换后,程序会等待ADC_FLAG置位,该标志位必须在软件里清零,否则下一次转换会误判完成。ADC_RES存放高8位结果,ADC_LOW2的bit0和bit1存放低2位,拼接后得到10位采样值。

关于通道选择,STC89C52的ADC通道号就是P1口的引脚序号,SMOKE_CH设为0时采集P1.0。如果你想同时接烟雾传感器和温湿度模块,就多定义几个通道宏,切换通道时最好连续采样两次并丢弃第一次结果,因为模拟开关切换瞬间会有残压。

4.2 滑动平均滤波与烟雾浓度爬坡检测

烟雾传感器的输出有明显的高频抖动,尤其在有风或者环境湿度变化大时。单次ADC读数直接拿来比较阈值,会产生临界抖动导致蜂鸣器断续鸣叫。常规做法是滑动平均滤波,代码短、占内存小,适合51单片机。

#define FILTER_LEN 8 unsigned int adc_buf[FILTER_LEN]; unsigned char adc_index = 0; unsigned int adc_filter(unsigned char ch) { unsigned char i; unsigned long sum = 0; adc_buf[adc_index] = get_adc(ch); adc_index = (adc_index + 1) % FILTER_LEN; for (i = 0; i < FILTER_LEN; i++) { sum += adc_buf[i]; } return (unsigned int)(sum / FILTER_LEN); }

逻辑说明:数组adc_buf存放最近8次采样值,每次新采集值覆盖最旧的那个,求和后取平均。FILTER_LEN取值8对应约80ms的平滑窗口,既能压住抖动,又不会让真实烟雾浓度的变化被拉得太钝。要注意sum用了unsigned long,因为8个10位ADC值累加最大是8×1023=8184,没超16位范围,但如果你把滤波长度加到32,就必须用32位累加。

滑动平均只是基础。我在毕设里还会加一个“爬坡检测”状态:若连续5次采样值都大于上一轮的值,就认为烟雾浓度在持续上升,即使还没到阈值,也把状态标记为“预警”,LED闪烁提醒。这样在传感器还没完全响应到位的时候,系统就能提前提示,答辩演示时用烟头靠近传感器的效果会更好。

4.3 阈值标定与报警灵敏度调节

烟雾报警系统的关键逻辑是双阈值回差判断。报警阈值ALARM_HIGH负责触发报警,恢复阈值ALARM_LOW负责解除报警,ALARM_LOW必须低于ALARM_HIGH,否则烟雾浓度在阈值附近波动时,系统会反复进入和退出报警状态。

#define ALARM_HIGH 200 // 报警阈值,对应烟雾浓度约 0.8mg/m³ #define ALARM_LOW 160 // 恢复阈值,比报警阈值低 40 个 ADC 码 bit alarm_flag = 0; void smoke_task(void) { unsigned int smoke_level; smoke_level = adc_filter(SMOKE_CH); if (alarm_flag == 0) { if (smoke_level > ALARM_HIGH) { alarm_flag = 1; alarm_output(1); // 打开蜂鸣器和继电器 } } else { if (smoke_level < ALARM_LOW) { alarm_flag = 0; alarm_output(0); // 关闭蜂鸣器,但保留 30 秒状态记忆 } // 烟雾未降回恢复阈值时保持报警,不做任何动作 } }

参数说明:ALARM_HIGH和ALARM_LOW的差值就是“回差”。回差大小直接决定报警系统的稳定性。我通常把回差设为报警阈值的20%左右。比如报警阈值是200,恢复阈值就设在150~160。如果现场测试时发现误报频繁,优先把回差加大,而不是无脑抬报警阈值,高阈值会牺牲对小烟雾的敏感度。

阈值标定的具体操作流程是:先把系统放在洁净空气中通电5分钟,用串口输出当前ADC值,比如稳定在60~80。然后点燃一支香烟靠近传感器,观察浓度值上升到多少会导致实际烟雾浓度已经“明显可见”,记录为报警阈值。再用打火机气体(丁烷)测试高浓度响应,确认饱和值不超过50%满量程,否则要调RL电阻降低静态工作点。

5. 抗干扰与异常处理:烟雾报警系统别在答辩现场误报

5.1 传感器预热漂移与电源去耦

MQ-2传感器刚上电时,内部加热丝的温度还在爬升,表面电导率变化很大,ADC读数会从几百缓慢掉到稳定值,这个过程需要3到5分钟。如果不做处理,上电瞬间就可能误触发报警。处理方式有两种。

第一种是软件方式:开机后进入30秒的“预热等待”状态,期间ADC照常采集但不做报警判断,只让运行指示灯闪烁提示。预热结束后,取当前稳定值作为基线过滤掉。

第二种是硬件方式:在传感器电源输入端加一个470μF电解电容和0.1μF陶瓷电容并联,给加热丝一个软启动效果。注意这个电解电容是给传感器供电的,不是给单片机供电,位置要尽量靠近MQ-2的电源引脚。

电源去耦的另一个重点:继电器或蜂鸣器动作瞬间,电流突变会在信号线上感应出毛刺。我一般会用光耦隔离继电器控制信号,虽然51单片机IO口直接驱动继电器模块也能工作,但光耦能把感性负载的干扰挡在控制器之外。如果嫌光耦增加成本,至少要在继电器电源端并联一个100μF电容。

5.2 报警状态机与恢复逻辑的正确设计

烟雾报警系统看起来是一个if-else判断,但真实场景里有三种状态:正常、预警、报警。状态之间切换需要连续多次满足条件,避免单次抖动触发。

#define CONFIRM_RISE 4 // 需要连续 4 次超过报警阈值 #define CONFIRM_FALL 10 // 需要连续 10 次低于恢复阈值 void smoke_state_machine(void) { static unsigned char rise_count = 0; static unsigned char fall_count = 0; unsigned int smoke = adc_filter(SMOKE_CH); if (smoke > ALARM_HIGH) { fall_count = 0; if (rise_count < 255) rise_count++; if (rise_count >= CONFIRM_RISE) { set_alarm(1); } } else if (smoke < ALARM_LOW) { rise_count = 0; fall_count++; if (fall_count >= CONFIRM_FALL) { set_alarm(0); } } else { rise_count = 0; fall_count = 0; } }

这里有个容易忽略的点:恢复阈值比报警阈值低,但两者之间的区间不能把计数器直接清零。比如烟雾浓度从300降到170时,仍高于恢复阈值160,此时系统应该保持报警状态,只是计数器清零。所以代码里用else if而不是else,仅在smoke < ALARM_LOW时才走消除逻辑。

5.3 用串口打印采样值快速定位误报原因

整个烟雾报警系统里最实用的调试验证手段,不是LED也不是蜂鸣器,而是串口打印。STC89C52用11.0592MHz晶振,串口波特率设置为9600时,可以用定时器1工作在模式2产生波特率,不需要额外晶振。下面是串口初始化和打印函数。

void uart_init(void) { SCON = 0x50; TMOD &= 0x0F; TMOD |= 0x20; TH1 = 0xFD; TL1 = 0xFD; TR1 = 1; } void uart_send_char(unsigned char dat) { SBUF = dat; while (!TI); TI = 0; } void uart_send_string(unsigned char *s) { while (*s) { uart_send_char(*s++); } } void debug_report(unsigned int adc_val, unsigned char state) { unsigned char buf[4]; buf[0] = 'A'; buf[1] = 'D'; buf[2] = 'C'; buf[3] = (unsigned char)(adc_val >> 2); uart_send_string("STATE:"); uart_send_char(state + '0'); uart_send_string(" VAL:"); uart_send_char((adc_val / 100) + '0'); uart_send_char(((adc_val / 10) % 10) + '0'); uart_send_char((adc_val % 10) + '0'); uart_send_string("\r\n"); }

代码里的uart_send_char等待TI标志位,这是51单片机串口发送的固定套路。注意发送一个字节前要等上次发送完成,否则SBUF会被覆盖。adc_val / 100这种按位拆数字的方式有个边界问题:当adc_val等于200时,输出的是2、0、0,正常;当adc_val小于100时,第一位会输出'0',不影响阅读。

用串口助手连上后,把光标靠近传感器吹一口烟,观察VAL值的变化趋势。如果VAL值跳变幅度超过±30,优先检查传感器电源;如果VAL值稳定但误报,再检查程序和回差设置。串口打印能帮你把“传感器问题”和“程序问题”快速分开。

6. 部署验证与灵敏度调节技巧:烟雾报警系统上门前的最优设定

烟雾报警系统做完后,不要急着直接验收。先用一张标定记录表做三次重复测量,每次间隔5分钟,记录下“触发报警时的ADC值”和“解除报警时的ADC值”。如果三次的触发值波动超过±20个ADC码,说明传感器预热不充分或供电不稳定,需要先解决这个问题再谈灵敏度。

灵敏度调节的核心技巧是调节比较器模块上的电位器,但如果你的系统直接用ADC采集,则应该在程序里留出“灵敏度档位”概念。比如定义三个阈值等级:低灵敏度(LOW)对应ALARM_HIGH=230,中灵敏度(MID)对应200,高灵敏度(HIGH)对应170。用按键切换档位并存入STC89C52的EEPROM,这样现场演示时可以快速切换,不用重新烧录程序。STC89C52内部EEPROM擦写寿命约10万次,足够毕业设计反复改写。

另一个验证技巧是人为制造“缓慢烟雾”与“突发烟雾”两种场景。缓慢烟雾用蚊香靠近传感器,观察报警延迟是否在10秒内;突发烟雾用打火机气体短喷,观察系统是否在2秒内进入报警。两种场景都通过后,再把系统断电静置10分钟重新上电,确认没有“上电即报警”的故障。如果上电后有短暂报警,检查程序里是否做了预热等待,以及报警延时去抖的时间是否被设成0。

最后回到回差设置:假设你的报警阈值是200,恢复阈值是160,那么用户手动复位按钮其实不需要设计。烟雾散尽后系统会在几十秒内自动消除警报。如果验收现场希望报警后能手动消音,可以在蜂鸣器控制逻辑里增加一个“静音30秒”的状态,只静音蜂鸣器,不关闭继电器和状态LED。这比增加物理消音按钮更简单,而且逻辑上不容易出现“消音后烟雾未消散就一直静音”的安全漏洞。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询