B019 - 甲醛甲烷煤气温湿度时间测试仪

任务

  1. 甲醛浓度测试
  2. 甲烷等可燃气体浓度测试
  3. 温湿度检测
  4. 时间检测
  5. LCD12864显示
  6. 语音报警

元器件清单

在这里插入图片描述
传感器说明:
MQ-2: 可燃气体、烟雾 300 to 10000ppm
MQ-5: 液化气、甲烷、煤制气 300 to 5000ppm ;–可用打火机测
MQ-7: 一氧化碳CO 10 to 1000ppm

实物图片

在这里插入图片描述

原理图PCB

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

源程序

/*******************************************************************************

* 文件名称:基于STM32的智能生态鱼缸

* 实验目的:1.

* 2.

* 程序说明:完整程序Q:2772272579;@: [email protected]

* 日期版本:可定制功能。

*******************************************************************************/
#include"include.h"

uint data ch2o=0;	 //甲醛上限变量,   甲醛浓度变量
uchar data bz=0,UART_dat[10]={
    
    0};	 //暂存数据切换变量, 串口暂存数据数组,甲醛浓度高、低位数组, 循环变量

bit flag_200ms=0;


sbit led=P2^0;	 //温湿度传感器IO口定义
sbit beep=P1^4;		//声音模块

extern uchar xdata   hour,minute,second;

uint idata value_CH4=0,value_CO=0;
uint idata ch2o_h=1000,CH4_H=100,CO_H=100;	//各种传感器上限
uchar idata TH_H=30,RH_H=60;		 //各种传感器上限

/********************独立按键程序*****************/
uchar idata key_can=20;	 //按键值

