基于51单片机的甲醛浓度显示及报警系统设计

1、设计需求及目标

单片机甲醛浓度报警器由51单片机+ZE08-CH2O甲醛浓度传感器+LCD1602液晶显示+LED灯+按键+蜂鸣器构成。

具体功能:

1、ZE08-CH2O检测当前甲醛浓度值并用LCD1602实时显示;

2、通过按键可设置报警最小浓度。当实际测出的甲醛浓度大于设定的浓度时就会使得蜂鸣器、LED灯报警;

3、LED灯显示正常工作状态和报警状态;

4、LCD1602液晶显示所测的甲醛浓度值和设置的报警阈值。

基于51单片机的甲醛浓度显示及报警系统设计_第1张图片

2、设计方案及思路

本设计是单片机要完成功能就是检测甲醛的浓度并在液晶上显示,当甲醛浓度超过用户设置的上限值发怵提示报警。

基于51单片机的甲醛浓度显示及报警系统设计_第2张图片

3、硬件电路

基于51单片机的甲醛浓度显示及报警系统设计_第3张图片

4、部分代码

#include				 //头文件
#include				 //头文件
#include"eeprom52.h"
#define uchar unsigned char		 //宏定义
#define uint unsigned int
#define LCD1602_dat P0


sbit LCD1602_rs=P2^5;//IO 定义
sbit LCD1602_rw=P2^6;
sbit LCD1602_e=P2^7;
sbit beep=P2^0;	   //蜂鸣器IO
sbit led_1=P1^0;	 //指示灯IO
sbit led_2=P1^1;
sbit key_1=P1^2;	//按键控制IO
sbit key_2=P1^3;

uint ch2o_H,ch2o;	 //甲醛上限变量,   甲醛浓度变量
uchar bz,ms,sec,UART_dat[10],zhi[2],i;	 //暂存数据切换变量, 50模式 变量,  串口暂存数据数组,甲醛浓度高、低位数组, 循环变量
bit beep1;






/********************************************************************
* 名称 : delay()
* 功能 : 小延时。													 
* 输入 : 无
* 输出 : 无
***********************************************************************/

void delay(uint T)					  //延时函数
{
	while(T--);
}

/********************************************************************
* 名称 : LCD1602_write(uchar order,dat)
* 功能 : 1602写如数据函数
* 输入 : 输入的命令值
* 输出 : 无
***********************************************************************/
void LCD1602_write(uchar order,dat)				  //1602 一个字节  处理
{
    LCD1602_e=0;
    LCD1602_rs=order;
    LCD1602_dat=dat;
    LCD1602_rw=0;
    LCD1602_e=1;
    delay(1);
    LCD1602_e=0;																								     
}
/********************************************************************
* 名称 : LCD1602_writebye(uchar *prointer)
* 功能 : 1602写入数据函数  指针式
* 输入 : 输入的命令值
* 输出 : 无
***********************************************************************/
void LCD1602_writebyte(uchar *prointer)				   //1602 字符串    处理
{
    while(*prointer!='\0')
    {
        LCD1602_write(1,*prointer);
        prointer++;
    }
}
/********************************************************************
* 名称 : LCD1602_cls()
* 功能 : 初始化1602液晶 
* 输入 : 无
* 输出 : 无
***********************************************************************/
void LCD1602_cls()									 //1602 初始化
{
	LCD1602_write(0,0x01);     //1602 清屏 指令
	delay(1500);
	LCD1602_write(0,0x38);     // 功能设置 8位、5*7点阵
	delay(1500);
	LCD1602_write(0,0x0c);     //设置 光标   不显示开关、不显示光标、字符不闪烁
	LCD1602_write(0,0x06);
	LCD1602_write(0,0xd0);
	delay(1500);
}

