加入星計劃,您可以享受以下權(quán)益:

  • 創(chuàng)作內(nèi)容快速變現(xiàn)
  • 行業(yè)影響力擴散
  • 作品版權(quán)保護
  • 300W+ 專業(yè)用戶
  • 1.5W+ 優(yōu)質(zhì)創(chuàng)作者
  • 5000+ 長期合作伙伴
立即加入

51單片機的家居空氣質(zhì)量監(jiān)測系統(tǒng)proteus仿真設(shè)計

07/31 09:11
1714
服務(wù)支持:
技術(shù)交流群

完成交易后在“購買成功”頁面掃碼入群,即可與技術(shù)大咖們分享疑惑和經(jīng)驗、收獲成長和認同、領(lǐng)取優(yōu)惠和紅包等。

虛擬商品不可退

當(dāng)前內(nèi)容為數(shù)字版權(quán)作品,購買后不支持退換且無法轉(zhuǎn)移使用。

加入交流群
掃碼加入
獲取工程師必備禮包
參與熱點資訊討論
放大
實物圖
相關(guān)方案
  • 方案介紹
  • 相關(guān)文件
  • 推薦器件
  • 相關(guān)推薦
  • 電子產(chǎn)業(yè)圖譜
申請入駐 產(chǎn)業(yè)圖譜

