基于51单片机的蓝牙+PM2.5+DHT11温湿度上下限报警系统设计

基于51单片机的蓝牙+PM2.5+DHT11温湿度上下限报警系统设计

一、系统概述

设计以STC89C52RC单片机(11.0592MHz晶振)为核心,集成蓝牙通信(HC-05)、PM2.5空气质量检测(GP2Y1010AU0F)、DHT11温湿度检测三大模块,实现环境参数的实时采集、上下限报警与远程监控。系统支持本地显示(LCD1602)、声光报警(蜂鸣器+LED)和蓝牙数据传输(手机APP查看/设置阈值),适用于家庭、教室、办公室等场景的空气质量管理。

二、硬件设计

2.1 核心组件选型

模块 型号/参数 功能说明
主控 STC89C52RC(8KB Flash,512B RAM) 传感器数据采集、阈值判断、蓝牙通信、报警控制
蓝牙模块 HC-05(主从一体,蓝牙2.0) 与手机APP通信(串口透传,波特率9600bps)
PM2.5传感器 GP2Y1010AU0F(模拟输出,0.5V3.5V对应0500μg/m³) 检测PM2.5浓度(需ADC转换)
温湿度传感器 DHT11(单总线,数字输出) 检测温度(050℃,±2℃)、湿度(2090%RH,±5%RH)
ADC转换 ADC0832(8位串行ADC) 将PM2.5模拟量转换为数字量(0~255)
显示模块 LCD1602(16×2字符型液晶) 显示温湿度、PM2.5值、报警状态
报警模块 有源蜂鸣器(5V)+ 红色LED 超限时声光报警(蜂鸣器鸣叫,LED闪烁)
按键 3个轻触按键(设置/加/减) 设置温湿度/PM2.5上下限阈值
电源 5V/2A DC(USB供电或7805稳压) 为系统供电(传感器、蓝牙、LCD均需5V)

2.2 硬件连接图

+-------------------+          +-------------------+          +-------------------+  
|   STC89C52RC       |          |   传感器模块       |          |   执行模块         |  
|  P3.0(RXD) ← HC-05|TXD         | DHT11: DATA→P3.7    |          | 蜂鸣器→P2.3         |  
|  P3.1(TXD) → HC-05|RXD         | GP2Y1010: AO→ADC0832(CH0) |          | LED→P2.4            |  
|  P1.0→ADC0832(CS)  |←→        | ADC0832: VCC→5V, GND→GND |          +-------------------+  
|  P1.1→ADC0832(CLK) |          | 蓝牙HC-05: VCC→5V, GND→GND |          +-------------------+  
|  P1.2→ADC0832(DO)  |          | LCD1602: RS→P2.0, RW→P2.1, E→P2.2 |        |    按键模块        |  
|  P3.7→DHT11(DATA)  |          |          D0~D7→P0口        |          | 设置→P3.2, 加→P3.3, 减→P3.4 |  
|  P2.0~P2.2→LCD1602 |          +-------------------+          +-------------------+  
|  P0口→LCD1602(D0~D7) |          |   HC-05: STATE→P3.5(状态指示) |          +-------------------+  
+-------------------+          +-------------------+          |    电源模块        |  
                                                               | 5V/2A→各模块        |  
                                                               +-------------------+

关键说明

三、软件设计(Keil C51)

3.1 开发环境

3.2 核心原理

  1. 数据采集

    • 温湿度:DHT11单总线协议读取(40位数据:16位湿度+16位温度+8位校验和);
    • PM2.5:ADC0832采集GP2Y1010模拟输出,转换为电压后计算浓度(μg/m³);
  2. 阈值判断:对比采集值与预设上下限(温湿度、PM2.5),超限则触发报警;

  3. 蓝牙通信:通过串口发送数据到手机APP(格式:T:25℃ H:50% P:35μg/m³ ALARM:0),接收APP设置的阈值;

  4. 显示与报警:LCD1602实时显示参数,超限时蜂鸣器鸣叫、LED闪烁。

