51单片机蓝牙空气质量PM2.5检测设计全套资料包含(仿真+原理图+PCB+源码+论文+学习资料)

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;	  //关闭中断
}
 

6、资料清单

  • 20
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

森旺电子

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值