本設(shè)計僅供參考
51單片機的家居空氣質(zhì)量監(jiān)測系統(tǒng)(proteus仿真+程序+原理圖+PCB
原理圖:Altium Designer或Protel 99 SE
仿真版本:proteus8.9
程序編譯器:keil 4
編號:C0038
資料下載鏈接

功能描述:
1、可同時檢測溫度、濕度、PM2.5濃度并同時在液晶上面顯示;
2、可以通過按鍵設(shè)置溫度上下限、濕度上下限和PM2.5濃度上限報警值;
3、超限啟動聲光報警提醒;

實物圖:

在這里插入圖片描述
在這里插入圖片描述

仿真圖(源文件):

在這里插入圖片描述

在這里插入圖片描述
在這里插入圖片描述

原理圖(提供源文件):

在這里插入圖片描述

PCB圖(提供源文件):

在這里插入圖片描述

源程序(提供源文件):
讀取溫度

/*********************************************************/
// 讀取DHT11的一幀數(shù)據(jù),濕高、濕低(0)、溫高、溫低(0)、校驗碼
/*********************************************************/
void ReadDhtData()
{    	 
	uchar HumiHig;		// 濕度高檢測值
	uchar HumiLow;		// 濕度低檢測值 
	uchar TemHig;			// 溫度高檢測值
	uchar TemLow;			// 溫度低檢測值
	uchar check;			// 校驗字節(jié) 
	
	DHT11_P=0;				// 主機拉低
	DelayMs(20);			// 保持20毫秒
	DHT11_P=1;				// DATA總線上拉電阻拉高

	Delay10us();	 		// 延時等待30us
	Delay10us();
	Delay10us();

	while(!DHT11_P);	// 等待DHT的低電平結(jié)束
	while(DHT11_P);		// 等待DHT的高電平結(jié)束

	//進入數(shù)據(jù)接收狀態(tài)
	HumiHig = DhtReadByte(); 	// 濕度高8位
	HumiLow = DhtReadByte(); 	// 濕度低8為,總為0
	TemHig  = DhtReadByte(); 	// 溫度高8位 
	TemLow  = DhtReadByte(); 	// 溫度低8為,總為0 
	check   = DhtReadByte();	// 8位校驗碼,其值等于讀出的四個字節(jié)相加之和的低8位

	DHT11_P=1;				// 拉高總線

	if(check==HumiHig + HumiLow + TemHig + TemLow) 		// 如果收到的數(shù)據(jù)無誤
	{
		temp=TemHig; 			// 將溫度的檢測結(jié)果賦值給全局變量temp
		humi=HumiHig;			// 將濕度的檢測結(jié)果賦值給全局變量humi
	}
}


顯示函數(shù)

/*********************************************************/
// 1602液晶寫命令函數(shù),cmd就是要寫入的命令
/*********************************************************/
void LcdWriteCmd(uchar cmd)
{ 
	LcdRs_P = 0;
	LcdRw_P = 0;
	LcdEn_P = 0;
	P0=cmd;
	DelayMs(2);
	LcdEn_P = 1;    
	DelayMs(2);
	LcdEn_P = 0;	
}


/*********************************************************/
// 1602液晶寫數(shù)據(jù)函數(shù),dat就是要寫入的數(shù)據(jù)
/*********************************************************/
void LcdWriteData(uchar dat)
{
	LcdRs_P = 1; 
	LcdRw_P = 0;
	LcdEn_P = 0;
	P0=dat;
	DelayMs(2);
	LcdEn_P = 1;    
	DelayMs(2);
	LcdEn_P = 0;
}


/*********************************************************/
// 1602液晶初始化函數(shù)
/*********************************************************/
void LcdInit()
{
	LcdWriteCmd(0x38);        // 16*2顯示,5*7點陣,8位數(shù)據(jù)口
	LcdWriteCmd(0x0C);        // 開顯示,不顯示光標(biāo)
	LcdWriteCmd(0x06);        // 地址加1,當(dāng)寫入數(shù)據(jù)后光標(biāo)右移
	LcdWriteCmd(0x01);        // 清屏
}


/*********************************************************/
// 液晶光標(biāo)定位函數(shù)
/*********************************************************/
void LcdGotoXY(uchar line,uchar column)
{
	// 第一行
	if(line==0)        
		LcdWriteCmd(0x80+column); 
	 // 第二行
	if(line==1)        
		LcdWriteCmd(0x80+0x40+column); 
}


/*********************************************************/
// 液晶輸出數(shù)字(PM2.5的)
/*********************************************************/
void LcdPrintNum1(uint num)
{
	LcdWriteData(num/100+48);					// 百位
	LcdWriteData(num%100/10+48);			// 十位
	LcdWriteData(num%10+48); 					// 個位
}


/*********************************************************/
// 液晶輸出數(shù)字(溫濕度的)
/*********************************************************/
void LcdPrintNum2(uchar num)
{
	LcdWriteData(num/10+48);					// 十位
	LcdWriteData(num%10+48); 					// 個位
}



/*********************************************************/
// 液晶輸出字符串函數(shù)
/*********************************************************/
void LcdPrintStr(uchar *str)
{
	while(*str!='?')
		LcdWriteData(*str++);
}


/*********************************************************/
// 液晶顯示內(nèi)容初始化
/*********************************************************/
void LcdShowInit()
{
	LcdGotoXY(0,0);										// 液晶光標(biāo)定位到第0行第0列
	LcdPrintStr(" PM2.5:   ug/m3 ");	// 顯示內(nèi)容
	LcdGotoXY(1,0);										// 液晶光標(biāo)定位到第1行第0列
	LcdPrintStr("T:   C   H:  %RH");	// 顯示內(nèi)容
	LcdGotoXY(1,4);										// 溫度單位攝氏度上面的圓圈符號
	LcdWriteData(0xdf);	
}

按鍵掃描函數(shù)

/*********************************************************/
// 按鍵掃描
/*********************************************************/
void KeyScanf()
{
	if(KeySet_P==0)		// 判斷設(shè)置按鍵是否被按下
	{
		EA=0;
		
		/*將液晶顯示改為設(shè)置溫度的頁面****************************************************/
		LcdWriteCmd(0x01);				  	
		LcdGotoXY(0,0);
		LcdPrintStr("Temperature Set ");
		LcdGotoXY(1,0);
		LcdPrintStr("      -    C    ");
		LcdGotoXY(1,10);	 					
		LcdWriteData(0xdf);			

		LcdGotoXY(1,4);	 					// 在液晶上填充溫度的下限值	
		LcdPrintNum2(AlarmTL);	
		LcdGotoXY(1,7);	 					// 在液晶上填充溫度的上限值
		LcdPrintNum2(AlarmTH);

		LcdGotoXY(1,5);	 					// 光標(biāo)定位到第1行第5列
		LcdWriteCmd(0x0f);				// 光標(biāo)閃爍
		
		DelayMs(10);	  					// 去除按鍵按下的抖動
		while(!KeySet_P);	 				// 等待按鍵釋放
		DelayMs(10);					  	// 去除按鍵松開的抖動

		/*設(shè)置溫度的下限值****************************************************************/
		while(KeySet_P)						// “設(shè)置鍵”沒有被按下,則一直處于溫度下限的設(shè)置
		{
			if(KeyDown_P==0)				// 判斷 “減按鍵“ 是否被按下		
			{
				if(AlarmTL>0)					// 只有當(dāng)溫度下限值大于0時,才能減1
					AlarmTL--;
				LcdGotoXY(1,4);	 			// 重新刷新顯示更改后的溫度下限值	
				LcdPrintNum2(AlarmTL);  		
				LcdGotoXY(1,5);				// 重新定位閃爍的光標(biāo)位置
				DelayMs(350);					// 延時
			}
			if(KeyUp_P==0)		  		// 判斷 “加按鍵“ 是否被按下
			{
				if(AlarmTL<99)	   		// 只有當(dāng)溫度下限值小于99時,才能加1
					AlarmTL++;
				LcdGotoXY(1,4);	 	 		// 重新刷新顯示更改后的溫度下限值
				LcdPrintNum2(AlarmTL);
				LcdGotoXY(1,5);				// 重新定位閃爍的光標(biāo)位置
				DelayMs(350);					// 延時
			}	
		}

		LcdGotoXY(1,8);
		DelayMs(10);	  					// 去除按鍵按下的抖動
		while(!KeySet_P);	 				// 等待按鍵釋放
		DelayMs(10);					  	// 去除按鍵松開的抖動

		/*設(shè)置溫度的上限值****************************************************************/	
		while(KeySet_P)	  				// “設(shè)置鍵”沒有被按下,則一直處于溫度上限的設(shè)置
		{
			if(KeyDown_P==0)				// 判斷 “減按鍵“ 是否被按下
			{
				if(AlarmTH>0)  				// 只有當(dāng)溫度上限值大于0時,才能減1			
					AlarmTH--;
				LcdGotoXY(1,7);	 	  	// 重新刷新顯示更改后的溫度上限值
				LcdPrintNum2(AlarmTH);
				LcdGotoXY(1,8);				// 重新定位閃爍的光標(biāo)位置
				DelayMs(350);					// 延時
			}
			if(KeyUp_P==0)			   	// 判斷 “加按鍵“ 是否被按下
			{
				if(AlarmTH<99)	 			// 只有當(dāng)溫度上限值小于99時,才能加1
					AlarmTH++;
				LcdGotoXY(1,7);				// 重新刷新顯示更改后的溫度上限值 	
				LcdPrintNum2(AlarmTH);
				LcdGotoXY(1,8);				// 重新定位閃爍的光標(biāo)位置
				DelayMs(350);					// 延時
			}								 
		}

		/*將液晶顯示改為設(shè)置濕度的頁面****************************************************/
		LcdWriteCmd(0x01);				  	
		LcdGotoXY(0,0);
		LcdPrintStr("  Humidity Set  ");
		LcdGotoXY(1,0);
		LcdPrintStr("      -   %RH   ");		

		LcdGotoXY(1,4);	 					// 在液晶上填充濕度的下限值	
		LcdPrintNum2(AlarmHL);	
		LcdGotoXY(1,7);	 					// 在液晶上填充濕度的上限值
		LcdPrintNum2(AlarmHH);

		LcdGotoXY(1,5);	 					// 光標(biāo)定位到第1行第5列
		
		DelayMs(10);	  					// 去除按鍵按下的抖動
		while(!KeySet_P);	 				// 等待按鍵釋放
		DelayMs(10);
		
		/*設(shè)置濕度的下限值****************************************************************/
		while(KeySet_P)				 		// “設(shè)置鍵”沒有被按下,則一直處于濕度下限的設(shè)置
		{
			if(KeyDown_P==0)				// 判斷 “減按鍵“ 是否被按下
			{
				if(AlarmHL>0)	 				// 只有當(dāng)濕度下限值大于0時,才能減1
					AlarmHL--;
				LcdGotoXY(1,4);				// 重新刷新顯示更改后的濕度下限值 	
				LcdPrintNum2(AlarmHL);
				LcdGotoXY(1,5);				// 重新定位閃爍的光標(biāo)位置
				DelayMs(350);
			}
			if(KeyUp_P==0)			  	// 判斷 “加按鍵“ 是否被按下
			{
				if(AlarmHL<99)	  		// 只有當(dāng)濕度下限值小于99時,才能加1
					AlarmHL++;
				LcdGotoXY(1,4);	 		 	// 重新刷新顯示更改后的濕度下限值
				LcdPrintNum2(AlarmHL);
				LcdGotoXY(1,5);	  		// 重新定位閃爍的光標(biāo)位置
				DelayMs(350);					// 延時
			}	
		}

		LcdGotoXY(1,8);
		DelayMs(10);	  					// 去除按鍵按下的抖動
		while(!KeySet_P);	 				// 等待按鍵釋放
		DelayMs(10);					  	// 去除按鍵松開的抖動
		
		/*設(shè)置濕度的上限值****************************************************************/
		while(KeySet_P)				   	// “設(shè)置鍵”沒有被按下,則一直處于濕度上限的設(shè)置
		{
			if(KeyDown_P==0)		 		// 判斷 “減按鍵“ 是否被按下
			{
				if(AlarmHH>0)			  	// 只有當(dāng)濕度上限值大于0時,才能減1
					AlarmHH--;
				LcdGotoXY(1,7);	 		 	// 重新刷新顯示更改后的濕度上限值
				LcdPrintNum2(AlarmHH);
				LcdGotoXY(1,8);		   	// 重新定位閃爍的光標(biāo)位置
				DelayMs(350);
			}
			if(KeyUp_P==0)				 	// 判斷 “加按鍵“ 是否被按下
			{
				if(AlarmHH<99)				// 只有當(dāng)濕度上限值小于99時,才能加1
					AlarmHH++;
				LcdGotoXY(1,7);	 			// 重新刷新顯示更改后的濕度上限值	
				LcdPrintNum2(AlarmHH);
				LcdGotoXY(1,8);	 			// 重新定位閃爍的光標(biāo)位置
				DelayMs(350);					// 延時
			}	
		}

		/*將液晶顯示改為設(shè)置PM2.5的頁面****************************************************/
		LcdWriteCmd(0x01);				  	// 設(shè)置界面的顯示框架
		LcdGotoXY(0,0);
		LcdPrintStr("   PM2.5 Set    ");
		LcdGotoXY(1,0);
		LcdPrintStr("        ug/m3   ");
		LcdGotoXY(1,4);								// 顯示當(dāng)前的報警值
		LcdPrintNum1(AlarmPM);				

		LcdGotoXY(1,6);	 							// 光標(biāo)定位到第1行第6列
		DelayMs(10);	  							// 去除按鍵按下的抖動
		while(!KeySet_P);	 						// 等待按鍵釋放
		DelayMs(10);
		
		while(KeySet_P)				 				// “設(shè)置鍵”沒有被按下,則一直處于光強下限的設(shè)置
		{
			if(KeyDown_P==0)						// 判斷 “減按鍵“ 是否被按下
			{
				if(AlarmPM>1)							// 只有g(shù)AlarmPM大于1才能減1								
					AlarmPM--;				
				LcdGotoXY(1,4);						// 液晶光標(biāo)定位
				LcdPrintNum1(AlarmPM);		// 刷新改變后的報警值
				LcdGotoXY(1,6);
				DelayMs(200);							// 延時一下
			}
			if(KeyUp_P==0)			  			// 判斷 “加按鍵“ 是否被按下
			{
			if(AlarmPM<999)							// 只有g(shù)AlarmPM小于999才能加1
					AlarmPM++;				
				LcdGotoXY(1,4);						// 液晶光標(biāo)定位
				LcdPrintNum1(AlarmPM);		// 刷新改變后的報警值
				LcdGotoXY(1,6);
				DelayMs(200);							// 延時一下
			}	
		}

		/*完成設(shè)置,退出前的處理**********************************************************/
		LcdWriteCmd(0x0C);	  						// 取消光標(biāo)閃爍
		LcdShowInit();										// 液晶顯示為檢測界面的

		DelayMs(10);	  									// 去除按鍵按下的抖動
		while(!KeySet_P);	 								// 等待按鍵釋放
		DelayMs(10);					  					// 去除按鍵松開的抖動

		Sector_Erase(0x2000);			 				// 存儲之前必須先擦除
		EEPROM_Write(0x2000,AlarmTL);			// 把溫度下限存入到EEPROM的0x2000這個地址
		EEPROM_Write(0x2001,AlarmTH);			// 把溫度上限存入到EEPROM的0x2001這個地址
		EEPROM_Write(0x2002,AlarmHL);			// 把濕度下限存入到EEPROM的0x2002這個地址
		EEPROM_Write(0x2003,AlarmHH);			// 把濕度上限存入到EEPROM的0x2003這個地址
		EEPROM_Write(0x2004,AlarmPM/100);	// 把PM2.5存入到EEPROM的0x2004和0x2005這兩個地址
		EEPROM_Write(0x2005,AlarmPM%100);
		
		EA=1;
	}	
}

主函數(shù)

/*********************************************************/
// 主函數(shù)
/*********************************************************/
void main(void)
{
	uchar i;				// 循環(huán)變量
	uint ret;				// 保存PM2.5測量結(jié)果

	LcdInit();				    	// 液晶功能初始化
	LcdShowInit();					// 液晶顯示初始化
	UartInit();							// 串口初始化
	AlarmInit();						// 報警值初始化

	while(1)
	{
		/*PM2.5的讀取*/
		ret=0;											// 清零測量結(jié)果
		for(i=0;i<10;i++)						// 將最新的20個測量結(jié)果求和
		{
			ret=ret+Value[i];
		}
		ret=ret/10;									// 再除以20求得平均值
		pm=((ret*5)/1024.0)*180;		// 將讀取到的電壓值轉(zhuǎn)換為灰塵濃度值	
		LcdGotoXY(0,7);							// 液晶定位到第0行第6列
		LcdPrintNum1(pm);						// 顯示測量結(jié)果
		
		/*溫濕度讀取*/
		EA=0;
		ReadDhtData(); 							// 檢測溫濕度數(shù)據(jù);
		EA=1;
		LcdGotoXY(1,2);	 						// 定位到要顯示溫度的地方
		LcdPrintNum2(temp);					// 顯示溫度值
		LcdGotoXY(1,11);						// 定位到要顯示濕度的地方
		LcdPrintNum2(humi);					// 顯示濕度值
		
		// 報警判斷
		AlarmJudge();						
		
		/*按鍵掃描和延時*/
		for(i=0;i<30;i++)
		{
			KeyScanf();								// 按鍵判斷
			DelayMs(10);
		}
	}
}

在這里插入圖片描述

論文報告:
在這里插入圖片描述

  • 設(shè)計資料獲取聯(lián)系方式.doc

推薦器件

更多器件
器件型號 數(shù)量 器件廠商 器件描述 數(shù)據(jù)手冊 ECAD模型 風(fēng)險等級 參考價格 更多信息
ATXMEGA128A4U-MHR 1 Atmel Corporation RISC Microcontroller, 16-Bit, FLASH, AVR RISC CPU, 32MHz, CMOS, PQCC44, 7 X 7 MM, 1 MM HEIGHT, 0.50 MM PITCH, GREEN, PLASTIC, MO-220VKKD-3, VQFN-44
$4.48 查看
MKL02Z32VFG4R 1 Freescale Semiconductor RISC MICROCONTROLLER

ECAD模型

下載ECAD模型
暫無數(shù)據(jù) 查看
ATMEGA128A-AUR 1 Microchip Technology Inc IC MCU 8BIT 128KB FLASH 64TQFP

ECAD模型

下載ECAD模型
$7.69 查看

相關(guān)推薦

電子產(chǎn)業(yè)圖譜