3.3 核心代码实现

3.3.1 头文件与引脚定义

#include <reg52.h>
#include <intrins.h>
#include <string.h>

// ==================== 引脚定义 ====================
// 蓝牙模块(HC-05)
#define BLUETOOTH_RXD P3_0  // 单片机RXD(接HC-05 TXD)
#define BLUETOOTH_TXD P3_1  // 单片机TXD(接HC-05 RXD)

// ADC0832(PM2.5传感器)
sbit ADC_CS = P1^0;
sbit ADC_CLK = P1^1;
sbit ADC_DO = P1^2;

// DHT11(温湿度)
sbit DHT11_DATA = P3^7;

// LCD1602
sbit LCD_RS = P2^0;
sbit LCD_RW = P2^1;
sbit LCD_E = P2^2;
#define LCD_DB P0  // 数据总线

// 报警模块
sbit BUZZER = P2^3;  // 蜂鸣器
sbit ALARM_LED = P2^4;  // 报警LED

// 按键(设置/加/减)
sbit KEY_SET = P3^2;
sbit KEY_ADD = P3^3;
sbit KEY_SUB = P3^4;

// ==================== 全局变量 ====================
unsigned char temp = 0, humi = 0;  // DHT11温湿度(整数)
unsigned char pm25_adc = 0;        // PM2.5的ADC值(0~255)
float pm25_conc = 0;               // PM2.5浓度(μg/m³)
// 阈值(默认:温度20~30℃,湿度30~70%RH,PM2.5 0~75μg/m³)
unsigned char temp_min = 20, temp_max = 30;
unsigned char humi_min = 30, humi_max = 70;
unsigned char pm25_max = 75;       // PM2.5通常只设上限
bit alarm_flag = 0;                // 报警标志(1=超限)

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 DHT11温湿度读取

// DHT11初始化(检测设备)
bit DHT11_Init() {
    DHT11_DATA = 1; DelayUs(30);
    DHT11_DATA = 0; DelayMs(20);  // 主机拉低18ms以上
    DHT11_DATA = 1; DelayUs(30);  // 释放总线
    if (!DHT11_DATA) {  // 等待DHT11响应(拉低80us)
        while (!DHT11_DATA);  // 等待响应结束
        while (DHT11_DATA);   // 等待DHT11准备数据
        return 1;  // 初始化成功
    }
    return 0;  // 初始化失败
}

// 读取DHT11数据(返回0成功,1失败)
bit DHT11_ReadData() {
    unsigned char i, buf[5] = {0};
    if (!DHT11_Init()) return 1;
    // 读取40位数据(5字节)
    for (i=0; i<40; i++) {
        while (!DHT11_DATA);  // 等待低电平(50us)
        DelayUs(30);  // 延时30us判断高电平持续时间
        buf[i/8] <<= 1;
        if (DHT11_DATA) buf[i/8] |= 1;  // 高电平>30us表示1
        while (DHT11_DATA);  // 等待高电平结束
    }
    // 校验和验证(前4字节和=第5字节)
    if (buf[4] == (buf[0]+buf[1]+buf[2]+buf[3])) {
        humi = buf[0];  // 湿度整数部分
        temp = buf[2];  // 温度整数部分
        return 0;
    }
    return 1;
}

3.3.4 ADC0832 PM2.5采集

// 读取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位数据(MSB first)
    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)
}

// ADC值转换为PM2.5浓度(μg/m³)
float ADC_to_PM25(unsigned char adc_val) {
    float voltage = adc_val * 5.0 / 255.0;  // 转换为电压(V)
    return (voltage - 0.5) / 0.17;  // 公式:C=(Vout-0.5)/0.17(GP2Y1010特性)
}

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;
}

// LCD初始化
void LCD_Init() {
    LCD_WriteCmd(0x38);  // 8位数据,2行显示
    LCD_WriteCmd(0x0C);  // 开显示,关光标
    LCD_WriteCmd(0x06);  // 光标右移
    LCD_WriteCmd(0x01);  // 清屏
    DelayMs(2);
}

