基于 51 的环境监测系统的设计

摘要:本设计旨在构建一个基于 51 单片机的环境监测系统,以 AT89C52RC 作为主控芯片,结合 DC-002 电源、LCD1602 显示屏、独立按键、蜂鸣器与 LED 声光报警模块、MQ-2 烟雾传感器以及 DHT11 温湿度传感器,实现对环境烟雾浓度和温湿度的实时监测与预警。系统能够稳定运行,提供直观的显示界面,并通过按键实现阈值设置,当环境参数超出设定范围时,及时发出声光报警,为环境安全提供有效保障。

关键词:51 单片机;环境监测;AT89C52RC;LCD1602;MQ-2;DHT11

一、绪论

1.1 课题背景

随着人们对生活环境质量的关注度不断提高,对环境参数的实时监测需求也日益增长。环境中的烟雾浓度和温湿度等因素直接影响着人们的生活舒适度和健康安全。例如,高浓度的烟雾可能预示着火灾等危险情况的发生,而不适宜的温湿度环境则可能影响人们的身体健康和工作效率。因此,设计一款能够实时监测环境烟雾浓度和温湿度的系统具有重要的现实意义。

1.2 概述及功能介绍

1.2.1 功能概述

本环境监测系统以 AT89C52RC 单片机为核心,通过 MQ-2 烟雾传感器和 DHT11 温湿度传感器采集环境数据,将数据传输至单片机进行处理。处理后的数据通过 LCD1602 显示屏实时显示,用户可以通过独立按键修改烟雾和温湿度的阈值。当环境参数超过设定的阈值时,系统会触发蜂鸣器和 LED 发出声光报警,提醒用户及时采取措施。

1.2.2 功能介绍
  • 核心处理单元:AT89C52RC 单片机作为系统的核心,承担着至关重要的任务。它就像整个环境监测系统的“大脑”,负责接收来自 MQ-2 烟雾传感器和 DHT11 温湿度传感器采集的环境数据。这些数据以电信号的形式传输到单片机中,单片机凭借其内部强大的处理能力,对这些数据进行快速而精准的处理和判断。

在数据处理过程中,单片机要对传感器采集到的原始数据进行一系列操作,比如数据格式的转换、异常数据的剔除等。它需要根据预设的算法和逻辑,分析当前环境中的烟雾浓度、温度和湿度是否处于正常范围。一旦判断出数据超出设定的阈值,单片机就会迅速做出反应,向相应的控制模块发出指令。

根据判断结果,单片机控制显示屏显示模块,将处理后的数据清晰地展示在 LCD1602 显示屏上,让用户能够直观地了解当前环境的烟雾浓度和温湿度值,以及自己设置的阈值信息。同时,它还会控制报警模块的工作,当环境参数超过设定的阈值时,触发蜂鸣器和 LED 发出声光报警,及时提醒用户注意环境安全。

  • 电源供应:DC-002 电源为系统提供稳定的直流电源,确保系统各模块能够正常工作。
  • 信息显示:LCD1602 显示屏用于显示当前环境的烟雾浓度和温湿度值,以及用户设置的阈值信息,使用户能够直观地了解环境状况。
  • 按键操作:独立按键用于实现用户与系统的交互,用户可以通过按键修改烟雾和温湿度的阈值,满足不同环境下的监测需求。
  • 声光报警:当环境中的烟雾浓度或温湿度超过设定的阈值时,蜂鸣器发出声音报警,LED 灯闪烁,及时提醒用户注意环境安全。
  • 环境检测:MQ-2 烟雾传感器能够检测空气中的烟雾浓度,DHT11 温湿度传感器可以实时测量空气中的温度和湿度,为系统提供准确的环境数据。

1.3 本课题的研究思路

1.3.1 研究意义

本课题的研究成果可以广泛应用于家庭、办公室、工厂等各种场所,为用户提供实时的环境监测和预警服务。通过及时发现环境中的异常情况,可以有效避免火灾等安全事故的发生,保障人们的生命财产安全,同时提高人们的生活和工作舒适度。

