3-基于单片机的按键、串口控制空气质量检测系统(气体传感器 酒精传感器 温度 湿度 报警 LCD1602 按键、串口控制)proteus,原理图、流程图、物料清单、仿真图、源代码
功能描述:
1、空气质量传感器用MQ135或GP2Y1014AU0F 酒精浓度传感器 用MQ3 温湿度传感器用DHT11
2、通过按键分别设置报警值,空气质量、温度、湿度过限则启动蜂鸣器报警
3、LCD显示当前空气质量、温湿度和报警值
4、通过串口显示当前系统检测的信息
5、串口传输与控制交互,通过串口调节阈值,同按键的功能(串口上传数据,遥控修改)
6、可按键控制也可以用串口遥控
资料包含:
1、proteus工程文件(.pdsprj)
2、原理图工程文件(.SchDoc)与PDF版本(.pdf)
3、流程图
4、物料清单excel表格(.xlsx)
5、源代码工程文件(.uvproj) keil4或带C51编译链的keil5
#include "reg51.h"
#include "ADC0832.h"
#include "lcd1602.h"
#include "DHT11.h"
sbit k1=P2^5;//按钮
sbit k2=P2^6;
sbit k3=P2^7;
sbit beep=P1^4;//蜂鸣器
//========================================
uchar air=0;//空气质量 0-100
uchar alc=0;//酒精检测 0-100
uchar time=0;//系统定时
uchar mode=0;//系统模式,测量、设置
uchar disp1[]="Air:00 ALC: ";
uchar disp2[]="T:00 C S:00%";
uchar disp3[]="A:00 T:00 S:00";
uchar disp4[]="J:00 00 00";
uchar air_lim=60,alc_lim=50,temp1=10,temp2=40,humi1=5,humi2=90;
uchar shidu=0;
//串口发送
void send(uchar i)
{
SBUF=i;
while(!TI);
TI=0;
}
//发送字符串
void fa(uchar *p)
{
while(*p!='\0')
{
if(*p!=0xdf)
send(*p);
p++;
}
}
//========================================
void disp()//显示阀值
{
write_string(1,0," ");
write_string(2,0," ");
disp3[2]=air_lim/10+0x30;
disp3[3]=air_lim%10+0x30;
disp3[7]=temp2/10+0x30;
disp3[8]=temp2%10+0x30;
disp3[12]=humi2/10+0x30;
disp3[13]=humi2%10+0x30;
disp4[2]=alc_lim/10+0x30;
disp4[3]=alc_lim%10+0x30;
disp4[7]=temp1/10+0x30;
disp4[8]=temp1%10+0x30;
disp4[12]=humi1/10+0x30;
disp4[13]=humi1%10+0x30;
write_string(1,0,disp3);
write_string(2,0,disp4);
//设置光标
switch(mode)
{
case 1:write_sfm(1,3);break;
case 2:write_sfm(1,8);break;
case 3:write_sfm(1,13);break;
case 4:write_sfm(2,3);break;
case 5:write_sfm(2,8);break;
case 6:write_sfm(2,13);
}
}
//主函数
void main()
{
init_1602();//初始化
disp2[4]=0xdf;
SCON=0X50; //设置为工作方式1
TMOD=0X21; //设置计数器工作方式2
TH1=0XFD;
TL1=0XFD;
ES=1; //打开接收中断
TR1=1; //打开计数器
TH0=0X3C;
TL0=0XB0;
ET0=1;//打开定时器0中断允许
EA=1;//打开总中断
TR0=1;//打开定时器
while(1)
{
if(!k1)//设置,确认
{
delay_uint(5000);//延时防抖
if(!k1)
{
if(mode<6)
mode++;
else
mode=0;
if(mode>0)
disp();
write_com(0x0e);
//设置光标
switch(mode)
{
case 1:write_sfm(1,3);break;
case 2:write_sfm(1,8);break;
case 3:write_sfm(1,13);break;
case 4:write_sfm(2,3);break;
case 5:write_sfm(2,8);break;
case 6:write_sfm(2,13);
}
while(!k1);
}
}
if(mode>0)//设置
{
if(!k2)//加
{
delay_uint(5000);//延时防抖
if(!k2)
{
switch(mode)
{
case 1://空气质量设置
if(air_lim<99)
air_lim++;
disp();
break;
case 2://温度上限
if(temp2<99)
temp2++;
disp();
break;
case 3://湿度上限
if(humi2<99)
humi2++;
disp();
break;
case 4://温度下限
if(temp1<temp2)
temp1++;
disp();
break;
case 5://湿度下限
if(humi1<humi2)
humi1++;
disp();
}
while(!k2);
}
}
if(!k3)//减
{
delay_uint(5000);//延时防抖
if(!k3)
{
switch(mode)
{
case 1://空气质量设置
if(air_lim>0)
air_lim--;
disp();
break;
case 2://温度上限
if(temp2>temp1)
temp2--;
disp();
break;
case 3://湿度上限
if(humi2>humi1)
humi2--;
disp();
break;
case 4://温度下限
if(temp1>0)
temp1--;
disp();
break;
case 5://湿度下限
if(humi1>0)
humi1--;
disp();
}
while(!k3);
}
}
}
}
}
//定时器0中断
void Timer0() interrupt 1
{
uint i=0,a=0;
if(time<10)//0.5s
time++;
else
{
time=0;
disp3[2]=air_lim/10+0x30; //阀值计算
disp3[3]=air_lim%10+0x30;
disp3[7]=temp2/10+0x30;
disp3[8]=temp2%10+0x30;
disp3[12]=humi2/10+0x30;
disp3[13]=humi2%10+0x30;
disp4[2]=alc_lim/10+0x30; //阀值计算
disp4[3]=alc_lim%10+0x30;
disp4[7]=temp1/10+0x30;
disp4[8]=temp1%10+0x30;
disp4[12]=humi1/10+0x30;
disp4[13]=humi1%10+0x30;
dht11_recive();//测量温湿度
shidu=dht11_dat[0];
i=ADC(1);//测量空气质量
a=ADC(2);
i=i*99/127;
air=99-i;
disp1[4]=air/10+0x30;
disp1[5]=air%10+0x30;
//酒精检测
a=a*99/127;
alc=99-a;
disp1[11]=alc/10+0x30;
disp1[12]=alc%10+0x30;
disp2[2]=dht11_dat[2]/10+0x30;
disp2[3]=dht11_dat[2]%10+0x30;
disp2[9]=shidu/10+0x30;
disp2[10]=shidu%10+0x30;
if(mode==0)//显示
{
write_string(1,0," ");
write_string(2,0," ");
write_string(1,0,disp1);
write_string(2,0,disp2);
//报警
if((air>air_lim)||(alc >alc_lim)||(dht11_dat[2]>temp2)||(dht11_dat[2]<temp1)||(shidu>humi2)||(shidu<humi1) )
beep=0;
else
{
beep=1;
write_com(0x0c);
}
if(air>air_lim)//设置报警光标
{
write_com(0x0e);
write_sfm(1,5);
}
if(alc>alc_lim)//设置报警光标
{
write_com(0x0e);
write_sfm(1,11);
}
if((dht11_dat[2]>temp2)||(dht11_dat[2]<temp1))
{
write_com(0x0e);
write_sfm(2,3);
}
if((shidu>humi2)||(shidu<humi1))
{
write_com(0x0e);
write_sfm(2,10);
}
}
//串口发送
fa(disp1);send(0x0d);
fa(disp2);send(0x0d);
fa(disp3);send(0x0d);
fa(" ");
fa(disp4);send(0x0d);
fa(" ");send(0x0d);
}
TH0=0X3C;
TL0=0XB0;
}