基于STC89C52与Proteus的火灾报警系统设计与仿真实践
2026/8/5 16:19:49 网站建设 项目流程

这次我们来看一个基于 STC89C52 单片机的木材仓库火灾报警系统设计。对于从事单片机开发、嵌入式系统课程设计或电子竞赛的同学来说,这是一个非常经典且实用的项目。它不涉及复杂的 AI 模型或高算力需求,核心在于如何利用低成本、易获取的硬件(如 STC89C52、DS18B20、MQ-2 传感器)和软件工具(如 Keil、Proteus),构建一个稳定可靠的本地化监测与报警方案。

项目的重点不是概念多复杂,而是能不能在你手头的开发板上跑起来,以及如何通过仿真验证整个系统的逻辑。本文将带你从零开始,理清系统的核心功能、硬件选型、电路设计、代码编写,并最终在 Proteus 中完成仿真测试。如果你关心如何将理论知识转化为一个可演示、可调试的完整项目,这篇文章可以直接收藏。

我们将重点关注系统的模块化设计思路、传感器数据采集的稳定性、报警逻辑的可靠性,以及 Proteus 仿真与实际硬件调试的差异。通过本文,你将掌握一个完整的“传感器+单片机+执行器”系统开发流程,并能够将其思路迁移到其他安防或环境监测场景中。

1. 核心能力速览

能力项说明
核心控制器STC89C52(兼容 AT89C52)8 位单片机
温度监测DS18B20 数字温度传感器,单总线通信,精度 ±0.5°C
烟雾监测MQ-2 半导体烟雾/可燃气体传感器,模拟量输出
显示模块LCD1602 液晶显示屏,用于实时显示温度和烟雾浓度
声光报警LED 指示灯与蜂鸣器,用于超限报警
开发环境Keil uVision5(代码编写与编译)
仿真工具Proteus 8 Professional(电路设计与系统仿真)
程序烧录使用 STC-ISP 工具通过串口下载
适合场景单片机课程设计、毕业设计、电子竞赛、物联网安防系统入门实践

2. 适用场景与使用边界

这个基于 STC89C52 的火灾报警系统设计,主要适用于以下几类人群和场景:

  • 单片机初学者与学习者:作为从理论到实践的桥梁,项目涵盖了 GPIO 控制、ADC 采集、单总线通信、中断、液晶显示等单片机核心知识点,是巩固 51 单片机知识的绝佳练手项目。
  • 课程设计与毕业设计:项目结构完整,包含硬件设计、软件编程和仿真验证,文档和代码易于扩展(例如增加 GSM 短信报警、Wi-Fi 上传数据等),能够满足大多数本科阶段电子类课程设计或毕业设计的要求。
  • 电子竞赛与创新实践:可作为智能安防、环境监测类赛题的基础框架,快速搭建原型系统。
  • 小型场所本地化监控:理论上可用于小型木材仓库、档案室、实验室等对防火有基本要求的封闭空间,进行本地化的温度与烟雾浓度监测。

使用边界与重要提醒:

  1. 教学与原型验证用途:本文所述系统主要在 Proteus 仿真环境下验证逻辑,其传感器模型(如 MQ-2)行为是简化的。切勿直接将仿真系统用于真实火灾报警场景。真实环境复杂,涉及传感器校准、防误报算法、设备防护等级、供电可靠性、国家消防认证等一系列工程和安全问题。
  2. 性能限制:STC89C52 处理能力和内存有限,不适合运行复杂的滤波算法或连接过多外设。DS18B20 和 MQ-2 的响应速度、精度和稳定性在极端环境下可能不足。
  3. 安全合规性:任何用于真实人身财产安全防护的系统,都必须遵循所在国家或地区的相关安全标准和法规,并采用经过认证的专业设备。本设计仅为学习提供思路参考。

3. 环境准备与前置条件

在开始动手之前,请确保你的电脑上已经安装好必要的软件环境。这是项目能否顺利推进的第一步。

