DHT11和DHT22使用区别(基于STM32)

温湿度模块DHT11和DHT22区别

  • 介绍
  • DHT系列区别
    • 起始信号
      • 代码实现
    • 数据处理
      • 代码实现
  • 调试问题
    • DHT22读取失败
  • 实现代码

介绍

温湿度模块DHT11和DHT22小项目用得比较多,虽然二者均是1-wire协议,但是细节部分还是有所差异。1-wire协议我就不多介绍了,网上很详细。这里着重介绍二者使用的区别。

DHT11
DHT11和DHT22使用区别(基于STM32)_第1张图片
DHT22

DHT11和DHT22使用区别(基于STM32)_第2张图片

DHT系列区别

DHT11和DHT22

芯片手册
提取:hgew

起始信号

DHT11

DHT11和DHT22使用区别(基于STM32)_第3张图片

DHT11和DHT22使用区别(基于STM32)_第4张图片

DHT22

DHT11和DHT22使用区别(基于STM32)_第5张图片
DHT11和DHT22使用区别(基于STM32)_第6张图片

显然DHT11拉低要>18ms,而DHT22拉低只要>1ms就足够。

代码实现

/*
 * 一次完整的数据传输为40bit,高位先出
 * 8bit 湿度整数 + 8bit 湿度小数 + 8bit 温度整数 + 8bit 温度小数 + 8bit 校验和 
 */
uint8_t DHT11_Read_TempAndHumidity(DHT11_Data_TypeDef *DHT11_Data)
{  
	/*输出模式*/
	DHT11_Mode_Out_PP();
	/*主机拉低*/
	DHT11_Dout_0;
	
	/*延时18ms*/
	DHT11_DELAY_MS(18); //dht11
	//DHT11_DELAY_MS(2); //dht22
	
	/*总线拉高 主机延时30us*/
	DHT11_Dout_1; 

	DHT11_DELAY_US(30);   //延时30us

	/*主机设为输入 判断从机响应信号*/ 
	DHT11_Mode_IPU();

	/*判断从机是否有低电平响应信号 如不响应则跳出,响应则向下运行*/   
	if(DHT11_Dout_IN()==Bit_RESET)     
	{
		/*轮询直到从机发出 的80us 低电平 响应信号结束*/  
		while(DHT11_Dout_IN()==Bit_RESET);

		/*轮询直到从机发出的 80us 高电平 标置信号结束*/
		while(DHT11_Dout_IN()==Bit_SET);

		/*开始接收数据*/   
		DHT11_Data->humi_int= DHT11_ReadByte();

		DHT11_Data->humi_deci= DHT11_ReadByte();

		DHT11_Data->temp_int= DHT11_ReadByte();

		DHT11_Data->temp_deci= DHT11_ReadByte();

		DHT11_Data->check_sum= DHT11_ReadByte();


		/*读取结束,引脚改为输出模式*/
		DHT11_Mode_Out_PP();
		/*主机拉高*/
		DHT11_Dout_1;

		/*检查读取的数据是否正确*/
		if(DHT11_Data->check_sum == DHT11_Data->humi_int + DHT11_Data->humi_deci + DHT11_Data->temp_int+ DHT11_Data->temp_deci)
			return SUCCESS;
		else 
			return ERROR;
	}
	
	else
		return ERROR;
	
}

13行 DHT11_DELAY_MS(18); 14行 DHT11_DELAY_MS(2); //DHT11时,延时18ms;DHT22时,延时1ms(建议2ms,经测试1ms有可能读取失败)

数据处理

DHT11

DHT11和DHT22使用区别(基于STM32)_第7张图片
DHT11和DHT22使用区别(基于STM32)_第8张图片

DHT22

DHT11和DHT22使用区别(基于STM32)_第9张图片
DHT11和DHT22使用区别(基于STM32)_第10张图片

代码实现

/*
 * 一次完整的数据传输为40bit,高位先出
 * 8bit 湿度整数 + 8bit 湿度小数 + 8bit 温度整数 + 8bit 温度小数 + 8bit 校验和 
 */
uint8_t DHT11_Read_TempAndHumidity(DHT11_Data_TypeDef *DHT11_Data)
{  
	uint32_t humi=0;
	uint32_t temp =0;
	
	/*输出模式*/
	DHT11_Mode_Out_PP();
	/*主机拉低*/
	DHT11_Dout_0;
	/*延时2ms*/
	DHT11_DELAY_MS(2);

	/*总线拉高 主机延时30us*/
	DHT11_Dout_1; 

	DHT11_DELAY_US(30);   //延时30us

	/*主机设为输入 判断从机响应信号*/ 
	DHT11_Mode_IPU();

	/*判断从机是否有低电平响应信号 如不响应则跳出,响应则向下运行*/   
	if(DHT11_Dout_IN()==Bit_RESET)     
	{
		/*轮询直到从机发出 的80us 低电平 响应信号结束*/  
		while(DHT11_Dout_IN()==Bit_RESET);

		/*轮询直到从机发出的 80us 高电平 标置信号结束*/
		while(DHT11_Dout_IN()==Bit_SET);

		/*开始接收数据,需要修改的计算方式跟dht11不同*/   
		DHT11_Data->humi_int= DHT11_ReadByte();

		DHT11_Data->humi_deci= DHT11_ReadByte();

		DHT11_Data->temp_int= DHT11_ReadByte();

		DHT11_Data->temp_deci= DHT11_ReadByte();

		DHT11_Data->check_sum= DHT11_ReadByte();


		/*读取结束,引脚改为输出模式*/
		DHT11_Mode_Out_PP();
		/*主机拉高*/
		DHT11_Dout_1;

		/*检查读取的数据是否正确*/
		if(DHT11_Data->check_sum == DHT11_Data->humi_int + DHT11_Data->humi_deci + DHT11_Data->temp_int+ DHT11_Data->temp_deci)
		{	/*----------------------------------数据处理-----------------------*/
			/*----------------DHT22温湿度16bit精度,故需要分高低字节计算,且需要uint32_t变量装载---------------------*/
			/*-----------------------------湿度和温度的高八位需要乘以256再加上低八位---------------------------------*/
			humi = DHT11_Data->humi_int *256 + DHT11_Data->humi_deci;
			temp = DHT11_Data->temp_int *256 + DHT11_Data->temp_deci;
			
			
			DHT11_Data->humi_int = (uint8_t)(humi*0.1);
			DHT11_Data->humi_deci = humi%10;
			
			DHT11_Data->temp_int = (uint8_t)(temp*0.1);
			DHT11_Data->humi_deci = temp%10;
			
			return SUCCESS;
		}
		else 
			return ERROR;
	}
	
	else
		return ERROR;
	
}

此处并没有错,我的程序通过改变宏定义即可切换dht11或dht22测量。所以函数名称没改回来。

调试问题

DHT22读取失败

1.主机拉低发送起始信号延时1ms时会读取失败,但延时2ms能完美解决问题。
2.两次数据读取时间过短,建议大于2s。

实现代码

代码地址

你可能感兴趣的:(stm32,计算机,编程,stm32,嵌入式,单片机)