单片机甲醛浓度报警器由51单片机+ZE08-CH2O甲醛浓度传感器+LCD1602液晶显示+LED灯+按键+蜂鸣器构成。
具体功能:
1、ZE08-CH2O检测当前甲醛浓度值并用LCD1602实时显示;
2、通过按键可设置报警最小浓度。当实际测出的甲醛浓度大于设定的浓度时就会使得蜂鸣器、LED灯报警;
3、LED灯显示正常工作状态和报警状态;
4、LCD1602液晶显示所测的甲醛浓度值和设置的报警阈值。
本设计是单片机要完成功能就是检测甲醛的浓度并在液晶上显示,当甲醛浓度超过用户设置的上限值发怵提示报警。
#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;
}
}
}