软件环境清单:

  1. Keil uVision5 (C51 版本):用于编写、编译和调试单片机的 C 语言源代码。确保安装时选择了 C51 工具链,而不是 ARM 的。
  2. Proteus 8 Professional (或更高版本):用于绘制电路原理图并进行交互式仿真。需要包含 8051 系列单片机、LCD1602、DS18B20、MQ-2 等元件的仿真模型库。
  3. STC-ISP 烧录软件:如果你有实物开发板,需要此软件将通过 Keil 生成的.hex文件烧录到 STC89C52 单片机中。可以从 STC 官网下载最新版。
  4. 串口调试助手(可选但推荐):如SSCOMXCOM,用于在实物调试时查看单片机通过串口打印的数据,便于排查问题。

硬件知识准备:

  • 基础 C 语言编程:理解变量、函数、循环、条件判断。
  • 51 单片机基础:了解 GPIO、定时器/计数器、中断、串口通信的基本概念。
  • 电路基础:能看懂简单的原理图,理解上拉电阻、电源、接地的含义。
  • 传感器初步了解:知道 DS18B20 是数字温度传感器,MQ-2 是模拟量输出的烟雾传感器。

检查你的 Proteus 元件库:打开 Proteus,在元件选择框中搜索以下关键词,确认是否存在对应的仿真模型:

  • AT89C52(可替代 STC89C52)
  • LM016L(即 LCD1602)
  • DS18B20
  • MQ-2MQS-2(Proteus 中可能用此模型)
  • BUZZER(蜂鸣器)
  • LED
  • POT-HG(滑动变阻器,用于模拟 MQ-2 输出变化)
  • RES(电阻)
  • CAP(电容)
  • CRYSTAL(晶振)

如果缺少某个模型,需要去网上寻找并添加到你的 Proteus 库中。

4. 系统设计与原理图绘制

在编写代码之前,我们需要在 Proteus 中设计出系统的电路原理图。清晰的电路图是后续仿真和实物连接的基础。

4.1 核心模块连接设计

1. 单片机最小系统:

  • STC89C52 的P0口需要接上拉电阻(例如 10kΩ 排阻)才能驱动 LCD1602。
  • 连接 12MHz 晶振到XTAL1XTAL2,并配上两个 30pF 左右的电容到地。
  • RST引脚接上电复位电路(10uF 电容 + 10kΩ 电阻)。
  • EA引脚接高电平(VCC),使用内部程序存储器。

2. 显示模块 (LCD1602):

  • RS,RW,E控制引脚分别接单片机P2.0,P2.1,P2.2
  • D0-D7数据引脚接单片机P0.0-P0.7
  • VSS接地,VDD5VVEE接一个滑动变阻器中间引脚用于调节对比度。

3. 温度传感器 (DS18B20):

  • DQ数据引脚接单片机P3.7,并接一个 4.7kΩ 的上拉电阻到VCC
  • VDD5VGND接地。
  • 注意:DS18B20 是单总线设备,对时序要求严格,仿真中模型工作良好,实物连接时导线不宜过长。

4. 烟雾传感器 (MQ-2):

  • MQ-2 有 4 个引脚(VCC,GND,DO,AO)。我们使用模拟输出AO
  • AO引脚接单片机P1.0(假设使用 ADC0808 芯片进行 AD 转换)或者,更简单的,在仿真中我们可以用一个滑动变阻器 (POT-HG) 来代替 MQ-2 的模拟输出,将其滑动端接至P1.0,通过手动调节阻值来模拟烟雾浓度变化。单片机通过查询P1.0口电平(需配置为输入)或经过 ADC 转换后的数字值来判断。
  • 为了简化仿真,本文采用将滑动变阻器输出直接接P1.0,并在程序中将P1.0配置为高阻输入,通过读取P1端口值来获取模拟量(0-255)。实物中必须使用 ADC 芯片(如 ADC0808/PCF8591)或单片机内部 ADC(如果选用带 ADC 的单片机如 STC12C5A60S2)来处理 MQ-2 的模拟信号。

5. 报警模块:

  • 报警 LED 接P2.6,串联一个 220Ω 限流电阻到地。
  • 蜂鸣器(有源)接P2.7。有源蜂鸣器高电平驱动,无源蜂鸣器需要 PWM 驱动。