// 显示温湿度、PM2.5与报警状态
void LCD_Display() {
    char buf[16];
    // 第一行:温度、湿度
    LCD_WriteCmd(0x80);
    sprintf(buf, "T:%dC H:%d%%", temp, humi);
    for (char i=0; buf[i]; i++) LCD_WriteData(buf[i]);
    // 第二行:PM2.5、报警状态
    LCD_WriteCmd(0xC0);
    sprintf(buf, "P:%dug/m3 %s", (int)pm25_conc, alarm_flag ? "ALARM!" : "");
    for (char i=0; buf[i]; i++) LCD_WriteData(buf[i]);
}

3.3.6 报警控制与蓝牙通信

// 报警控制(超限时蜂鸣器鸣叫、LED闪烁)
void Alarm_Control() {
    alarm_flag = 0;
    // 温度超限(<min或>max)
    if (temp < temp_min || temp > temp_max) alarm_flag = 1;
    // 湿度超限(<min或>max)
    if (humi < humi_min || humi > humi_max) alarm_flag = 1;
    // PM2.5超限(>max)
    if (pm25_conc > pm25_max) alarm_flag = 1;

    if (alarm_flag) {
        BUZZER = ~BUZZER;  // 蜂鸣器翻转(鸣叫)
        ALARM_LED = ~ALARM_LED;  // LED闪烁
    } else {
        BUZZER = 0;  // 关闭蜂鸣器
        ALARM_LED = 1;  // LED熄灭
    }
}

// 蓝牙发送数据到手机APP
void Bluetooth_SendData() {
    char buf[50];
    sprintf(buf, "T:%dC,H:%d%%,P:%dμg/m3,ALARM:%d\r\n", temp, humi, (int)pm25_conc, alarm_flag);
    // 串口发送(需实现串口初始化)
    SBUF = buf[0]; while(!TI); TI=0;  // 发送第一个字符(示例,实际需循环发送整个字符串)
    // ...(省略后续字符发送,完整代码需遍历buf发送)
}

3.3.7 主函数(程序入口)

void main() {
    LCD_Init();       // 初始化LCD
    UART_Init();      // 初始化串口(蓝牙通信,9600bps)
    while (1) {
        // 1. 采集数据
        DHT11_ReadData();  // 读取温湿度
        pm25_adc = ADC0832_Read();  // 读取PM2.5的ADC值
        pm25_conc = ADC_to_PM25(pm25_adc);  // 转换为浓度

        // 2. 显示数据
        LCD_Display();

        // 3. 报警控制
        Alarm_Control();

        // 4. 蓝牙发送数据
        Bluetooth_SendData();

        // 5. 按键扫描(设置阈值,省略具体代码)
        Key_Scan();

        DelayMs(1000);  // 1秒刷新一次
    }
}

参考代码 基于51单片机 蓝牙+PM2.5空气质量+DHT11温湿度上下限报警的设计 www.youwenfan.com/contentcst/181691.html

四、测试与验证

  1. 硬件连接:按2.2节连接各模块,确保电源稳定(5V/2A),传感器接线正确(尤其GP2Y1010的滤波电路)。

  2. 功能测试

    • 用手捂住DHT11,观察温度升高、湿度上升,LCD显示变化,超限时报警;
    • 用香烟烟雾靠近GP2Y1010,PM2.5浓度上升,超过75μg/m³时触发报警;
    • 手机APP连接HC-05,接收数据并显示,发送阈值设置指令(如SET:T20:30:H30:70:P75)。

五、总结

基于51单片机实现了蓝牙+PM2.5+DHT11的上下限报警系统,核心是多传感器数据采集、阈值判断与蓝牙通信。通过LCD1602本地显示和声光报警,结合手机APP远程监控,可实时掌握环境空气质量与温湿度状态,及时采取措施改善环境。

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