基于单片机瓦斯气体PM2.5温度风速检测报警系统

该设计利用STC89C52单片机控制,结合瓦斯、PM2.5传感器、温度传感器DS18B20和风速传感器,通过ADC0832转换数据,实现在LCD1602上显示测量值并设置报警阈值。当测量值超出预设范围时,系统触发蜂鸣器报警。软件部分包括LCD1602初始化、数据显示及按键功能处理。此外,使用Proteus软件进行仿真验证设计方案的可行性。
摘要由CSDN通过智能技术生成

基于单片机瓦斯气体PM2.5温度风速检测报警系统
一、系统方案

本设计采用STC89C52作为主控制器,瓦斯传感器、PM2.5传感器采集数据值送到ADC0832转换,送到单片机处理,液晶1602显示对应测量值,温度DS18B20采集温度值,送到液晶显示,风速传感器采集风速,送到ADC0832转换,送到单片机处理对应测量值,按键设置报警阀值,测量值超过设设定阀值,蜂鸣器报警。
在这里插入图片描述
二、硬件设计
原理图如下:
在这里插入图片描述
三、单片机软件设计
1、首先是系统初始化:

Lcd1602_Init(); //LCD1602初始化
Delay_function(50); //延时50ms
lcd1602_clean(); //清屏
Delay_function(50); //延时50ms
Ds18b20_Init(); //DS18B20初始化
Delay_function(50); //延时50ms
2、液晶显示程序
/**********************************
包含头文件
**********************************/
#include “lcd1602.h”

/**********************************
函数定义
******************************/
/

*******1602检测忙函数
*****/
void lcd1602_check_busy()
{
P0=0xff;
do
{
LCD1602_RS=0;
LCD1602_RW=1;
LCD1602_E=0;
LCD1602_E=1;
} while(LCD1602_BUSY==1);
LCD1602_E=0;
}

/****
*******1602写数据忙函数
*****/
void lcd1602_write_date(uchar date)
{
lcd1602_check_busy();
LCD1602_E=0;
LCD1602_PORT=date;
LCD1602_RS=1;
LCD1602_RW=0;
LCD1602_E=1;
LCD1602_E=0;
}

/****
*******1602写命令函数
*****/
void lcd1602_write_com(uchar com)
{
lcd1602_check_busy();
LCD1602_E=0;
LCD1602_PORT=com;
LCD1602_RS=0;
LCD1602_RW=0;
LCD1602_E=1;
LCD1602_E=0;
}

/****
*******LCD1602初始化函数
*****/
void Lcd1602_Init()
{
lcd1602_write_com(0x38);
lcd1602_write_com(0x0c);
lcd1602_write_com(0x06);
lcd1602_write_com(0x01);
}

/****
*******LCD1602显示字符串函数
*******参量定义: hang:输入显示行数 1 第一行 2 第二行
******* add:偏移量,0-15
******* dat:所要显示的字符串,输入格式 " "
*****/
void lcd1602_display_str(uchar hang, uchar add, uchar *dat)
{
if(hang==1)
lcd1602_write_com(0x80+add); //第一行
else
lcd1602_write_com(0x80+0x40+add); //第二行

while(*dat != '\0')
{
	lcd1602_write_date(*dat++);
}

}

/****
*******LCD1602清屏函数
*****/
void lcd1602_clean()
{
lcd1602_display_str(1,0," “);
lcd1602_display_str(2,0,” ");
}

/****
*******LCD1602显示数字函数(最大4位)
*******参量定义: hang:输入显示行数 1 第一行 2 第二行
******* add:偏移量,0-15
******* num:所要显示的数据,最大4位
*****/
void lcd1602_display_num(uchar hang, uchar add, uint num)
{
if(hang==1)
lcd1602_write_com(0x80+add); //第一行
else
lcd1602_write_com(0x80+0x40+add); //第二行

if(num > 999)
	lcd1602_write_date(num/1000%10+48);	//千
if(num > 99)
	lcd1602_write_date(num/100%10+48);	//百
if(num > 9)
	lcd1602_write_date(num/10%10+48);		//十
lcd1602_write_date(num/1%10+48);		//个
lcd1602_write_date(' ');
lcd1602_write_date(' ');
lcd1602_write_date(' ');

}

/****
*******LCD1602显示温度函数(显示格式:**.*℃)
*******参量定义: hang:输入显示行数 1 第一行 2 第二行
******* add:偏移量,0-15
******* temp:所要显示的温度
*****/
void lcd1602_display_temp(uchar hang, uchar add,uint temp)
{
if(hang==1)
lcd1602_write_com(0x80+add); //第一行
else
lcd1602_write_com(0x80+0x40+add); //第二行

lcd1602_write_date(temp/100%10+48);
lcd1602_write_date(temp/10%10+48);
lcd1602_write_date('.');
lcd1602_write_date(temp/1%10+48);
lcd1602_write_date(0xdf);				//显示温度的小圆圈符号,0xdf是液晶屏字符库的该符号地址码

lcd1602_write_date(0x43); //显示"C"符号,0x43是液晶屏字符库里大写C的地址码
}

/****
*******LCD1602显示风速(显示格式:**.*m/s)
*******参量定义: hang:输入显示行数 1 第一行 2 第二行
******* add:偏移量,0-15
******* wind:所要显示的风速
*****/
void lcd1602_display_wind(uchar hang, uchar add,uint wind)
{
if(hang==1)
lcd1602_write_com(0x80+add); //第一行
else
lcd1602_write_com(0x80+0x40+add); //第二行

lcd1602_write_date(wind/100%10+48);
lcd1602_write_date(wind/10%10+48);
lcd1602_write_date('.');
lcd1602_write_date(wind/1%10+48);
lcd1602_write_date('m');
lcd1602_write_date('/');
lcd1602_write_date('s');

}

/****
*******LCD1602显示气体浓度(显示格式:000ppm)
*******参量定义: hang:输入显示行数 1 第一行 2 第二行
******* add:偏移量,0-15
******* gas_value:所要显示的气体浓度
*****/
void lcd1602_display_gas(uchar hang, uchar add,uint gas_value)
{
if(hang==1)
lcd1602_write_com(0x80+add); //第一行
else
lcd1602_write_com(0x80+0x40+add); //第二行

if(gas_value > 999)
	lcd1602_write_date(gas_value/1000%10+48);
if(gas_value > 99)
	lcd1602_write_date(gas_value/100%10+48);
if(gas_value > 9)
	lcd1602_write_date(gas_value/10%10+48);
lcd1602_write_date(gas_value/1%10+48);
lcd1602_write_date('p');

lcd1602_write_date(‘p’);
lcd1602_write_date(‘m’);
lcd1602_write_date(’ ‘);
lcd1602_write_date(’ ‘);
lcd1602_write_date(’ ');
}

/****
*******LCD1602显示PM2.5(显示格式:000ug/m3)
*******参量定义: hang:输入显示行数 1 第一行 2 第二行
******* add:偏移量,0-15
******* pm25_value:所要显示的PM2.5
*****/
void lcd1602_display_pm25(uchar hang, uchar add,uint pm25_value)
{
if(hang==1)
lcd1602_write_com(0x80+add); //第一行
else
lcd1602_write_com(0x80+0x40+add); //第二行

if(pm25_value > 999)
	lcd1602_write_date(pm25_value/1000%10+48);
if(pm25_value > 99)
	lcd1602_write_date(pm25_value/100%10+48);
if(pm25_value >= 9)
	lcd1602_write_date(pm25_value/10%10+48);
lcd1602_write_date(pm25_value/1%10+48);
lcd1602_write_date('u');

lcd1602_write_date(‘g’);
lcd1602_write_date(‘/’);
lcd1602_write_date(‘m’);
lcd1602_write_date(‘3’);
lcd1602_write_date(’ ');
}

3、按键检测程序
/****
*******按键函数
*****/
void Key_function(void)
{
key_num = Chiclet_Keyboard_Scan(0); //按键扫描
if(key_num != 0) //有按键按下
{
switch(key_num)
{
case 1: //按键1,切换界面
flag_display++;
if(flag_display >= 6)
flag_display = 0;

			lcd1602_clean();
		break;

		case 2:													//按键2,不同界面有不同功能
			switch(flag_display)
			{
				case 0:											//界面0,切换测量界面
					flag_meas_display++;
					if(flag_meas_display >= 2)
						flag_meas_display = 0;
					
					lcd1602_clean();
				break;
				
				case 1:											//界面1,温度最大值+1
					if(temp_max < 99)
						temp_max++;
				break;
				
				case 2:											//界面2,温度最小值+1
					if(temp_min < temp_max-1)
						temp_min++;
				break;
				
				case 3:											//界面3,风速最大值+1
					if(wind_max < 99)
						wind_max++;
				break;
					
				case 4:											//界面4,瓦斯最大值+1
					if(gas_max < 500)
						gas_max++;
				break;
					
				case 5:											//界面5,PM2.5最大值+1
					if(pm25_max < 500)
						pm25_max++;
				break;
				
				default:
				break;
			}
		break;

		case 3:													//按键3,不同界面有不同功能
			switch(flag_display)
			{
				case 1:											//界面1,温度最大值-1
					if(temp_max > temp_min+1)
						temp_max--;
				break;
				
				case 2:											//界面2,温度最小值-1
					if(temp_min > 0)
						temp_min--;
				break;
				
				case 3:											//界面3,风速最大值-1
					if(wind_max > 0)
						wind_max--;
				break;
					
				case 4:											//界面4,瓦斯最大值-1
					if(gas_max > 0)
						gas_max--;
				break;
					
				case 5:											//界面5,PM2.5最大值-1
					if(pm25_max > 0)
						pm25_max--;
				break;

				default:
				break;
			}
		break;

		default:
			break;
	}
}

}
4、核心算法程序
void Manage_function(void)
{
if(flag_display == 0) //界面0,即测量界面
{
if(temp_value > temp_max10 || temp_value < temp_min10 || wind_value > wind_max*10 || gas_value > gas_max || pm25_value > pm25_max) //测量值不在设置的阈值之内,进行声光报警
{
if(time_num % 10 == 0)
{
LED = ~LED;
BEEP = ~BEEP;
}
}
else //测量值在设置的阈值之内,不进行声光报警
{
LED = 1;
BEEP = 1;
}
}
else //其他界面,即设置界面
{
LED = 1;
BEEP = 1;
}
}

四、proteus仿真设计
Proteus软件是一款应用比较广泛的工具,它可以在没有硬件平台的基础上通过自身的软件仿真出硬件平台的运行情况,这样就可以通过软件仿真来验证我们设计的方案有没有问题,如果有问题,可以重新选择器件,连接器件,直到达到我们设定的目的,避免我们搭建实物的时候,如果当初选择的方案有问题,我们器件都已经焊接好了,再去卸载下去,再去焊接新的方案的器件,测试,这样会浪费人力和物力,也给开发者带来一定困惑,Proteus仿真软件就很好的解决这个问题,我们在设计之初,就使用该软件进行模拟仿真,测试,选择满足我们设计的最优方案。最后根据测试没问题的仿真图纸,焊接实物,调试,最终完成本设计的作品。
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

bbxyliyang

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值