4.2 在 Proteus 中绘制原理图

  1. 打开 Proteus ISIS,新建一个设计。
  2. 从元件库中依次添加所有需要的元件。
  3. 按照上述设计连接电路。一个参考的连接方式如下:
    • LCD1602:RS-P2.0,RW-P2.1,E-P2.2,D0-D7->P0.0-P0.7
    • DS18B20:DQ-P3.7
    • MQ-2模拟输入:POT-HG滑动端 ->P1.0
    • LED:P2.6
    • BUZZER:P2.7
  4. P0口添加一个RESPACK-8上拉排阻。
  5. 放置电源 (POWER) 和地 (GROUND) 符号,并正确连接。
  6. 最终绘制完成的原理图应该是一个闭合的、可工作的电路。务必检查VCCGND是否连接到所有需要供电的元件。

5. 软件编程与代码解析

电路是躯干,程序是灵魂。下面我们分模块编写驱动代码和主控逻辑。

5.1 工程创建与头文件

  1. 打开 Keil uVision5,新建一个Project,选择STC MCU Database中的STC89C52RC
  2. 新建main.clcd1602.clcd1602.hds18b20.cds18b20.hdelay.cdelay.h等文件,并添加到工程中。
  3. main.c中包含必要的头文件。
// main.c #include <reg52.h> // 51单片机头文件 #include “lcd1602.h” #include “ds18b20.h” #include “delay.h” // 宏定义引脚 sbit LED_Alarm = P2^6; // 报警LED sbit BUZZER = P2^7; // 蜂鸣器 sbit MQ2_IN = P1^0; // MQ-2模拟输入(简化处理) // 报警阈值 #define TEMP_THRESHOLD 50 // 温度阈值 50°C #define SMOKE_THRESHOLD 150 // 烟雾浓度阈值 (0-255模拟量范围) // 全局变量 unsigned char Temp_Value = 0; // 温度值 unsigned char Smoke_Value = 0; // 烟雾浓度值 bit Alarm_Flag = 0; // 报警标志位

5.2 LCD1602 驱动模块

LCD1602 的驱动是标准代码,需要实现初始化、写命令、写数据、清屏、显示字符串等功能。

// lcd1602.h #ifndef __LCD1602_H__ #define __LCD1602_H__ void LCD_Init(void); void LCD_WriteCmd(unsigned char cmd); void LCD_WriteData(unsigned char dat); void LCD_Clear(void); void LCD_SetCursor(unsigned char line, unsigned char column); void LCD_ShowStr(unsigned char line, unsigned char column, unsigned char *str); #endif
// lcd1602.c #include “lcd1602.h” #include “delay.h” // 引脚定义,根据你的原理图连接修改 sbit LCD_RS = P2^0; sbit LCD_RW = P2^1; sbit LCD_E = P2^2; #define LCD_DataPort P0 // 写命令函数 void LCD_WriteCmd(unsigned char cmd) { LCD_RS = 0; LCD_RW = 0; LCD_DataPort = cmd; LCD_E = 1; DelayMs(2); LCD_E = 0; DelayMs(2); } // ... 其他函数实现(写数据、初始化、清屏、设置光标、显示字符串) // 具体实现代码较长,此处省略,可参考标准51单片机LCD1602驱动库。

5.3 DS18B20 温度读取模块

DS18B20 的驱动关键在于精确的延时函数以满足单总线时序。