void show()			//显示数据
{
	LCD1602_write(0,0x80);
	LCD1602_writebyte("CH2O:");  	  //显示当前的甲醛浓度值
	LCD1602_write(1,0x30+ch2o/10000%10);
	LCD1602_writebyte(".");
	LCD1602_write(1,0x30+ch2o/1000%10);
	LCD1602_write(1,0x30+ch2o/100%10);
	LCD1602_write(1,0x30+ch2o/10%10);
	LCD1602_write(1,0x30+ch2o%10);
	LCD1602_writebyte("mg/m3");

	LCD1602_write(0,0xc0);
	LCD1602_writebyte("CH2O_H:");	  //显示甲醛上限值
	LCD1602_write(1,0x30+ch2o_H/100%10);
	LCD1602_writebyte(".");
	LCD1602_write(1,0x30+ch2o_H/10%10);
	LCD1602_write(1,0x30+ch2o_H%10);
	LCD1602_writebyte("mg/m3");	  //毫克每立方米
}


void proc()   //超限处理
{
	if(ch2o/100>=ch2o_H)  //如果当前甲醛浓度超出甲醛浓度上限
	{
		led_1=1;		   //对应指示灯点亮
		led_2=0;
		beep1=1;		  //开启蜂鸣器报警
	}else	   //否则
	{
		led_1=0;	   //对应指示灯点亮
		led_2=1;
		beep1=0;	   //开启蜂鸣器报警
	}
}


void key()
{
	if(!key_1)   //判断按下
	{
		ms=sec=0;
		delay(888);   //按键延时去抖
		if(!key_1)  //判断按下
		{
			if(ch2o_H<700)ch2o_H++;
			ms=sec=0;	  //清楚按键按下计时  重新计时
			while(!key_1)	 //按键判断释放
			{
				show();
				proc();
			}
			SectorErase(0x2000);	 //保存上限值
			byte_write(0x2000,ch2o_H/256);
			byte_write(0x2001,ch2o_H%256);	
		}
	}

	if(!key_2)    //判断按下
	{
		ms=sec=0;
		delay(888);  //按键延时去抖
		if(!key_2)  //判断按下
		{
			if(ch2o_H>0) ch2o_H--;
			ms=sec=0;
			while(!key_2)	//按键判断释放
			{
				show();
				proc();
			}
			SectorErase(0x2000);	 //保存上限值
			byte_write(0x2000,ch2o_H/256);
			byte_write(0x2001,ch2o_H%256);
		}
	}

}

void main()
{
	uchar h,l;
	LCD1602_cls();	  //LCD 1602   调用初始化程序
	TMOD=0x21;	//配置定时
	TH0=0x4c;		//50ms  定时赋值
	TL0=0x00;
	ET0=1;
	TR0=1;
	TH1=0xfd;		//串口波特率定时初始
	TL1=0xfd;
	SCON=0x50;	//只发送
	EA=1;		//打开定时总中断
	ES=1;		//打开串口中断				
	TR1=1;
	h=byte_read(0x2000);
	l=byte_read(0x2001);   //读取保存的数据
	ch2o_H=h*256+l;
	if(ch2o_H>700)
	ch2o_H=80;
	while(1)
	{
		show();		 //显示函数
		key();		 //按键处理程序
		proc();		 //超限处理程序
	}
}


void UART_1() interrupt 1 
{
	TH0=0x4c;
	TL0=0x00;
	ms++;
	if(ms%2==0)   //长按按键计数处理
	{
		if(sec>1)
		{
			if(!key_1)	//设置按键长按处理
			{
				if(ch2o_H<700)ch2o_H++;
			}
			if(!key_2)
			{
				if(ch2o_H>0) ch2o_H--;
			}
		}
	}
	if(ms%10==0)
	{
		if(beep1==1)	//蜂鸣器报警处理
		{
			beep=!beep;
		}else
		{
			beep=1;
		}
	}
	if(ms>19)	   //1s 定时
	{
		ms=0;
		sec++;
		
	}
} 

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;

		}
	}
}               

 

你可能感兴趣的:(51单片机实例)