基于51单片机的温度-火灾-烟雾报警器设计

基于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→各模块     |  
+-------------------+          +-------------------+          +-------------------+

关键说明

三、软件设计(Keil C51)

3.1 开发环境

3.2 核心原理

  1. 数据采集

    • 温度:DS18B20单总线协议读取,转换为实际温度(℃);
    • 烟雾浓度:ADC0832采集MQ-2模拟量,转换为0~100%相对浓度;
    • 火焰:读取P3.6电平(0=检测到火焰,1=正常)。
  2. 阈值判断

    • 温度>50℃ 烟雾浓度>60% 火焰检测到 → 触发报警;
  3. 报警控制:蜂鸣器鸣叫、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

四、测试与验证

  1. 硬件连接:按2.2节连接传感器、执行模块,确保电源稳定(5V/2A)。

  2. 功能测试

    • 加热DS18B20至50℃以上,观察是否触发声光报警;
    • 用烟雾(如蚊香烟雾)靠近MQ-2,观察浓度显示及报警;
    • 用打火机火焰靠近火焰传感器,观察是否触发报警。
  3. 误报率测试:在无干扰环境中连续运行24小时,误报次数<1次。

五、总结

基于51单片机实现了温度-火灾-烟雾三参数报警,核心是多传感器数据采集、阈值判断与联动控制。通过DS18B20、MQ-2、火焰传感器的组合,覆盖了火灾发生的主要特征(高温、烟雾、明火),可扩展GSM短信报警或WiFi远程通知功能,提升实用性。

专注于matlab/simulink,电子电路,编程