// ds18b20.h #ifndef __DS18B20_H__ #define __DS18B20_H__ unsigned int DS18B20_ReadTemp(void); // 读取温度值 #endif
// ds18b20.c #include “ds18b20.h” #include “delay.h” sbit DQ = P3^7; // 数据线引脚 // DS18B20初始化(存在检测) bit DS18B20_Init(void) { bit flag; DQ = 1; DelayUs(2); DQ = 0; DelayUs(500); // 拉低480us以上 DQ = 1; DelayUs(60); // 释放总线,等待15-60us flag = DQ; // 读取存在脉冲 DelayUs(240); return flag; // 0:存在,1:不存在 } // 从DS18B20读一个字节 unsigned char DS18B20_ReadByte(void) { unsigned char i, dat = 0; for(i=0; i<8; i++) { DQ = 0; _nop_(); _nop_(); // 拉低开始读时序 DQ = 1; DelayUs(2); // 释放总线 dat >>= 1; if(DQ) dat |= 0x80; DelayUs(60); // 等待读时序结束 } return dat; } // 向DS18B20写一个字节 void DS18B20_WriteByte(unsigned char dat) { unsigned char i; for(i=0; i<8; i++) { DQ = 0; _nop_(); _nop_(); // 拉低开始写时序 DQ = dat & 0x01; // 发送最低位 DelayUs(60); // 保持60us DQ = 1; dat >>= 1; // 释放总线,准备下一位 DelayUs(2); } } // 读取温度值 unsigned int DS18B20_ReadTemp(void) { unsigned int temp = 0; unsigned char LSB, MSB; if(DS18B20_Init() == 0) { // 检测到器件 DS18B20_WriteByte(0xCC); // 跳过ROM DS18B20_WriteByte(0x44); // 启动温度转换 DelayMs(750); // 等待转换完成,12位精度需750ms DS18B20_Init(); DS18B20_WriteByte(0xCC); // 跳过ROM DS18B20_WriteByte(0xBE); // 读暂存器 LSB = DS18B20_ReadByte(); // 低字节 MSB = DS18B20_ReadByte(); // 高字节 temp = MSB; temp <<= 8; temp |= LSB; } return temp; // 返回16位原始数据 }

5.4 主程序逻辑

主程序负责协调各个模块,循环读取传感器数据,判断是否超限,并控制显示和报警。

// main.c 主函数部分 void main() { unsigned int temp_raw; unsigned char temp_display, smoke_display; unsigned char disp_buf[16]; LCD_Init(); // 初始化液晶 LCD_Clear(); LCD_ShowStr(0, 0, “Temp: C“); LCD_ShowStr(1, 0, “Smoke: “); while(1) { // 1. 读取温度 temp_raw = DS18B20_ReadTemp(); // DS18B20返回的是16位有符号整数,低4位是小数部分 // 简单处理:取整数部分 (temp_raw >> 4) Temp_Value = (unsigned char)(temp_raw >> 4); // 2. 读取烟雾浓度(简化:读取P1.0口模拟电压对应的数字值) // 注意:P1口需先写0xFF使其为高阻输入状态 P1 = 0xFF; Smoke_Value = P1 & 0x01; // 仅读取P1.0,实际可扩展为8位ADC值 // 在仿真中,我们用滑动变阻器模拟,这里假设Smoke_Value是0-255的值 // 为了演示,我们用一个变量模拟变化,实际应从ADC读取 static unsigned char sim_smoke = 100; sim_smoke++; if(sim_smoke > 200) sim_smoke = 100; Smoke_Value = sim_smoke; // 3. 判断报警条件 if((Temp_Value > TEMP_THRESHOLD) || (Smoke_Value > SMOKE_THRESHOLD)) { Alarm_Flag = 1; LED_Alarm = 0; // 低电平点亮LED BUZZER = 0; // 低电平驱动有源蜂鸣器 } else { Alarm_Flag = 0; LED_Alarm = 1; BUZZER = 1; } // 4. 更新LCD显示 // 显示温度 sprintf(disp_buf, “%3d”, Temp_Value); // 需要包含 stdio.h LCD_SetCursor(0, 6); LCD_ShowStr(0, 6, disp_buf); // 显示烟雾浓度 sprintf(disp_buf, “%4d”, Smoke_Value); LCD_SetCursor(1, 7); LCD_ShowStr(1, 7, disp_buf); // 显示报警状态 LCD_SetCursor(1, 12); if(Alarm_Flag) { LCD_ShowStr(1, 12, “ALARM“); } else { LCD_ShowStr(1, 12, “SAFE “); } DelayMs(500); // 延时500ms,控制刷新频率 } }

6. Proteus 仿真与调试