1.3.2 研究思路
  • 硬件选型:根据系统功能需求,选择合适的单片机、传感器、显示屏、按键、报警模块和电源等硬件设备。
  • 电路设计:设计系统的硬件电路,包括单片机最小系统电路、传感器接口电路、显示屏接口电路、按键电路、报警电路和电源电路等,确保各模块之间能够正常连接和通信。
  • 软件编程:编写单片机的控制程序,实现传感器数据的采集、处理、显示和报警功能。同时,设计按键处理程序,使用户能够方便地修改阈值设置。
  • 系统调试:对硬件电路和软件程序进行调试,检查系统是否能够正常工作,各项功能是否符合设计要求。对发现的问题及时进行修改和优化,确保系统的稳定性和可靠性。
1.3.3 研究难点
  • 传感器数据的准确采集和处理:MQ-2 烟雾传感器和 DHT11 温湿度传感器的输出信号可能受到环境因素的影响,需要进行有效的滤波和校准处理,以提高数据的准确性。
  • 按键的防抖处理:独立按键在按下和释放过程中可能会产生抖动信号,影响按键的识别和处理。需要采用合适的软件或硬件方法进行防抖处理,确保按键操作的准确性。
  • 系统的稳定性和可靠性:环境监测系统需要长时间稳定运行,因此需要考虑系统的抗干扰能力和可靠性。在硬件设计和软件编程中,采取相应的措施,如添加滤波电容、优化程序结构等,提高系统的稳定性和可靠性。

1.4 主要工作

  • 完成系统的硬件选型和电路设计,绘制电路原理图和 PCB 图。
  • 编写单片机的控制程序,实现传感器数据的采集、处理、显示和报警功能,以及按键处理程序。
  • 对硬件电路进行焊接和调试,确保各模块能够正常工作。
  • 将软件程序下载到单片机中,进行系统联调,检查系统是否能够实现各项功能。
  • 对系统进行测试和优化,提高系统的性能和稳定性。

二、系统方案设计

2.1 系统构成

本环境监测系统主要由 AT89C52RC 单片机、MQ-2 烟雾传感器、DHT11 温湿度传感器、LCD1602 显示屏、独立按键、蜂鸣器、LED 灯和 DC-002 电源等模块组成。各模块之间通过相应的接口连接,实现数据的传输和控制。

2.2 方案设计

2.2.1 单片机的选择

AT89C52RC 是一种低功耗、高性能的 CMOS 8 位微控制器,具有 8K 在系统可编程 Flash 存储器。它拥有丰富的片上资源,包括 32 个 I/O 口、3 个 16 位定时器/计数器、5 个中断源等,能够满足本系统的控制需求。此外,AT89C52RC 单片机具有较高的性价比和广泛的应用基础,便于开发和调试。

2.2.2 传感器的选择
  • 烟雾传感器:MQ-2 烟雾传感器是一种常用的气体传感器,对烟雾、液化气、丙烷等气体具有较高的灵敏度。它采用半导体气敏材料,通过检测气体浓度引起的电阻变化来输出信号,具有响应速度快、稳定性好等优点,适合用于环境烟雾浓度的检测。
  • 温湿度传感器:DHT11 是一款集成数字温湿度传感器,具有校准数字信号输出功能。它采用专用的数字模块采集技术和温湿度传感技术,能够同时测量空气中的温度和湿度,具有测量精度高、抗干扰能力强等特点,广泛应用于各种温湿度监测场合。
2.2.3 显示器选择方案

LCD1602 是一种工业字符型液晶显示屏,能够同时显示 16x02 即 32 个字符。它具有体积小、功耗低、显示清晰等优点,且与单片机的接口简单,编程方便。在本系统中,LCD1602 显示屏用于实时显示环境中的烟雾浓度、温湿度值以及用户设置的阈值信息,能够满足系统的显示需求。

三、硬件的设计

3.1 主控电路

