基于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→各模块 |
+-------------------+
关键说明:
- GP2Y1010AU0F:需串联一个150Ω电阻和220μF电容滤波,模拟输出电压与PM2.5浓度关系约为 Vout(V) = 0.17×C(μg/m³) + 0.5(C为浓度);
- ADC0832:8位分辨率,0255对应05V,需软件实现串行读取;
- HC-05:默认波特率9600bps,通过AT指令可配置为主/从模式(本设计设为从机,手机APP为主机)。
三、软件设计(Keil C51)
3.1 开发环境
- IDE:Keil μVision5(C51编译器)
- 晶振:11.0592MHz(确保串口波特率误差<1%)
- 通信协议:蓝牙串口透传(手机APP发送指令,单片机返回数据)、DHT11单总线协议、ADC0832串行协议
3.2 核心原理
-
数据采集:
- 温湿度:DHT11单总线协议读取(40位数据:16位湿度+16位温度+8位校验和);
- PM2.5:ADC0832采集GP2Y1010模拟输出,转换为电压后计算浓度(μg/m³);
-
阈值判断:对比采集值与预设上下限(温湿度、PM2.5),超限则触发报警;
-
蓝牙通信:通过串口发送数据到手机APP(格式:
T:25℃ H:50% P:35μg/m³ ALARM:0),接收APP设置的阈值; -
显示与报警: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
四、测试与验证
-
硬件连接:按2.2节连接各模块,确保电源稳定(5V/2A),传感器接线正确(尤其GP2Y1010的滤波电路)。
-
功能测试:
- 用手捂住DHT11,观察温度升高、湿度上升,LCD显示变化,超限时报警;
- 用香烟烟雾靠近GP2Y1010,PM2.5浓度上升,超过75μg/m³时触发报警;
- 手机APP连接HC-05,接收数据并显示,发送阈值设置指令(如
SET:T20:30:H30:70:P75)。
五、总结
基于51单片机实现了蓝牙+PM2.5+DHT11的上下限报警系统,核心是多传感器数据采集、阈值判断与蓝牙通信。通过LCD1602本地显示和声光报警,结合手机APP远程监控,可实时掌握环境空气质量与温湿度状态,及时采取措施改善环境。