代码编写完成后,下一步就是在 Proteus 中加载程序并进行仿真,这是验证逻辑是否正确的最关键一步。

  1. 编译生成 HEX 文件

    • 在 Keil 中,确保Options for Target->Output中勾选了Create HEX File
    • 点击Rebuild编译工程。如果没有错误,会在工程目录下生成.hex文件。
  2. 在 Proteus 中加载程序

    • 回到 Proteus 原理图界面。
    • 双击原理图中的AT89C52(或STC89C52)单片机元件,会弹出属性编辑框。
    • Program File一栏,点击文件夹图标,选择刚才 Keil 生成的.hex文件。
    • Clock Frequency设置为12MHz(与你的晶振频率一致)。
    • 点击OK
  3. 运行仿真

    • 点击 Proteus 界面左下角的Play(运行) 按钮。
    • 观察 LCD1602 显示屏是否点亮并显示初始信息 “Temp: C” 和 “Smoke:”。
    • DS18B20 元件上可能会显示一个默认温度(如 +85°C),你可以双击 DS18B20 元件,在属性中修改Current Temperature值来模拟温度变化。
    • 找到代表 MQ-2 模拟输入的滑动变阻器 (POT-HG)。在仿真运行时,用鼠标点击并拖动滑动变阻器上的箭头,改变其阻值,从而改变输入到P1.0口的电压(模拟烟雾浓度变化)。
  4. 功能验证

    • 正常状态:当 DS18B20 温度低于 50°C,且滑动变阻器输出值(对应Smoke_Value)低于 150 时,LCD 应显示 “SAFE”,LED 熄灭,蜂鸣器静音。
    • 高温报警:双击 DS18B20,将温度设置为 55°C。观察 LCD 温度显示是否更新,同时报警状态是否变为 “ALARM”,LED 是否点亮,蜂鸣器是否响起。
    • 烟雾报警:将滑动变阻器调整到高位,使Smoke_Value超过 150。观察 LCD 烟雾值显示是否变化,并触发报警。
    • 报警解除:将温度和烟雾浓度都调回阈值以下,观察报警是否自动解除,显示恢复 “SAFE”。

仿真调试技巧:

  • 如果 LCD 不显示,检查P0口上拉电阻是否连接,VEE对比度调节是否合适,以及代码中 LCD 初始化时序是否正确。
  • 如果 DS18B20 温度读取始终为 0 或错误,检查单总线引脚连接、上拉电阻,以及ds18b20.c中的延时函数精度。Proteus 仿真对时序要求比实物宽松,但仍需基本正确。
  • 可以利用 Proteus 的Virtual Terminal(虚拟终端) 连接到单片机的串口,在代码中添加printf语句打印调试信息,这是非常有效的排查手段。

7. 实物制作与调试要点(进阶)

如果你打算将系统制作成实物,仿真成功只是第一步。实物调试会遇到更多问题。

  1. 元器件采购与焊接

    • STC89C52 单片机(或开发板)、LCD1602、DS18B20、MQ-2、有源蜂鸣器、LED、电阻、电容、晶振、排针、杜邦线、万用板或洞洞板。
    • 注意:MQ-2 传感器需要预热几分钟才能稳定输出。实物连接时,AO引脚必须连接到 ADC 转换芯片或带 ADC 的单片机引脚。
  2. 程序烧录

    • 使用 USB-TTL 串口模块(如 CH340、CP2102)连接电脑和单片机的P3.0(RXD) 和P3.1(TXD)。
    • 打开 STC-ISP 软件,选择正确的单片机型号、串口号。
    • 打开编译好的.hex文件,点击“下载/编程”按钮,然后给单片机上电(冷启动),等待烧录完成。
  3. 常见实物问题排查

    • LCD1602 显示乱码或黑块:首先调节VEE对比度电压。检查RS,RW,E控制线连接是否与代码定义一致。确保P0口上拉电阻有效(通常用 10kΩ 排阻)。
    • DS18B20 读取失败:检查DQ线是否接了 4.7kΩ 上拉电阻。检查代码中的延时函数,实物对微秒级延时精度要求更高,建议使用定时器产生精确延时或使用经过验证的延时函数库。尝试降低 DS18B20 的通信速率(使用更宽松的延时)。
    • MQ-2 数值不变或不准:确认AO引脚连接到了 ADC 输入。检查 ADC 参考电压是否稳定。MQ-2 需要通电预热。在代码中实现软件滤波(如多次采样取平均)以消除抖动。
    • 蜂鸣器不响:确认是有源蜂鸣器(给高/低电平就响)还是无源蜂鸣器(需要 PWM 驱动)。检查驱动三极管或集成电路是否工作正常。
    • 系统不稳定:检查电源是否充足(5V/1A 以上),所有GND是否共地良好。在单片机VCCGND之间靠近引脚处加一个 10uF 电解电容和一个 0.1uF 瓷片电容进行电源滤波。