AT89C52RC 单片机是系统的核心控制单元,其最小系统包括电源电路、时钟电路和复位电路。

  • 电源电路:DC-002 电源为单片机提供稳定的 5V 直流电源。通过电源滤波电容,减少电源噪声对单片机的影响,确保单片机的稳定运行。
  • 时钟电路:采用内部时钟方式,在单片机的 XTAL1 和 XTAL2 引脚外接 12MHz 的晶振和两个 30pF 的电容,构成自激振荡器,为单片机提供时钟信号。
  • 复位电路:采用按键手动复位方式,当按下复位按键时,单片机的 RST 引脚被拉高,实现复位操作。同时,复位电路中还添加了上电自动复位功能,确保系统在上电时能够自动复位。

3.2 烟雾检测电路

MQ-2 烟雾传感器的输出信号为模拟信号,需要通过 ADC 转换电路将其转换为数字信号,以便单片机进行处理。在本系统中,采用 ADC0832 模数转换芯片实现模拟信号到数字信号的转换。

  • MQ-2 烟雾传感器连接:MQ-2 烟雾传感器的 VCC 引脚接 5V 电源,GND 引脚接地,AO 引脚(模拟输出)连接到 ADC0832 的 CH0 通道。
  • ADC0832 连接:ADC0832 的 CS、CLK、DI、DO 引脚分别与单片机的 I/O 口相连,实现数据的传输和控制。ADC0832 将 MQ-2 传感器输出的模拟信号转换为 8 位数字信号,并传输给单片机。

3.3 温湿度检测电路

DHT11 温湿度传感器采用单总线接口与单片机通信,其数据引脚直接连接到单片机的一个 I/O 口。单片机通过发送特定的时序信号,与 DHT11 传感器进行通信,读取传感器采集的温度和湿度数据。

3.4 报警电路

报警电路由蜂鸣器和 LED 灯组成,当环境中的烟雾浓度或温湿度超过设定的阈值时,单片机控制报警电路发出声光报警。

  • 蜂鸣器连接:蜂鸣器的一端接单片机的 I/O 口,另一端通过一个三极管驱动后接地。当单片机输出高电平时,三极管导通,蜂鸣器发声。
  • LED 灯连接:LED 灯的正极通过限流电阻接单片机的 I/O 口,负极接地。当单片机输出高电平时,LED 灯点亮。

3.5 显示电路

LCD1602 显示屏通过并行接口与单片机连接,其 RS、RW、E 引脚分别连接到单片机的 I/O 口,用于控制显示屏的指令和数据读写操作。D0 - D7 数据引脚与单片机的 I/O 口相连,实现数据的传输。同时,显示屏的 VCC 引脚接 5V 电源,GND 引脚接地,V0 引脚通过一个电位器调节对比度。

3.6 按键电路

本系统采用独立按键实现用户与系统的交互,共设置 4 个独立按键,分别用于修改烟雾阈值、修改温度阈值、修改湿度阈值和确认设置。按键的一端接单片机的 I/O 口,另一端接地,通过上拉电阻确保按键未按下时 I/O 口为高电平。当按键按下时,I/O 口被拉低,单片机通过检测 I/O 口的电平变化来识别按键操作。

四、软件的设计

4.1 软件介绍

本系统的软件采用 C 语言编写,使用 Keil C51 开发环境进行编程和调试。C 语言具有可读性强、可移植性好、易于维护等优点,能够满足系统软件开发的需求。

4.2 系统程序流程图

系统程序主要包括主程序、传感器数据采集程序、数据处理程序、显示程序、按键处理程序和报警程序等。主程序流程图如下:

  1. 系统初始化,包括单片机 I/O 口初始化、传感器初始化、显示屏初始化、按键初始化等。
  2. 进入主循环,不断采集传感器数据。
  3. 对采集到的数据进行处理,判断是否超过设定的阈值。
  4. 如果超过阈值,触发报警程序;否则,继续采集数据。
  5. 检测按键是否按下,如果按下,执行相应的按键处理程序,修改阈值设置。
  6. 将处理后的数据和阈值信息显示在 LCD1602 显示屏上。
  7. 返回主循环,继续执行上述步骤。

