【51单片机设计】基于单片机的煤气安全报警器的设计


  资料下载:


1、实现功能


(1)煤气浓度实时监测:系统能够持续检测环境中的煤气浓度,并将数据转换为可读信号,确保实时监控空气质量。
(2)阈值设定与调整:用户可通过按键自由设定煤气浓度报警阈值,使系统适应不同场景需求,提高灵活性。
(3)超标报警提示:当检测到煤气浓度超出设定范围,系统将立即触发蜂鸣器报警,及时提醒用户。
(4)数据可视化显示:通过液晶屏实时显示煤气浓度和系统状态,用户可直观了解环境信息,便于及时响应。

可增加的功能:

主要元器件:

  51单片机、晶振、ADC0832数模转换芯片、LCD1602显示屏、MQ-2可燃气体传感器、蜂鸣器、三极管


2、硬件

硬件框图

煤气安全报警器采用STC89C52单片机作为核心控制器,采用MQ传感器实现对空气中煤气浓度的实时检测,并将其转换为模拟电压信号传输至ADC0832模数转换芯片,再由单片机进行数据读取和处理。用户可通过按键模块设定报警阈值,当实际煤气浓度超出设定范围时,单片机将驱动蜂鸣器发出声响警报。系统使用LCD1602液晶屏实时显示当前煤气浓度及系统状态,以便用户直观了解环境信息。系统采用5V直流稳压电源供电,并对电路进行抗干扰优化,确保长期稳定运行。整个方案具备实时监测、阈值设定、声光报警、数据可视化显示等功能,能够有效提升家庭或工业环境的煤气安全监测能力,减少燃气泄漏带来的安全隐患

在这里插入图片描述

实物

请添加图片描述

3、代码

   代码采用C语言,软件是keil5,关键代码有中文注释,看不懂可以VX问我

//宏定义
#define uint unsigned int
#define uchar unsigned char
//头函数
#include <reg52.h>	
#include <intrins.h>
#include <stdio.h>
#include "usart.h"
#define dat P0

sbit beep   =P2^0;		//蜂鸣器驱动引脚

sbit lcd1602_rs=P2^5;			//读/写数据选择引脚
sbit lcd1602_rw=P2^6;			//片选 0 有效
sbit lcd1602_en=P2^7;  		//数据传输使能引脚

/***************************************************************
* 名称 : delay_ms()
* 功能 : 延时1ms函数
* 输入 : q
* 输出 : 无
****************************************************************/
void delay_ms(unsigned int q)
{
    
    
	unsigned int i,j;
	for(i=0;i<q;i++)
		for(j=0;j<120;j++);
}
sbit K1=P3^3;
sbit K2=P3^4;
sbit K3=P3^5;
unsigned char Key_Scan()
{
    
    
	static unsigned char key_up,key_num;		//松手检测
	key_num=0;
	if(((K1==0)||(K2==0)||(K3==0))&&(key_up==1) )
	{
    
    
		key_up=0;
		delay_ms(10);		//软件消抖
		if(K1==0)
			key_num = 1;
		else if(K2==0)
			key_num = 2;
		else if(K3==0)
			key_num = 3;
	}
	else if((K1==1)&&(K2==1)&&(K3==1))
	{
    
    
		key_up=1;
	}
	return key_num;
}
//函数  delay(unsigned char z)
//功能能  延时
void lcd1602_delay(unsigned int z)
{
    
    
	unsigned int a,b;
	for(a=z;z>0;z--)
	for(b=110;b>0;b--);	
}
void write_com(unsigned char com)  //写命令
{
    
    
	lcd1602_rs=0;
  dat=com;
	lcd1602_en=0;
	lcd1602_delay(1);
	lcd1602_en=1;
	lcd1602_delay(1);
	lcd1602_en=0;
}
void write_date(unsigned char date)//写数据
{
    
    	
	dat=date;
	lcd1602_rs=1;
	lcd1602_en=0;
	lcd1602_delay(1);
	lcd1602_en=1;
	lcd1602_delay(1);
	lcd1602_en=0;
}
void lcd1602_init()// 1602初始化
{
    
    	
	lcd1602_rw=0;
	lcd1602_en=0;
	write_com(0x38);//设置1602显示模式为5*7点阵
	lcd1602_delay(1);
	write_com(0x01);//清屏	
	lcd1602_delay(1);		  				
	write_com(0x0c);//开显示,不显示光标,光标不闪烁
	lcd1602_delay(1);	  	
  write_com(0x06);//设置当读或写一个字符后,地址指针加一,且光标加一	
	lcd1602_delay(1);
}


void show_str(unsigned char  *s)// 1602显示字符串
{
    
     
	while(*s != '\0')
  {
    
     
		write_date(*s++);
  }
}