void key_scan()	     //独立按键程序
{
    
    
	static uchar key_new;
	key_can = 20;               //按键值还原
	P3 |= 0xf0;
	if((P3 & 0xf0) != 0xf0)		//按键按下
	{
    
    
		delay_1ms(1);	     	//按键消抖动
		if(((P3 & 0xf0) != 0xf0) && (key_new == 1))
		{
    
    						//确认是按键按下
			key_new = 0;
			switch(P3 & 0xf0)
			{
    
    
				case 0xd0: key_can = 1; break;	   //得到k1键值
				case 0xb0: key_can = 2; break;	   //得到K2键值
				case 0x70: key_can = 3; break;	   //得到k3键值
			}
		}			
	}
	else 
		key_new = 1;	
}
uchar idata menu_1=0;		//必须赋初值 !!!!!
/****************按键显示函数***************/
void key_with()
{
    
    
	if(key_can == 1)	   //设置键
	{
    
    
		menu_1 ++;
		if(menu_1 == 1)			//设置时间界面
		{
    
    
			lcd_SendCMD(0x01);//清除显示

			lcd_write_string(1,0,"    设置时间    ");
			lcd_write_string(2,0,"  15:05:00    ");  // 1 3 5		时分秒位置											 

//			lcd_write_string(2,0,"0123456789abcdef");
				
			 lcd_write_sfm2(2,1,hour);		
			 lcd_write_sfm2(2,3,minute);
			 lcd_write_sfm2(2,5,second);							
		}
		if(menu_1 == 4)			//设置甲醛界面
		{
    
    
			lcd_SendCMD(0x01);//清除显示

			lcd_write_string(1,0,"设置甲醛浓度上限");
			lcd_write_string(2,0,"0.0100mg/m3     ");  // 3 位置  Right_Arrow

			lcd_write_string(3,0,"温度:    ℃    ");  // 1 3 5		温度
			lcd_write_string(4,0,"湿度:    %     ");  // 1 3 5		湿度

			lcd_SendWord(2,7,Left_Arrow);	//显示 ←	提示符
			lcd_write_jiaquan(2,0,ch2o_h);	

			lcd_write_sfm2(3,3,TH_H);	
			lcd_write_sfm2(4,3,RH_H);
		}
		if(menu_1 == 7)			//设置甲烷界面
		{
    
    
			lcd_SendCMD(0x01);//清除显示

			lcd_write_string(1,0,"甲烷浓度上限:   ");
			lcd_write_string(2,0,"上限: 100 ppm   ");  // 3 位置
			lcd_write_CH4(2,3,CH4_H);
			lcd_write_string(3,0,"  CO浓度上限:   ");
			lcd_write_string(4,0,"上限: 100 ppm   ");  // 3 位置
			lcd_write_CO(4,3,CO_H);	
		}
		if(menu_1 > 8)
		{
    
    
			menu_1 = 0;
			lcd_SendCMD(0x01);//清除显示
			lcd_write_string(1,0,"  15:05:00    ");	 	
			lcd_write_string(2,0,"甲醛            ");
			lcd_write_string(3,0,"温度:20湿度:20");
			lcd_write_string(4,0,"甲烷      CO    ");	
			
			WriteSet1302(0x8E,0x00);                 //根据写状态寄存器命令字,写入不保护指令 
			WriteSet1302(0x84,((hour/10)<<4|(hour%10))); //根据写小时寄存器命令字,写入小时
			WriteSet1302(0x82,((minute/10)<<4|(minute%10))); //根据写小时寄存器命令字,写入小时
			WriteSet1302(0x80,((second/10)<<4|(second%10))); //根据写小时寄存器命令字,写入小时
//			WriteSet1302(0x8E,0x80);                 //根据写状态寄存器命令字,写入保护指令	
		
			lcd_write_jiaquan(2,2,ch2o);
			lcd_write_string(2,5,"mg/m3");
			lcd_write_sfm2(3,3,TH);	
			lcd_write_sfm2(3,7,RH);	
			lcd_write_CH4(4,2,value_CH4);
			lcd_write_CO(4,6,value_CO);

		}
	}
	if(menu_1 == 1)			//设置时间界面	   小时    
	{
    
    
		if(key_can == 2)
		{
    
    
			hour=hour+1;	
			if(hour>23)
				hour=23;		
		}
		if(key_can == 3)			 //设置 
		{
    
    
			hour=hour-1 ;			
			if(hour <= 1)
				hour = 1;
		}
		lcd_write_sfm2(2,1,hour);	
		lcd_SendWord(3,1,Up_Arrow);	//显示 ↑	提示符
	}
	if(menu_1 == 2)			//设置时间界面	   分   
	{
    
    
		if(key_can == 2)
		{
    
    
			minute=minute+1;	
			if(minute>59)
				minute=59;		
		}
		if(key_can == 3)			 //设置 
		{
    
    
			minute=minute-1 ;			
			if(minute <= 1)
				minute = 1;
		}
		lcd_write_sfm2(2,3,minute);
		lcd_SendWord(3,1,' ');	//显示 	提示符
		lcd_SendWord(3,3,Up_Arrow);	//显示 ↑	提示符
	}
	if(menu_1 == 3)			//设置时间界面	   秒  
	{
    
    
		if(key_can == 2)
		{
    
    
			second=second+1;	
			if(second>59)
				second=59;		
		}
		if(key_can == 3)			 //设置 
		{
    
    
			second=second-1 ;			
			if(second <= 1)
				second = 1;
		}
		lcd_write_sfm2(2,5,second);
		lcd_SendWord(3,3,' ');	//显示 	提示符
		lcd_SendWord(3,5,Up_Arrow);	//显示 ↑	提示符
	}
	if(menu_1 == 4)			//设置界面	   甲醛  
	{
    
    
		if(key_can == 2)
		{
    
    
			ch2o_h+=10;	
			if(ch2o_h>=10000)
				ch2o_h=10000;		
		}
		if(key_can == 3)			 //设置 
		{
    
    
			ch2o_h-=10 ;			
			if(ch2o_h <= 10)
				ch2o_h = 10;
		}
		lcd_write_jiaquan(2,0,ch2o_h);	
		lcd_SendWord(2,7,Left_Arrow);	//显示 ←	提示符
	}
	if(menu_1 == 5)			//设置界面	   温度 
	{
    
    
		if(key_can == 2)
		{
    
    
			TH_H+=1;	
			if(TH_H>=100)
				TH_H=100;		
		}
		if(key_can == 3)			 //设置 
		{
    
    
			TH_H-=1 ;			
			if(TH_H <= 1)
				TH_H = 1;
		}
		
		lcd_write_sfm2(3,3,TH_H);
		lcd_write_string(2,7,"  ");	//显示 	提示符
		lcd_SendWord(3,7,Left_Arrow);	//显示 ←	提示符	
	}
	if(menu_1 == 6)			//设置界面	  湿度
	{
    
    
		if(key_can == 2)
		{
    
    
			RH_H+=1;	
			if(RH_H>=100)
				RH_H=100;		
		}
		if(key_can == 3)			 //设置 
		{
    
    
			RH_H-=1 ;			
			if(RH_H <= 1)
				RH_H = 1;
		}
		lcd_write_sfm2(4,3,RH_H);
		lcd_write_string(3,7,"  ");	//显示 	提示符
		lcd_SendWord(4,7,Left_Arrow);	//显示 ←	提示符
	}
	if(menu_1 == 7)			//设置界面	   甲烷
	{
    
    
		if(key_can == 2)
		{
    
    
			CH4_H+=10;	
			if(CH4_H>=1000)
				CH4_H=10000;		
		}
		if(key_can == 3)			 //设置 
		{
    
    
			CH4_H-=10 ;			
			if(CH4_H <= 10)
				CH4_H = 10;
		}
		lcd_write_CH4(2,3,CH4_H);
		lcd_SendWord(2,7,Left_Arrow);	//显示 ←	提示符
	}
	if(menu_1 == 8)			//设置界面	   CO
	{
    
    
		if(key_can == 2)
		{
    
    
			CO_H+=10;	
			if(CO_H>=1000)
				CO_H=10000;		
		}
		if(key_can == 3)			 //设置 
		{
    
    
			CO_H-=10 ;			
			if(CO_H <= 10)
				CO_H = 10;
		}
		lcd_write_CO(4,3,CO_H);
		lcd_SendWord(2,7,' ');	//显示 	提示符
		lcd_SendWord(4,7,Left_Arrow);	//显示 ←	提示符
		lcd_write_string(2,7,"  ");	//显示 	提示符
	}		
} 
// uint ch2o_h=1000,CH4_H=100,CO_H=100;	//各种传感器上限
//uchar TH_H=30,RH_H=60;		 //各种传感器上限
void SPK(void)
{
    
    
	if((ch2o>=ch2o_h)||(value_CH4>=CH4_H)||(value_CO>=CO_H)||(TH>=TH_H)||(RH>=RH_H))
	{
    
    
		beep=0;
		led=0;		 
	}
	else
	{
    
    
	    beep=1;
		led=1;	
	}
}
/*************定时器0初始化程序***************/
void time_init()	  
{
    
    
	EA   = 1;	 	  //开总中断
	TMOD = 0X21;	  //定时器0、定时器1工作方式1
	TH0=(65536-50000)/256;
	TL0=(65536-50000)%256;
	ET0  = 1;		  //开定时器0中断 
	TR0  = 1;		  //允许定时器0定时
	TH1=0xfd;		//串口波特率定时初始
	TL1=0xfd;
	SCON=0x50;	//只发送
	ES=1;		//打开串口中断
	TR1=1;
}
/******************主程序**********************/	 
void main(void)
{
    
    
	uchar Count_DHT11=0,Count_Jiaquan=0,Count_ADC0809_CO=0,Count_ADC0809_CH4=0;
//	uchar test;
	Init_DS1302();
	LCD_Init();
	read_date();
	time_init();  	//定时器初始化
	beep=1;
	led=1;
	while(1)
	{
    
    		
		key_scan();				  //按键检测,若有按键按下,则进按键处理
		if(key_can < 10)
		{
    
    
			key_with();			    //设置参数  
			TR0=TR1=0;	
		}			
		if(menu_1==0)
		{
    
    
			TR0=1;
			read_date();	  //读取并显示1302时间				
			if(flag_200ms == 1)									//如果200ms时间到.
			{
    
    
				flag_200ms = 0;									//200ms标志清
				Count_DHT11++;
				if(Count_DHT11>2)			//2S采集一次
				{
    
    
					Count_DHT11=0;
					receive();
					lcd_write_sfm2(3,3,TH);	
					lcd_write_sfm2(3,7,RH);	
				}
				Count_ADC0809_CO++;
				if(Count_ADC0809_CO>4)		//4S采集一次CO数据
				{
    
    
					Count_ADC0809_CO=0;	  
					CO_TEST
					value_CO=Get_CO();
					lcd_write_CO(4,6,value_CO);
				}
				Count_ADC0809_CH4++;
				if(Count_ADC0809_CH4>5)		//5S采集一次CH4数据
				{
    
    
					Count_ADC0809_CH4=0;
					CH4_TEST
					value_CH4=Get_CH4();
					lcd_write_CH4(4,2,value_CH4);		  
				}
				Count_Jiaquan++;
				if(Count_Jiaquan>8)			//8S采集一次
				{
    
    
					Count_Jiaquan=0;
					ES=1;
					TR1=1;
					lcd_write_jiaquan(2,2,ch2o);
					lcd_write_string(2,5,"mg/m3");
				}
				else
				{
    
    
					ES=0;
					TR1=0;
				}				
			}
			SPK();
		}

	}
}  
/*************定时器0中断服务程序***************/
void time0_int() interrupt 1		 //定时中断函数	 每50ms进一次中断 
{
    
      	
	static uchar count_timer0=0;							
    TH0=(65536-50000)/256;
	TL0=(65536-50000)%256;
	count_timer0++;
	if(count_timer0>=20)		 //1s  
	{
    
    
		flag_200ms=1;
		count_timer0=0;
	}
}
void UART_4() interrupt 4 //处理接收的串口数据
{
    
    
	if(RI)
	{
    
    
		RI=0;   //RI 置0
		UART_dat[bz]=SBUF;	  //暂存串口数据
		switch(bz)
		{
    
    
			case 0:
				if(UART_dat[bz]==0xFF)
				{
    
    
					bz=1;
				}else
				{
    
    
					bz=0; 
				}
			break;

			case 1:
				if(UART_dat[bz]==0x17)
				{
    
    
					bz=2;
				}else
				{
    
    
					bz=0; 
				}
			break;

			case 2:
				if(UART_dat[bz]==0x04)
				{
    
    
					bz=3;
				}else
				{
    
    
					bz=0;  
				}
			break;

			case 3:
				if(UART_dat[bz]==0x00)
				{
    
    
					bz=4; 
				}else
				{
    
    
					bz=0; 
				}
			break;

			case 4:
				bz=5;   
			break;

			case 5:
				bz=6; 
			break;

			case 6:
				if(UART_dat[bz]==0x13)
				{
    
    
					bz=7;   
				}else
				{
    
    
					bz=0; 
				}
			break;

			case 7:
				if(UART_dat[bz]==0x88)
				{
    
    
					bz=8;  
				}else
				{
    
    
					bz=0; 
				}
			break;

			case 8:  //校验接收的数据  正确则处理接收的数据
				if((UART_dat[bz]+UART_dat[1]+UART_dat[2]+UART_dat[3]+UART_dat[4]+UART_dat[5]+UART_dat[6]+UART_dat[7])%256==0)
				{
    
    
					ch2o=UART_dat[4]*256+UART_dat[5];
					ch2o=ch2o*13.392857;
					bz=0;
				}else
				{
    
    
					bz=0;   
				}
			break;

		}
	}
}     

猜你喜欢

转载自blog.csdn.net/qq_20467929/article/details/126107437