1、方案设计
本设计采用由STC89C52单片机最小系统、GP2Y1010AU粉尘传感器、ADC0832模数转换器模块、LCD1602液晶模块、电源模块、温湿度传感器HDT11、蜂鸣器报警模块和按键模块模块组成。单片机实时通过ADC0832转换芯片采集GP2Y1010AU粉尘传感器的粉尘的浓度,通过单片机的数据转换处理后在液晶屏上显示空气中的质量,当测量空间中的粉尘浓度大于设置粉尘浓度时,蜂鸣器和发光二极管发出声光报警。同时检测室内温湿度传感器上温度,湿度的测量值,当温度湿度的测量值大设置值上限或者小于设置值的下限值发出声光报警。粉尘的浓度报警值,温湿度的上下限报警值可以通过按键进行设置。系统总体框图如图2-1所示:
2、实物图
3、原理图
4、PCB
5、部分程序
#include"LCD1602.h" //添加LCD1602头文件
#include"dht11.h" //添加DHT11头文件
#include"adc0832.h"
#include<math.h>
sbit BUZZER = P1^3; //蜂鸣器驱动端口==P1^3
sbit Reduc = P3^2; //按键键输入端口==P1^7
sbit Add = P3^3; //按键加输入端口==P3^1
sbit Mode = P3^4; //按键加输入端口==P3^1
sbit LED1=P2^0;
sbit LED2=P2^1;
uchar Rx_buf[4],Rxnum=0;
uchar T1L=15,T1H=35,R1L=30,R1H=80;
void InitUART(void) //这是串口的基本配置,配置他的波特率是9600.这些参数都是标准的。
{
TMOD = 0x20;
SCON = 0x50;
TH1 = 0xFD;
TL1 = TH1;
PCON = 0x00;
EA = 1;
ES = 1;
TR1 = 1;
}
/*
* UART 发送一字节
*/
void UART_send_byte(char dat)
{
SBUF = dat;
while (TI == 0);
TI = 0;
}
/*
* UART 发送字符串
*/
void UART_send_string(unsigned char *buf)
{
while (*buf != '\0')
{
UART_send_byte(*buf++);
}
}
/************************************************
** 函数名称 : void main(void)
** 函数功能 : 主函数
** 输 入 : 无
** 输 出 : 无
** 说 明 :
************************************************/
void main(void)
{
double PM,pm1,pm2;
int PMVAL=0,HPM=200,PM_count=0,pm1_count=0;
uchar T1_data=0,R1_data=0,T2_data=0,R2_data=0;//温度、湿度变量
uchar shezhi_flag=1,Mode_flag=1,n=1;//设置变量
uchar bueezr_flag=0,count=0,buzzer_time=9;//蜂鸣器报警变量
uint Mode_count=0;
uchar disp[16] ={"PM2.5:0000ug/m3 "};
uchar disp1[16]= {"T :00C RH:00%"};
uchar Tx_Buf[15];
InitUART(); //初始化串口
LCD_Init();
WriteChar(1,0,16,disp); //在第一行显示‘内容’
WriteChar(2,0,16,disp1); //在第二行显示‘内容’
while(1)
{
T1_data=Read_TRH(0,0);//温度
disp1[3]=T1_data/10+0x30;//十位
disp1[4]=T1_data%10+0x30;//个位
R1_data=Read_TRH(1,0);//湿度
disp1[13]=R1_data/10+0x30;//十位
disp1[14]=R1_data%10+0x30;//个位
pm1+=read_data(1);
if(++PM_count>=20)
{
PM_count=0;
pm1=pm1/20;
pm2+=pm1;
pm1=0;
if(++pm1_count>=5)
{
pm1_count=0;
PM=pm2/5;
PM=PM*50/255;
PM-=4;
PM/=5;
PM*=1000;
PMVAL=PM;
PMVAL+=235; PMVAL=PMVAL/9;
if(PMVAL>=9999)PMVAL=9999;
WriteCOMDATA(0x86,0);
if(PMVAL<0)//PMVAL=0;
{WriteCOMDATA(0+0x30,1);PMVAL=abs(PMVAL);}
else WriteCOMDATA(PMVAL/1000+0x30,1);
WriteCOMDATA(PMVAL/100%10+0x30,1);
WriteCOMDATA(PMVAL/10%10+0x30,1);
WriteCOMDATA(PMVAL%10+0x30,1);
PM=pm1=pm2=0;
}
}
/*调用报警函数,温湿度是否在设定范围内*/
//温度值与报警值比较
if(T1_data<T1L)
{
bueezr_flag=1;//报警标志位置1
}
else if(T1_data>T1H)
{
bueezr_flag=1;//报警标志位置1
}
//湿度值与报警值比较
if(R1_data<R1L)
{
bueezr_flag=1;//报警标志位置1
}
else if(R1_data>R1H)
{
bueezr_flag=1;//报警标志位置1
}
//PM值与报警值比较
if(PMVAL>HPM)
{
bueezr_flag=1;
}
if(T1_data>T1L&&T1_data<T1H && R1_data>R1L&&R1_data<R1H && PMVAL<HPM)
{
bueezr_flag=0;
BUZZER=1;
}
/*******蜂鸣器报警********/
count++;if(count>buzzer_time*10)count=buzzer_time+1;
if(count%buzzer_time==0 && bueezr_flag)
{
BUZZER=~BUZZER;//蜂鸣器取反 发出声音提示
}
/*******Mode键设置报警参数********/
if(Mode==0 && Mode_flag)
{
WriteCOMDATA(0x0F,0);//LCD显示光标
Delay(100);
if(Mode==0)
{
BUZZER=1;
bueezr_flag=0;
Mode_flag=0;
shezhi_flag=1;
n=1;
while(1)
{
switch(shezhi_flag)
{
case 1:
if(n)
{
n=0;
WriteChar(1,0,16,"T1L:00C T1H:00C");//在第一行显示内容
WriteChar(2,0,16,"R1L:00% R1H:00%");//在第二行显示内容
WriteCOMDATA(0x8D,0);WriteCOMDATA(T1H/10+0x30,1);
WriteCOMDATA(0x8E,0);WriteCOMDATA(T1H%10+0x30,1);
WriteCOMDATA(0xC4,0);WriteCOMDATA(R1L/10+0x30,1);
WriteCOMDATA(0xC5,0);WriteCOMDATA(R1L%10+0x30,1);
WriteCOMDATA(0xCD,0);WriteCOMDATA(R1H/10+0x30,1);
WriteCOMDATA(0xCE,0);WriteCOMDATA(R1H%10+0x30,1);
}
WriteCOMDATA(0x84,0);WriteCOMDATA(T1L/10+0x30,1);
WriteCOMDATA(0x85,0);WriteCOMDATA(T1L%10+0x30,1);
WriteCOMDATA(0x85,0);
break;
case 2:
WriteCOMDATA(0x8D,0);WriteCOMDATA(T1H/10+0x30,1);
WriteCOMDATA(0x8E,0);WriteCOMDATA(T1H%10+0x30,1);
WriteCOMDATA(0x8E,0);
break;
case 3:
WriteCOMDATA(0xC4,0);WriteCOMDATA(R1L/10+0x30,1);
WriteCOMDATA(0xC5,0);WriteCOMDATA(R1L%10+0x30,1);
WriteCOMDATA(0xC5,0);
break;
case 4:
WriteCOMDATA(0xCD,0);WriteCOMDATA(R1H/10+0x30,1);
WriteCOMDATA(0xCE,0);WriteCOMDATA(R1H%10+0x30,1);
WriteCOMDATA(0xCE,0);
break;
case 5:
if(n)
{
n=0;
WriteChar(1,0,16," PM2.5 SET ");//在第一行显示内容
WriteChar(2,0,16,"HPM2.5: ug/m3");//在第二行显示内容
}
WriteCOMDATA(0xC7,0);
WriteCOMDATA(HPM/1000+0x30,1);
WriteCOMDATA(HPM/100%10+0x30,1);
WriteCOMDATA(HPM/10%10+0x30,1);
WriteCOMDATA(HPM%10+0x30,1);
WriteCOMDATA(0xCA,0);
break;
}
Delay(200);
//加
if(Reduc==0)
{
Delay(200);
//while(Reduc==0);
switch(shezhi_flag)
{
case 1:T1L+=1;break;
case 2:T1H+=1;break;
case 3:R1L+=1;break;
case 4:R1H+=1;break;
case 5:HPM+=1;break;
}
}
//减
if(Add==0)
{
Delay(200);
//while(Add==0);
switch(shezhi_flag)
{
case 1:T1L-=1;break;
case 2:T1H-=1;break;
case 3:R1L-=1;break;
case 4:R1H-=1;break;
case 5:HPM-=1;break;
}
}
//短按切换设置项目 长按退出设置页面
if(Mode==0)
{
Delay(300);
while(Mode==0)
{
Delay(300);
Mode_count++;
if(Mode_count>6)
{
WriteChar(1,0,16,"PM2.5:0000ug/m3 ");//在第一行显示内容
WriteCOMDATA(0x86,0);
if(PMVAL<0)//PMVAL=0;
{WriteCOMDATA(0+0x30,1);PMVAL=abs(PMVAL);}
else WriteCOMDATA(PMVAL/1000+0x30,1);
WriteCOMDATA(PMVAL/100%10+0x30,1);
WriteCOMDATA(PMVAL/10%10+0x30,1);
WriteCOMDATA(PMVAL%10+0x30,1);
WriteChar(2,0,16,disp1); //在第二行显示内容
}
}
if(Mode_count>6)
{
Mode_count=0;shezhi_flag=0;
//当下限值大于上限值时,蜂鸣器鸣叫1S提示,参数设置有误
if(T1L>T1H || R1L>R1H)
{
BUZZER=0;Delay(1000);BUZZER=1;
}
//否则退出设置页面,返回主页面
else
{
WriteCOMDATA(0x0C,0);//关闭LCD光标
Delay(10);
n=0;
break;
}
}
else Mode_count=0;
shezhi_flag++;
if(shezhi_flag>5)shezhi_flag=1;
if(shezhi_flag==1 || shezhi_flag==5)n=1;
pm1+=read_data(1);
if(++PM_count>=20)
{
PM_count=0;
pm1=pm1/20;
pm2+=pm1;
pm1=0;
if(++pm1_count>=15)
{
pm1_count=0;
PM=pm2/15;
PM=PM*50/255;
PM-=4;
PM/=5;
PM*=1000;
PMVAL=PM;
PMVAL-=480; PMVAL=PMVAL/3;
if(PMVAL>=9999)PMVAL=9999;
PM=pm1=pm2=0;
}
}
}
}
}
}
/********LCD1602显示********/
//WriteChar(1,0,16,disp); //在第一行显示‘内容’
WriteChar(2,0,16,disp1); //在第二行显示‘内容’
if(Mode_flag==0){Mode_count++;if(Mode_count>20){Mode_count=0;Mode_flag=1;}}
Tx_Buf[0]='T'; //帧头
Tx_Buf[1]=T1_data/10%10+0x30; //将温湿度数据送往发送数组,送给蓝牙模块让手机APP显示
Tx_Buf[2]=T1_data%10+0x30;
Tx_Buf[3]=R1_data/10%10+0x30;
Tx_Buf[4]=R1_data%10+0x30;
Tx_Buf[5]=PMVAL/1000+0x30; //将温湿度数据送往发送数组,送给蓝牙模块让手机APP显示
Tx_Buf[6]=PMVAL/100%10+0x30;
Tx_Buf[7]=PMVAL/10%10+0x30;
Tx_Buf[8]=PMVAL%10+0x30;
Tx_Buf[9]=0;//结束符
Tx_Buf[10]=0;//结束符
Tx_Buf[11]=0;//结束符
UART_send_string( Tx_Buf); //串口发送温湿度数据出去
}
}
/*****************串口接收中断函数,接收蓝牙模块的数据*********************/
void UARTInterrupt(void) interrupt 4
{
ES=0; //关闭中断
if(RI) //接收到数据
{
Rx_buf[Rxnum]=SBUF; //接收数据进数组
if(Rx_buf[Rxnum]==0x08)
Rxnum=0;
else
Rxnum++;
if(Rx_buf[0]==0x01)//LED1灯
{
if(Rx_buf[1]==0x01)//开灯
LED1=0;//开灯
else
LED1=1; //关灯
}
if(Rx_buf[0]==0x02)//LED2灯
{
if(Rx_buf[1]==0x01)//开灯
LED2=0;//开灯
else
LED2=1; //关灯
}
}
RI=0;
ES=1; //关闭中断
}