數字溫濕度傳感器DHT11--操作源代碼


//IO定義
#define		P_DataIN_DHT11		PB0_IN
#define		P_DataOUT_DHT11		PB0_OUT
//宏定義
#define	  BSET_DHT11			P_DataOUT_DHT11 = 1 
#define	  BCLR_DHT11			P_DataOUT_DHT11 = 0 



//***************************************
// 模塊功能:讀取DHT11的數據
// 該模塊為溫濕度傳感器 當主機給啟動信號后
// 該模塊會連續發出5個字節的數據 共耗時約4MS
// 第一二個字節為濕度數據的整數與小數部分
// 第三四個字節為溫度數據的整數與小數部分
// 第五個字節為校驗碼 它是前四個數據相加后的后8位的數值
// 程序帶未傳感器未連接檢測 及讀數據超時處理
//***************************************

//*************************************
// 函數名稱:VerificaDHT11Data
// 函數功能:效驗DHT11所讀的數據是否正確
// 入口參數:
// 出口參數:校驗正確返回1 否則返回0
// 備注: 
//***************************************/
uint8 VerificaDHT11Data(uint8 *a)
{
		uint8 i ;
		uint8 Tmp = 0 ;
		uint16 wTmp = 0 ;
		
		for(i=0;i<4;i++)
		{
				wTmp += a[i] ;
		}
		Tmp = (uint8)(wTmp & 0x00ff) ; //取低8位數據	

		if(Tmp == a[4])
		{
				return 1 ;
		}
		else
		{
				return 0 ;
		}	
}
//*************************************
// 函數名稱:ReadPinDHT11
// 函數功能:讀管腳並濾波 
// 入口參數:
// 出口參數:返回管腳狀態 Fcpu=16M時 耗時6US
//***************************************/
uint8 ReadPinDHT11(void) 
{
		uint8 Tcon = 0 ;
		uint8 i ;
		
		for(i=0;i<5;i++)  //讀5次
		{	
				_asm("nop") ;//延時
				_asm("nop") ;
				_asm("nop") ;
				_asm("nop") ;
				_asm("nop") ;
				
				if(P_DataIN_DHT11 == 1)	
				{
						Tcon ++ ;
				}				 
		}
		if(Tcon >= 3) //讀狀態為1的次數大於3次
		{
				return 1 ;
		}
		else 
		{
				return 0 ;
		}			
}
//=====讀一字節數據======
uint8 ReadDHT11DataByte(uint8 InValue)
{
		uint8 Data = 0 ;
		uint8 i = 0 ;
		uint8 ucTOver = 0 ; //等待超時時間
		
		for(i=0;i<8;i++)
		{
				ucTOver = 30  ;  //200U
				while(!ReadPinDHT11()&&(ucTOver--)) ; //等待高電平的到來
				Nopt(VT_DLY40U) ; //延時40U
				
				Data <<= 1;
				
				ucTOver = 30  ;  //200U
				if(ReadPinDHT11()&&(ucTOver--)) //判斷IO是否還是被拉高的狀態
				{
						Data |= 0x01 ; 
						//讀最后一BIT數據時 不等待高電平
						ucTOver = 30  ;  //200U
						while(ReadPinDHT11()&&(ucTOver--)) ; //等待IO被外設拉低
				}
		}
		
		return Data ;
}
//*************************************
// 函數名稱:ReadDH11Data
// 函數功能:讀取DHT
// 入口參數:
// 出口參數:返回讀取的數據 
// 當讀取到數據時 返回1 未讀取到數據返回0
//***************************************/
uint8 ReadDHT11Data(uint8 *a)
{	
		uint8 i ;		
		uint8 ucTOver = 0 ; //等待超時時間
		
		Nopt(VT_DLY40U) ; //延時40U
		
		if(ReadPinDHT11())
		{
				Nopt(VT_DLY40U) ; //延時40U
				 //從機一直沒有回應 直接退出
				if(ReadPinDHT11())
				{
						return 0 ;
				}
		}
		
		//等待從機回應信號結束
		ucTOver = 30  ;  //200U
		while(!ReadPinDHT11()&&(ucTOver--)) ; //從機拉低時一直等待
		ucTOver = 30  ;  //200U
		while(ReadPinDHT11()&&(ucTOver--)) ; //從機拉高時一直等待 
		
		for(i=0;i<5;i++) //讀5字節數據
		{
				*a = ReadDHT11DataByte(i) ;
				a++ ;
		}	

		return 1 ;
}


//*************************************
// 函數名稱:CmdDHT11Data
// 函數功能:讀DHT11的濕度 溫度
// 入口參數:延時時間
// 出口參數:無
//***************************************/
void CmdDHT11Data(void)
{	
		static uint16 Tcyc = 0 ;
		static uint8 Tcon = 0 ;
		static uint8 TNum = 0 ;
		uint8 Tmp = 0 ;
		uint16 wTmp = 0 ;
		uint8 i ;		
	
		Tcyc ++ ;
		if(Tcyc >= (VT_1S*VT_READDHT11)) //1s讀取一次數據
		{
				Tcyc = 0 ;
				F_ReadD11 = 1 ; 
				Tcon = 0 ;
		}
		
		if(F_ReadD11) //准備啟動從機 1S動作一次
		{
				if(Tcon < 4) // 主機啟動 拉低40ms		
				{
						Tcon ++ ;
						BCLR_DHT11 ;
				}
				else 
				{		
						F_ReadD11 = 0 ;
						
						F_TestDH11 = 0 ; //讀數據前清掉工作正常標志
						
						for(i=0;i<5;i++) //清空數據緩存
						{
								aDHT11Data[i] = 0 ;
						}		
						
						BSET_DHT11 ;   //主機拉高 等待從機回應			
						//從DHT11讀數據
						Tmp = ReadDHT11Data(aDHT11Data) ;//
						
						BSET_DHT11 ;	//釋放總線
						
						if(Tmp != 0)//讀數據有效
						{	
								if(VerificaDHT11Data(aDHT11Data)) 
								{			
										F_ReadD11OK = 1 ;//校驗 成功	
										TNum = 0 ;
								}	
						}
						else  //傳感器未連接出錯
						{
								TNum ++ ;
								if(TNum >= 4)
								{
										TNum = 0 ;
										F_ERRD11 = 1 ;
								}
						}
							
				}
		}
}
//*************************************
// 函數名稱:CountDHT11
// 函數功能:計算濕度
// 入口參數:延時時間
// 出口參數:無
//***************************************/
void CountHumidity(void)
{
		uint8  Tmp ;
		static 	uint8	 R_Save[3];			
	
		if(!F_ReadD11OK) return ;
		F_ReadD11OK = 0 ;
		//對數據進行濾波取中值處理
		RMovData_Byte(R_Save,3);
		R_Save[0] =	aDHT11Data[0] ;	
		//保存結果		
		Humidity = Order_Byte(R_Save); //處理位數最大3位		
		
		F_TestDH11 = 1 ; //DHT11 工作正常
}
//======================================================
//=======main========================================
//======================================================
void main(void)
{
	while(1)
	{
		while(!F_10MS); // 主程序10MS跑一次
		F_10MS = 0 ;	

		CmdDHT11Data() ; //讀DHT11數據
		CountHumidity() ; // 計算濕度
	}	


}



免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM