数字温湿度传感器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() ; // 计算湿度
	}	


}


原文地址:https://www.cnblogs.com/dyllove98/p/3215027.html