//管脚声明
sbit CS     =P1^2;		//CS定义脚, 连接ADC0832CS脚
sbit SCL    =P1^0;		//SCL定义脚,连接ADC0832CLK脚
sbit DO     =P1^1;		//DO定义脚,连接ADC0832DAT脚
/***********读数模转换数据********************************************************/	
//请先了解ADC0832模数转换的串行协议,再来读本函数,主要是对应时序图来理解,本函数是模拟0832的串行协议进行的
unsigned char ad0832read(bit SGL,bit ODD)
{
    
    
	unsigned char i=0,value=0,value1=0;		
	SCL=0;
	DO=1;
	CS=0;		//开始
	SCL=1;	//第一个上升沿	
	SCL=0;
	DO=SGL;
	SCL=1;  	//第二个上升沿
	SCL=0;
	DO=ODD;
	SCL=1;	    //第三个上升沿
	SCL=0;	    //第三个下降沿
	DO=1;
	for(i=0;i<8;i++)
	{
    
    
		SCL=1;
		SCL=0; //开始从第四个下降沿接收数据
		value<<=1;
		if(DO)
			value++;						
	}
	for(i=0;i<8;i++)
	{
    
    			//接收校验数据
		value1>>=1;
		if(DO)
			value1+=0x80;
		SCL=1;
		SCL=0;
	}
	CS=1;
	SCL=1;	
	if(value==value1)				//与校验数据比较,正确就返回数据,否则返回0	
		return value;
	return 0;
}

char str[50];
unsigned int MQ5 = 0;  //
unsigned int SET1=50; //阈值
/****************主函数**********************/
void main()
{
    
    
	unsigned char mode=0,time=0,i; //模式
	unsigned char key,flag=1;
	delay_ms(100);
	lcd1602_init();   //LCD1602初始化
	UART_init(9600);
	while(1)	   	//循环
	{
    
    
		key=Key_Scan();  //按键获取
		if(key == 1)
		{
    
    
			write_com(0x01);//清屏	
			mode++;
			if(mode==2)
				mode=0;
		}
		delay_ms(10);
		if(mode == 0)
		{
    
    
			if(time++>200)
			{
    
    
				for(i = 0;i<5;i++)
				{
    
    
					MQ5 += ad0832read(1,0)/2.56;
					delay_ms(1);
				}
				MQ5 = MQ5 / 5;
				time = 0;
				write_com(0x80);//设置第二行显示温湿度
				show_str("MQ:");
				write_date(MQ5%100/10+0x30);
				write_date(MQ5%10+0x30);
				show_str("%");
				if( MQ5>SET1)//超过阈值
				{
    
    
					beep = !beep;
				}    
				else //否则关闭报警
				{
    
    
					beep=1; 
				}
			}
		}
		else
		{
    
    
			beep=1;
			if(key == 2)   //加按键
			{
    
    
				switch(mode)  //根据模式选择具体加哪个
				{
    
    
					case 1:SET1++;break;
				}
			}
			if(key == 3)  //减按键同理
			{
    
    
				switch(mode)
				{
    
    
					case 1:SET1--;break;
				}
			}
			write_com(0xC0);      //设置第一行显示
			switch(mode)  //根据模式选择具体哪个
			{
    
    
				case 1:sprintf(str,"SET:%02d   ",SET1);break;
			}
			show_str(str);
		}
	}
}
/*----------------------------
UART interrupt service routine
----------------------------*/
void Uart_Isr() interrupt 4 {
    
    
	static unsigned char last;
	unsigned char res;	
	if (RI) 
	{
    
    
		RI = 0;             //Clear receive interrupt flag
		res = SBUF;
		if((last == 0x2c)&&(res == 0xe4))
		{
    
    
			uart_count = 0;
		}
		else
		{
    
    
			uart_buff[uart_count++] = res;
			last = res;
		}
		//CO2 =( uart_buff[4]*256 + uart_buff[5] );
	}
	if (TI) 
	{
    
    
		TI = 0;             //Clear transmit interrupt flag
		busy = 0;           //Clear transmit busy flag
	}
}


4、原理图/PCB

  原理图和PCB都使用立创EDA绘制,对新手较为友好。可以导出为AD格式的文件

在这里插入图片描述

在这里插入图片描述

5、总结

本设计基于STC89C52单片机实现了一款煤气安全报警器系统,旨在提供一种高效、可靠的煤气检测与报警解决方案。系统能够实时监测环境中的煤气浓度,并在浓度超标时及时发出声光报警,有效预防煤气泄漏带来的安全隐患。在硬件设计方面,系统采用了MQ气体传感器,该传感器具有较高的灵敏度和响应速度,能够准确检测常见的可燃气体,如甲烷、液化气等。通过ADC0832模数转换芯片,将模拟信号转化为数字信号,由单片机进行数据处理与决策控制。为了实现直观的数据显示,系统选用了LCD1602液晶显示模块,实时显示煤气浓度及报警状态,用户可通过三个按键模块设定报警阈值,满足不同使用环境的需求。在软件设计方面,系统实现了数据采集、报警控制、阈值设定和数据显示等功能。特别在阈值设定和按键输入处理方面,采用了软件消抖技术,有效避免了按键抖动引起的误操作,确保系统的稳定性和可靠性。综上所述,煤气安全报警器在满足基本功能需求的基础上,通过合理的硬件选型与软件实现,提高了系统的性能与用户体验。

猜你喜欢

转载自blog.csdn.net/lihuadetongzhuo/article/details/146481833