8. 功能扩展与优化建议

基础系统完成后,你可以考虑以下方向进行扩展,这会让你的项目更具挑战性和实用性:

  1. 增加实时时钟 (RTC):添加 DS1302 或 PCF8563 芯片,在 LCD 上显示当前时间,并记录报警发生的时间点。
  2. 增加数据存储:使用 AT24C02 等 EEPROM 芯片,存储历史报警记录或温度阈值。
  3. 增加无线通信:添加 ESP8266 Wi-Fi 模块或 HC-05 蓝牙模块,将报警信息和传感器数据发送到手机 APP 或电脑上位机,实现远程监控。
  4. 改进烟雾检测:使用真正的 ADC 芯片(如 ADC0808)读取 MQ-2 的模拟量,并编写更精确的浓度-电压换算程序。
  5. 增加手动布防/撤防:添加按键,允许管理员在安全检查后手动关闭报警系统。
  6. 多级报警:区分预警(闪烁黄灯)和火警(红灯常亮+蜂鸣器),例如温度超过 45°C 预警,超过 60°C 或烟雾浓度超高时火警。
  7. 上位机软件:使用 C#、Python 或 LabVIEW 编写一个简单的上位机,通过串口接收数据,绘制温度/烟雾浓度曲线图。

9. 项目总结与资源获取

这个“木材仓库火灾报警系统”项目,完整地走通了从需求分析、硬件选型、电路设计、软件编程到仿真验证的嵌入式系统开发全流程。它的价值在于提供了一个清晰、可复现的模板,你可以基于此模板,替换不同的传感器(如湿度传感器 DHT11、火焰传感器)和执行器(如继电器控制排风扇、电磁阀控制喷水),快速构建其他类型的监测控制系统。

最值得尝试的点

  • 模块化编程:将 LCD、DS18B20 驱动写成独立的.c/.h文件,主程序逻辑清晰,便于调试和移植。
  • Proteus 仿真先行:在焊接实物前,用仿真验证了核心逻辑,节省了大量时间和物料成本。
  • 报警逻辑直观:通过简单的阈值比较实现报警,易于理解和修改。

最先应该验证的功能

  1. LCD1602 能否正常显示静态字符。
  2. DS18B20 能否在 Proteus 中读取并显示变化的温度值。
  3. 通过滑动变阻器模拟的烟雾信号,能否触发报警。

最容易踩的坑

  1. 时序问题:DS18B20 和 LCD1602 的驱动对延时很敏感,务必使用经过测试的延时函数。
  2. 端口配置:读 DS18B20 或 MQ-2 模拟口时,要先将端口设置为高阻输入(写1)。
  3. 电源与接地:实物中电源不稳定或地线虚接是导致各种诡异问题的首要原因。

下一步: 你可以尝试将仿真成功的代码烧录到真正的 STC89C52 开发板上,连接实物传感器进行测试。在这个过程中,你会深刻体会到仿真与实物的差异,并学会使用万用表、逻辑分析仪等工具进行调试,这才是嵌入式工程师真正的成长之路。相关的完整源码、Proteus 仿真文件、元件清单,通常可以在一些开源硬件平台或电子技术论坛找到,搜索“STC89C52 火灾报警 Proteus 仿真”即可。建议在理解本文思路的基础上,自己动手从头构建一遍,收获会更大。

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

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

立即咨询