4.3 各模块程序设计

4.3.1 传感器数据采集程序
  • MQ-2 烟雾传感器数据采集:单片机通过控制 ADC0832 芯片,将 MQ-2 传感器输出的模拟信号转换为数字信号,并读取转换后的数据。
  • DHT11 温湿度传感器数据采集:单片机按照 DHT11 传感器的通信协议,发送开始信号,等待传感器响应,然后读取传感器发送的温度和湿度数据。
4.3.2 数据处理程序

对采集到的烟雾浓度、温度和湿度数据进行滤波处理,去除噪声干扰。然后,将处理后的数据与用户设定的阈值进行比较,判断是否超过阈值。

4.3.3 显示程序

将采集到的环境数据和用户设置的阈值信息按照一定的格式显示在 LCD1602 显示屏上。通过发送相应的指令和数据,控制显示屏的显示内容和位置。

4.3.4 按键处理程序

检测按键是否按下,如果按下,根据按键的不同功能,执行相应的操作,如修改烟雾阈值、修改温度阈值、修改湿度阈值和确认设置等。在按键处理过程中,需要进行防抖处理,确保按键操作的准确性。

4.3.5 报警程序

当环境中的烟雾浓度或温湿度超过设定的阈值时,单片机控制蜂鸣器和 LED 灯发出声光报警。通过控制 I/O 口的电平变化,实现蜂鸣器的发声和 LED 灯的闪烁。

五、测试结果及结论

5.1 调试

在硬件电路焊接完成后,首先对电路进行通电测试,检查各模块的电源供应是否正常。然后,使用万用表等工具检测电路的连接是否正确,有无短路或断路现象。

在软件编程过程中,采用分步调试的方法,先对各个模块的程序进行单独调试,确保每个模块的功能正常。例如,先调试传感器数据采集程序,检查是否能够正确读取传感器数据;再调试显示程序,检查显示屏是否能够正常显示数据。

将各个模块的程序集成后,进行系统联调。通过模拟不同的环境条件,测试系统是否能够准确采集环境数据,并及时发出报警信号。同时,检查按键操作是否能够正确修改阈值设置,显示屏显示是否准确清晰。

在调试过程中,遇到了一些问题,如传感器数据不准确、显示屏显示乱码、按键误触发等。通过对硬件电路和软件程序的仔细检查和分析,找到了问题的原因,并采取了相应的措施进行解决。例如,对于传感器数据不准确的问题,通过调整传感器的安装位置和添加滤波电路,提高了数据的准确性;对于显示屏显示乱码的问题,通过检查显示屏的连接和初始化程序,解决了显示问题。

5.2 结论

经过调试和测试,本基于 51 单片机的环境监测系统能够实现预期的功能。系统能够稳定运行,准确采集环境中的烟雾浓度和温湿度数据,并通过 LCD1602 显示屏实时显示。用户可以通过独立按键方便地修改烟雾和温湿度的阈值设置,当环境参数超过设定的阈值时,系统能够及时发出声光报警,提醒用户采取措施。

本系统具有成本低、性能稳定、操作简单等优点,能够满足一般环境监测的需求。同时,该系统还具有一定的扩展性,可以根据实际需求添加其他传感器,实现更多环境参数的监测。然而,本系统也存在一些不足之处,如传感器的精度有待进一步提高,系统的抗干扰能力还可以加强等。在今后的研究中,可以针对这些问题进行改进和优化,提高系统的性能和可靠性。

致谢

在本次毕业设计过程中,得到了许多老师和同学的帮助与支持。感谢指导老师在课题选择、方案设计、硬件调试和软件编程等方面给予的悉心指导和宝贵建议,使我能够顺利完成毕业设计任务。感谢同学们在实验过程中提供的帮助和交流,让我在遇到问题时能够及时得到解决。同时,也要感谢学校提供的良好的实验环境和学习资源,为毕业设计的完成提供了有力保障。

参考文献

[1] 李朝青. 单片机原理及接口技术[M]. 北京航空航天大学出版社, 2013.
[2] 郭天祥. 新概念 51 单片机 C 语言教程——入门、提高、开发、拓展全攻略[M]. 电子工业出版社, 2009.
[3] 谭浩强. C 程序设计(第四版)[M]. 清华大学出版社, 2010.
[4] 童诗白, 华成英. 模拟电子技术基础(第五版)[M]. 高等教育出版社, 2015.
[5] 阎石. 数字电子技术基础(第六版)[M]. 高等教育出版社, 2016.

附录

附录 A:原理图

(此处插入系统的硬件原理图)

附录 B:源程序

#include <reg52.h>

// 定义引脚
sbit RS = P2^0;
sbit RW = P2^1;
sbit E = P2^2;
sbit DQ = P2^3; // DHT11 数据引脚
sbit ADC_CS = P2^4;
sbit ADC_CLK = P2^5;
sbit ADC_DI = P2^6;
sbit ADC_DO = P2^7;
sbit BUZZER = P2^8;
sbit LED = P2^9;
sbit KEY1 = P3^0; // 修改烟雾阈值
sbit KEY2 = P3^1; // 修改温度阈值
sbit KEY3 = P3^2; // 修改湿度阈值
sbit KEY4 = P3^3; // 确认设置

// 定义变量
unsigned char smoke_threshold = 50;
unsigned char temp_threshold = 30;
unsigned char humi_threshold = 60;
unsigned char smoke_value;
unsigned char temp_value;
unsigned char humi_value;

// LCD1602 函数声明
void LCD_Init();
void LCD_WriteCommand(unsigned char cmd);
void LCD_WriteData(unsigned char dat);
void LCD_DisplayString(unsigned char x, unsigned char y, unsigned char *str);

// DHT11 函数声明
void DHT11_Start();
unsigned char DHT11_ReadByte();
unsigned char DHT11_ReadData(unsigned char *temp, unsigned char *humi);

// ADC0832 函数声明
unsigned char ADC0832_Read(unsigned char channel);

// 按键处理函数声明
void Key_Scan();

// 报警函数声明
void Alarm();

// 主函数
void main()
{
    LCD_Init();
    while (1)
    {
        smoke_value = ADC0832_Read(0); // 读取烟雾传感器数据
        DHT11_ReadData(&temp_value, &humi_value); // 读取温湿度传感器数据

        Key_Scan(); // 扫描按键

        // 显示数据
        LCD_DisplayString(0, 0, "Smoke:");
        LCD_DisplayString(6, 0, " ");
        LCD_DisplayString(6, 0, itoa(smoke_value)); // 显示烟雾值
        LCD_DisplayString(0, 1, "Temp:");
        LCD_DisplayString(5, 1, " ");
        LCD_DisplayString(5, 1, itoa(temp_value)); // 显示温度值
        LCD_DisplayString(9, 1, "Humi:");
        LCD_DisplayString(14, 1, " ");
        LCD_DisplayString(14, 1, itoa(humi_value)); // 显示湿度值

        // 判断是否超过阈值并报警
        if (smoke_value > smoke_threshold || temp_value > temp_threshold || humi_value > humi_threshold)
        {
            Alarm();
        }
        else
        {
            BUZZER = 1;
            LED = 1;
        }
    }
}

// LCD1602 初始化函数
void LCD_Init()
{
    LCD_WriteCommand(0x38); // 8 位数据接口,2 行显示,5x7 点阵字符
    LCD_WriteCommand(0x0C); // 显示开,光标关,闪烁关
    LCD_WriteCommand(0x06); // 输入模式设置,每次写入后指针加 1,显示不移动
    LCD_WriteCommand(0x01); // 清屏指令
}

// LCD1602 写命令函数
void LCD_WriteCommand(unsigned char cmd)
{
    RS = 0;
    RW = 0;
    P0 = cmd;
    E = 1;
    delay(1);
    E = 0;
}

// LCD1602 写数据函数
void LCD_WriteData(unsigned char dat)
{
    RS = 1;
    RW = 0;
    P0 = dat;
    E = 1;
    delay(1);
    E = 0;
}

// LCD1602 显示字符串函数
void LCD_DisplayString(unsigned char x, unsigned char y, unsigned char *str)
{
    unsigned char addr;
    if (y == 0)
    {
        addr = 0x80 + x;
    }
    else
    {
        addr = 0xC0 + x;
    }
    LCD_WriteCommand(addr);
    while (*str)
    {
        LCD_WriteData(*str++);
    }
}

// DHT11 启动信号函数
void DHT11_Start()
{
    DQ = 0;
    delay(20); // 主机拉低大于 18ms
    DQ = 1;
    delay(30); // 主机拉高 20 - 40us
}

// DHT11 读取字节函数
unsigned char DHT11_ReadByte()
{
    unsigned char i, dat = 0;
    for (i = 0; i < 8; i++)
    {
        while (!DQ); // 等待低电平过去
        delay(4); // 延时 40us
        dat <<= 1;
        if (DQ)
        {
            dat |= 0x01;
        }
        while (DQ); // 等待高电平过去
    }
    return dat;
}

// DHT11 读取数据函数
unsigned char DHT11_ReadData(unsigned char *temp, unsigned char *humi)
{
    unsigned char buf[5];
    DHT11_Start();
    if (!DQ)
    {
        while (!DQ); // 等待拉高结束
        buf[0] = DHT11_ReadByte();
        buf[1] = DHT11_ReadByte();
        buf[2] = DHT11_ReadByte();
        buf[3] = DHT11_ReadByte();
        buf[4] = DHT11_ReadByte();
        if (buf[0] + buf[1] + buf[2] + buf[3] == buf[4])
        {
            *humi = buf[0];
            *temp = buf[2];
            return 1;
        }
    }
    return 0;
}

// ADC0832 读取数据函数
unsigned char ADC0832_Read(unsigned char channel)
{
    unsigned char i, dat = 0;
    ADC_CS = 0;
    ADC_CLK = 0;
    ADC_DI = 1;
    ADC_CLK = 1;
    ADC_CLK = 0;
    ADC_DI = channel & 0x01;
    ADC_CLK = 1;
    ADC_CLK = 0;
    ADC_DI = (channel >> 1) & 0x01;
    ADC_CLK = 1;
    ADC_CLK = 0;
    ADC_DI = 1;
    for (i = 0; i < 8; i++)
    {
        ADC_CLK = 1;
        ADC_CLK = 0;
        dat <<= 1;
        dat |= ADC_DO;
    }
    ADC_CS = 1;
    return dat;
}

// 按键扫描函数
void Key_Scan()
{
    if (KEY1 == 0)
    {
        delay(10); // 消抖
        if (KEY1 == 0)
        {
            smoke_threshold++;
            while (KEY1 == 0); // 等待按键释放
        }
    }
    if (KEY2 == 0)
    {
        delay(10); // 消抖
        if (KEY2 == 0)
        {
            temp_threshold++;
            while (KEY2 == 0); // 等待按键释放
        }
    }
    if (KEY3 == 0)
    {
        delay(10); // 消抖
        if (KEY3 == 0)
        {
            humi_threshold++;
            while (KEY3 == 0); // 等待按键释放
        }
    }
    if (KEY4 == 0)
    {
        delay(10); // 消抖
        if (KEY4 == 0)
        {
            // 确认设置,可添加其他操作
            while (KEY4 == 0); // 等待按键释放
        }
    }
}

// 报警函数
void Alarm()
{
    BUZZER = 0;
    LED = 0;
    delay(500);
    BUZZER = 1;
    LED = 1;
    delay(500);
}

// 延时函数
void delay(unsigned int ms)
{
    unsigned int i, j;
    for (i = ms; i > 0; i--)
        for (j = 110; j > 0; j--);
}

// 整数转字符串函数
char *itoa(unsigned char num)
{
    static char str[4];
    str[0] = num / 100 + '0';
    str[1] = (num % 100) / 10 + '0';
    str[2] = num % 10 + '0';
    str[3] = '\0';
    return str;
}
Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