基于51单片机的温度-火灾-烟雾报警器设计
一、系统概述
以STC89C52RC单片机(8位,11.0592MHz晶振)为核心,集成温度、烟雾、火焰三参数检测功能,通过多传感器融合与阈值判断实现火灾早期预警。系统支持实时数据显示、声光报警、继电器联动控制(如启动灭火装置),具备低功耗、易部署特点,适用于家庭、仓库、机房等场景。
二、硬件设计
2.1 核心组件选型
| 模块 | 型号/参数 | 功能说明 |
|---|---|---|
| 主控 | STC89C52RC(8KB Flash,512B RAM) | 传感器数据采集、阈值判断、报警控制 |
| 温度传感器 | DS18B20(单总线,数字输出) | 检测环境温度(-55~125℃,精度±0.5℃) |
| 烟雾传感器 | MQ-2(模拟输出,检测液化气/烟雾) | 检测烟雾浓度(0~5V模拟量,阈值可调) |
| 火焰传感器 | 红外火焰传感器(数字输出,检测760~1100nm) | 检测火焰(输出低电平表示检测到火焰) |
| 显示模块 | LCD1602(16×2字符型液晶) | 显示温度、烟雾浓度、报警状态 |
| 报警模块 | 有源蜂鸣器(5V)+ 红色LED | 声光报警(异常时触发) |
| 联动模块 | 5V继电器(10A/250VAC) | 控制外部设备(如风扇、喷淋装置) |
| ADC转换 | ADC0832(8位串行ADC) | 将MQ-2模拟量转换为数字量(0~255) |
2.2 硬件连接图
+-------------------+ +-------------------+ +-------------------+
| STC89C52RC | | 传感器模块 | | 执行模块 |
| P3.7 → DS18B20(DQ) | | DS18B20: VCC→5V, GND→GND | | 蜂鸣器→P1.0 |
| P1.3 → ADC0832(CS) |←→ | MQ-2: AO→ADC0832(CH0) | | LED→P1.1 |
| P1.4 → ADC0832(CLK)| | 火焰传感器: DO→P3.6 | | 继电器→P1.2 |
| P3.6 → 火焰传感器(DO) | | 所有传感器GND→GND | +-------------------+
| P0口 → LCD1602(D0~D7) | +-------------------+ +-------------------+
| P2.0→RS, P2.1→RW, P2.2→E | | ADC0832: VCC→5V, GND→GND | | 电源模块 |
| P1.0→蜂鸣器, P1.1→LED | | 火焰传感器: VCC→5V | | 5V/2A DC→各模块 |
+-------------------+ +-------------------+ +-------------------+
关键说明:
- DS18B20:单总线通信,需4.7kΩ上拉电阻;
- MQ-2:模拟输出经ADC0832转换为数字量(0255对应05V);
- 火焰传感器:数字输出(检测到火焰时DO=0,正常时DO=1)。
三、软件设计(Keil C51)
3.1 开发环境
- IDE:Keil μVision5(C51编译器)
- 晶振:11.0592MHz(确保延时精度与串口兼容性)
- 通信协议:DS18B20单总线、ADC0832串行ADC
3.2 核心原理
-
数据采集:
- 温度:DS18B20单总线协议读取,转换为实际温度(℃);
- 烟雾浓度:ADC0832采集MQ-2模拟量,转换为0~100%相对浓度;
- 火焰:读取P3.6电平(0=检测到火焰,1=正常)。
-
阈值判断:
- 温度>50℃ 或 烟雾浓度>60% 或 火焰检测到 → 触发报警;
-
报警控制:蜂鸣器鸣叫、LED闪烁、继电器吸合(联动外部设备)。
3.3 核心代码实现
3.3.1 头文件与引脚定义
#include <reg52.h>
#include <intrins.h>
// ==================== 引脚定义 ====================
// DS18B20(单总线)
sbit DQ = P3^7;
// ADC0832(烟雾传感器)
sbit ADC_CS = P1^3;
sbit ADC_CLK = P1^4;
sbit ADC_DO = P1^5;
// 火焰传感器
sbit FLAME_SENSOR = P3^6;
// 执行模块
sbit BUZZER = P1^0; // 蜂鸣器
sbit ALARM_LED = P1^1; // 报警LED
sbit RELAY = P1^2; // 继电器(联动设备)
// LCD1602
sbit LCD_RS = P2^0;
sbit LCD_RW = P2^1;
sbit LCD_E = P2^2;
#define LCD_DB P0 // 数据总线
3.3.2 延时函数(微秒/毫秒级)
// 微秒延时(11.0592MHz,1us≈12机器周期)
void DelayUs(unsigned int us) {
while (us--) {
_nop_(); _nop_(); _nop_(); _nop_(); // 4个_nop_≈3.6us
}
}
// 毫秒延时
void DelayMs(unsigned int ms) {
unsigned int i, j;
for (i=0; i<ms; i++)
for (j=0; j<110; j++); // 110次循环≈1ms
}
3.3.3 DS18B20温度采集
// DS18B20初始化
bit DS18B20_Init() {
bit ack;
DQ = 1; DelayUs(2);
DQ = 0; DelayUs(500); // 复位脉冲(480~960us)
DQ = 1; DelayUs(60); // 释放总线
ack = DQ; DelayUs(420);
return !ack; // 1=设备存在
}
// 读1字节
unsigned char DS18B20_ReadByte() {
unsigned char i, dat = 0;
for (i=0; i<8; i++) {
DQ = 0; _nop_(); // 拉低总线
dat >>= 1;
DQ = 1; _nop_();
if (DQ) dat |= 0x80;
DelayUs(60);
}
return dat;
}
// 读取温度(℃)
float DS18B20_ReadTemp() {
unsigned char temp_l, temp_h;
if (!DS18B20_Init()) return -99; // 初始化失败
DS18B20_WriteByte(0xCC); // 跳过ROM
DS18B20_WriteByte(0x44); // 启动转换
DelayMs(750); // 等待转换完成
DS18B20_Init();
DS18B20_WriteByte(0xCC);
DS18B20_WriteByte(0xBE); // 读暂存器
temp_l = DS18B20_ReadByte(); // 低8位
temp_h = DS18B20_ReadByte(); // 高8位
return (temp_h << 8 | temp_l) * 0.0625; // 12位精度,0.0625℃/LSB
}
3.3.4 ADC0832烟雾浓度采集
// 读ADC0832(通道0)
unsigned char ADC0832_Read() {
unsigned char i, dat = 0;
ADC_CS = 0; // 片选使能
ADC_CLK = 0;
// 发送通道选择(CH0:起始位+1位通道号)
ADC_DO = 1; _nop_(); ADC_CLK = 1; _nop_(); ADC_CLK = 0; // 起始位
ADC_DO = 0; _nop_(); ADC_CLK = 1; _nop_(); ADC_CLK = 0; // CH0
// 读8位数据
for (i=0; i<8; i++) {
ADC_CLK = 1; _nop_();
dat <<= 1;
if (ADC_DO) dat |= 0x01;
ADC_CLK = 0; _nop_();
}
ADC_CS = 1; // 片选禁用
return dat; // 0~255(对应0~5V)
}
3.3.5 LCD1602显示
// LCD写命令
void LCD_WriteCmd(unsigned char cmd) {
LCD_RS = 0; LCD_RW = 0;
LCD_DB = cmd; DelayUs(5);
LCD_E = 1; DelayUs(5); LCD_E = 0;
}
// LCD写数据
void LCD_WriteData(unsigned char dat) {
LCD_RS = 1; LCD_RW = 0;
LCD_DB = dat; DelayUs(5);
LCD_E = 1; DelayUs(5); LCD_E = 0;
}
// 显示温度、烟雾浓度
void LCD_Display(float temp, unsigned char smoke) {
char buf[16];
LCD_WriteCmd(0x80); // 第一行
sprintf(buf, "T:%.1fC S:%d%%", temp, smoke);
for (char i=0; buf[i]; i++) LCD_WriteData(buf[i]);
// 第二行显示报警状态
LCD_WriteCmd(0xC0);
if (temp > 50 || smoke > 60 || !FLAME_SENSOR) {
LCD_WriteData('A'); LCD_WriteData('L'); LCD_WriteData('A'); LCD_WriteData('R'); LCD_WriteData('M');
} else {
LCD_WriteData('N'); LCD_WriteData('O'); LCD_WriteData('R'); LCD_WriteData('M'); LCD_WriteData('A'); LCD_WriteData('L');
}
}
3.3.6 主函数(报警逻辑)
void main() {
float temp;
unsigned char smoke;
LCD_Init(); // 初始化LCD(省略LCD_Init函数,参考前文)
while (1) {
// 1. 采集数据
temp = DS18B20_ReadTemp();
smoke = ADC0832_Read() * 100 / 255; // 转换为0~100%
// 2. 显示数据
LCD_Display(temp, smoke);
// 3. 报警判断
if (temp > 50 || smoke > 60 || FLAME_SENSOR == 0) { // 异常条件
BUZZER = 1; // 蜂鸣器响
ALARM_LED = ~ALARM_LED; // LED闪烁
RELAY = 1; // 继电器吸合(启动联动设备)
} else {
BUZZER = 0;
ALARM_LED = 1; // LED灭
RELAY = 0; // 继电器释放
}
DelayMs(1000); // 1秒刷新一次
}
}
参考代码 51单片机助力温度火灾烟雾报警器 www.youwenfan.com/contentcst/182122.html
四、测试与验证
-
硬件连接:按2.2节连接传感器、执行模块,确保电源稳定(5V/2A)。
-
功能测试:
- 加热DS18B20至50℃以上,观察是否触发声光报警;
- 用烟雾(如蚊香烟雾)靠近MQ-2,观察浓度显示及报警;
- 用打火机火焰靠近火焰传感器,观察是否触发报警。
-
误报率测试:在无干扰环境中连续运行24小时,误报次数<1次。
五、总结
基于51单片机实现了温度-火灾-烟雾三参数报警,核心是多传感器数据采集、阈值判断与联动控制。通过DS18B20、MQ-2、火焰传感器的组合,覆盖了火灾发生的主要特征(高温、烟雾、明火),可扩展GSM短信报警或WiFi远程通知功能,提升实用性。