数字温湿度传感器DHT11模块

1. 数字温湿度传感器DHT11

 

接口:建议连接线长度短于20米时用5K上拉电阻,大于20米时根据实际情况使用合适的上拉电阻。

 

2. 数字温湿度传感器模块DHT11实物、原理图

2.模块说明

2.1 DHT11产品概述

  • DHT11数字温湿度传感器是一款含有已校准数字信号输出的温湿度复合传感器。每个DHT11传感器都在极为精确的湿度校验室中进行校准。校准系数以程序的形式储存在OTP内存中,传感器内部在检测信号的处理过程中要调用这些校准系数。
  • 传感器包括一个电阻式感湿元件和一个NTC测温元件,并与一个高性能8位单片机相连接。
  • 单线制串行接口,使系统集成变得简易快捷。超小的体积、极低的功耗,信号传输距离可达20米以上,使其成为各类应用甚至最为苛刻的应用场合的最佳选则。

 

2.2 订货信息:

型号                测量范围 测湿精度测温精度 分辨力  封装
DHT11      20-90%RH  0-50℃ ±5%RH  ±2℃                14 针单排直插

 

2.3 性能参数

 

2.4 电源引脚

 

DHT11的供电电压为3-5.5V。传感器上电后,要等待1s 以越过不稳定状态,在此期间无需发送任何指令。电源引脚(VDD,GND)之间可增加一个100nF 的电容,用以去耦滤波。

2.5 串行接口(单线双向)

2.5.1 单总线工作原理:DATA 输出线用于单片机与DHT11之间的通讯,一次通讯时间4ms左右;单片机发送一次开始信号后,DHT11从低功耗模式转换到高速模式,等待主机开始信号结束后,DHT11发送响应信号,送出40bit的数据,并触发一次信号采集,用户可选择读取数据,采集数据后转换到低速模式;如果没有接收到主机发送的开始信号,DHT11不会主动进行温湿度采集。

2.5.2 数据格式:

  • 一次完整的数据传输为40bit,高位先出;   
  • 数据格式:8bit湿度整数数据+8bit湿度小数数据+8bi温度整数数据+8bit温度小数数据+8bit校验;
  • DHT11数据分小数部分和整数部分,当前小数部分用于以后扩展,现读出为零; 测量分辨率分别为8bit(温度)、8bit(湿度)
  • 数据传送正确时校验位等于“8bit湿度整数数据+8bit湿度小数数据+8bi温度整数数据+8bit温度小数数据”之和

 

通讯过程

 

2.5.3 开始信号与响应信号

开始信号:由于上拉电阻,总线空闲状态为高电平,主机发出开始信号,把总线拉低大于18ms,拉高电平延时等待20-40us后, 读取DHT11的响应信号;

响应信号:DHT11接收到主机的开始信号后,等待主机开始信号结束,发送80us低电平响应信号,再把总线拉高80us;主机发送开始信号结束后,可以切换到输入模式,总线由上拉电阻拉高或者输出高电平均可。

2.5.4 数据信号与结束信号

数据信号:每一bit数据都以50us低电平开始,高电平的长短决定数据位是0还是1,如下图所示:
结束信号:当最后一bit数据传送完毕后,DHT11拉低总线50us,随后总线由上拉电阻拉高进入空闲状态。

数字0信号表示方法

 

数字1信号表示方法

3.STM32程序与显示结果

 

 

//主函数
#include <stdio.h>	
#include "stm32f10x.h"
//#include "bsp_led.h"
#include "bsp_usart.h"
#include "bsp_rccclkconfig.h"
#include "dht11.h"
#include "bsp_systick.h"

extern uint8_t dat[5];

/**
  * @brief  主函数
  * @param  无  
  * @retval 无
  */
int main(void)
{	
	USART_Config();
	HSE_SetSysClk( RCC_PLLMul_6 );

	
	printf( "串口printf函数测试\n" );
	
	
	while (1)
	{
	if(DHT_Read())
			printf("湿度:%d%%,温度:%d度\r\n",dat[0],dat[2]);

		SysTick_Delay_ms(3000);
	}
}
/*********************************************END OF FILE**********************/

 

//dht11.c程序
#include "dht11.h"
#include "bsp_systick.h"

uint8_t dat[5]={0x00,0x00,0x00,0x00,0x00};
uint8_t sum=0;

//初始化为输出
void DHT11_GPIO_OUT(void)
{
	GPIO_InitTypeDef  GPIO_InitStructure;
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE); 
		
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; 
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(GPIOB, &GPIO_InitStructure);		
}
//初始化为输入
void DHT11_GPIO_IN(void)
{
	GPIO_InitTypeDef  GPIO_InitStructure;
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
		
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14;	
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; 
  GPIO_Init(GPIOB, &GPIO_InitStructure);					
}

//读一个字节
uint8_t DHT_Read_Byte(void)
{
	uint8_t temp;
	uint8_t ReadDat=0;
	
	uint8_t retry = 0;	
	uint8_t i;
	
	for(i=0;i<8;i++)
	{
		//数据信号低电平50us
		while(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_14)==0&&retry<100)
		{		
			SysTick_Delay_us(1);
			retry++;		
		}
		retry=0;
		SysTick_Delay_us(30);
		temp=0;//数字信号0,temp=0
		//数字0信号高电平持续28us,数字1信号高电平70us,延时30us以确认数字0或1
		if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_14)==1) temp=1;		
		while(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_14)==1&&retry<100)//数字1信号高电平剩余40us
		{		
			SysTick_Delay_us(1);
			retry++;
		}
		retry=0;
		ReadDat<<=1;
		ReadDat|=temp;
	}	
	return ReadDat;
}

uint8_t DHT_Read(void)
{
	uint8_t i;
	uint8_t retry = 0;
	
	//主机设置为输出,发送开始信号低电平18ms,高电平40us
	DHT11_GPIO_OUT();
	GPIO_ResetBits(GPIOB,GPIO_Pin_14);
	SysTick_Delay_ms(18);
	GPIO_SetBits(GPIOB,GPIO_Pin_14);
	SysTick_Delay_us(40);
	//主机设置为输入,检查并接收响应信号低电平80us,高电平80us
	DHT11_GPIO_IN();
	SysTick_Delay_us(20);
	//延时20us,低电平80us,还剩60us,检查是否是低电平以确定是否有响应信号
	if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_14)==0)
	{
		while(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_14)==0&&retry<100)//接收响应信号低电平剩余60us
		{
			SysTick_Delay_us(1);
			retry++;			
		}
		retry=0;//超过100us自动向下运行,以免卡死
		while(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_14)==1&&retry<100)//接收响应信号高电平80us
		{
			SysTick_Delay_us(1);
			retry++;			
		}
		retry=0;
		//接收8字节数据
		for(i=0;i<5;i++)
		{
			dat[i]=DHT_Read_Byte();
		}
		SysTick_Delay_us(50);//DHT11拉低总线50us作为结束信号,或者使用以下语句
				
//		while(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_14)==0&&retry<100)//接收响应信号低电平剩余60us
//		{
//			SysTick_Delay_us(1);
//			retry++;			
//		}
//		retry=0;
		
	}
	sum=dat[0]+dat[1]+dat[2]+dat[3];
	if(dat[4]==sum)
	{
		return 1;
	}
	else
		return 0;
}
//dth11.h程序
#ifndef __DHT11_H
#define __DHT11_H

#include "stm32f10x.h"


void DHT11_GPIO_OUT(void);
void DHT11_GPIO_IN(void);
uint8_t DHT_Read_Byte(void);
uint8_t DHT_Read(void);

#endif 
//延时.c函数
#include "bsp_systick.h"


#if 0
static __INLINE uint32_t SysTick_Config(uint32_t ticks)
{ 
	//  判断 tick 的值是否大于 2^24,如果大于,则不符合规则
  if (ticks > SysTick_LOAD_RELOAD_Msk)  return (1);

  // 初始化reload寄存器的值	
  SysTick->LOAD  = (ticks & SysTick_LOAD_RELOAD_Msk) - 1;
	
  // 配置中断优先级,配置为15,默认为最低的优先级
	NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1); 

  // 初始化counter的值为0	
  SysTick->VAL   = 0; 
  
  // 配置 systick 的时钟为 72M
  // 使能中断
	// 使能systick
  SysTick->CTRL  = SysTick_CTRL_CLKSOURCE_Msk | 
                   SysTick_CTRL_TICKINT_Msk   | 
                   SysTick_CTRL_ENABLE_Msk;                    
  return (0);                                                 
}
#endif


void SysTick_Delay_us(uint32_t us)
{
	uint32_t i;
	SysTick_Config(72);
	
	for(i=0; i<us; i++)
	{
		while( !((SysTick->CTRL) & (1<<16)) );
	}
	
	SysTick->CTRL &= ~ SysTick_CTRL_ENABLE_Msk;
}

void SysTick_Delay_ms(uint32_t ms)
{
	uint32_t i;
	SysTick_Config(72000);
	
	for(i=0; i<ms; i++)
	{
		while( !((SysTick->CTRL) & (1<<16)) );
	}
	
	SysTick->CTRL &= ~ SysTick_CTRL_ENABLE_Msk;
}
//延时.h函数
#ifndef __BSP_SYSTICK_H
#define __BSP_SYSTICK_H

#include "stm32f10x.h"
#include "core_cm3.h"

void SysTick_Delay_us(uint32_t us);
void SysTick_Delay_ms(uint32_t ms);

#endif /* __BSP_SYSTICK_H */
//12M晶振替换8M,RCC.C程序配置频率
#include "bsp_rccclkconfig.h"


void HSE_SetSysClk( uint32_t RCC_PLLMul_x )
{
	ErrorStatus HSEStatus;
	
	// 把RCC 寄存器复位成复位值
	RCC_DeInit();	

	// 使能 HSE 
	RCC_HSEConfig(RCC_HSE_ON);
	
	HSEStatus = RCC_WaitForHSEStartUp();
	
	if( HSEStatus == SUCCESS )
	{
		// 使能预取指
		FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);
		FLASH_SetLatency(FLASH_Latency_2);
		
		RCC_HCLKConfig(RCC_SYSCLK_Div1);
		RCC_PCLK1Config(RCC_HCLK_Div2);
		RCC_PCLK2Config(RCC_HCLK_Div1);
		
		// 配置 PLLCLK = HSE * RCC_PLLMul_x
    RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_x);
		
    // 使能PLL
		RCC_PLLCmd(ENABLE);
		
		// 等待PLL稳定
		while( RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET );
		
    // 选择系统时钟
		RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
		
    while( RCC_GetSYSCLKSource() != 0x08 );
	}
	else
  {
		/* 如果HSE 启动失败,用户可以在这里添加处理错误的代码 */
	}
}

void HSI_SetSysClk( uint32_t RCC_PLLMul_x )
{
	__IO uint32_t HSIStatus = 0;
	
	// 把RCC 寄存器复位成复位值
	RCC_DeInit();	

	// 使能 HSI 
	RCC_HSICmd(ENABLE);
	
	HSIStatus = RCC->CR & RCC_CR_HSIRDY;
	
	if( HSIStatus == RCC_CR_HSIRDY )
	{
		// 使能预取指
		FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);
		FLASH_SetLatency(FLASH_Latency_2);
		
		RCC_HCLKConfig(RCC_SYSCLK_Div1);
		RCC_PCLK1Config(RCC_HCLK_Div2);
		RCC_PCLK2Config(RCC_HCLK_Div1);
		
		// 配置 PLLCLK = HSE * RCC_PLLMul_x
    RCC_PLLConfig(RCC_PLLSource_HSI_Div2, RCC_PLLMul_x);
		
    // 使能PLL
		RCC_PLLCmd(ENABLE);
		
		// 等待PLL稳定
		while( RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET );
		
    // 选择系统时钟
		RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
		
    while( RCC_GetSYSCLKSource() != 0x08 );
	}
	else
  {
		/* 如果HSI 启动失败,用户可以在这里添加处理错误的代码 */
	}
}

void MCO_GPIO_Config(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;
	// 开启GPIOA的时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
	
	// 选择GPIO8引脚
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
	
	//设置为复用功能推挽输出
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
	
	//设置IO的翻转速率为50M
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	
	// 初始化GPIOA8
  GPIO_Init(GPIOA, &GPIO_InitStructure);

}
//12M晶振替换8M晶振,重新设置频率.H程序
#ifndef __BSP_RCCCLKCONFIG_H
#define __BSP_RCCCLKCONFIG_H

#include "stm32f10x.h"

void HSE_SetSysClk( uint32_t RCC_PLLMul_x );
void MCO_GPIO_Config(void);
void HSI_SetSysClk( uint32_t RCC_PLLMul_x );
#endif /*__BSP_RCCCLKCONFIG_H */

 

### 回答1: DHT.zip是一款设计用于湿度传感器DHT11模块的软件。DHT11是一种数字湿度传感器,具有独特的技术和优良的性能,可以被广泛地应用于各种类型的电子项目,包括测量室内/室外环境的度和湿度等。为了满足需求,DHT.zip被设计为能够提供可靠的读取和输出数据的软件。此软件能够精确地读取DHT11模块信号,将读取到的数据通过串口传输至主控板,可以被进一步处理和分析,以达到精确测量环境度和湿度的目的。DHT.zip非常易于使用,用户仅需将传感器连接到主板上,并通过串口运行DHT.zip程序即可开始正常工作。此外,这个软件界面也非常直观,能够帮助用户轻松地理解数据的读取和分析过程。总的来说,DHT.zip是一款非常实用的软件,对于那些需要使用DHT11模块来测量湿度的用户来说,它将是一个非常有用的工具。 ### 回答2: dht.zip是一个针对于湿度传感器DHT11模块的专用软件。使用dht.zip可以方便地获取和处理DHT11传感器所传输的度和湿度数据。DHT11模块是一款高精度、响应速度快、体积小巧的湿度传感器模块,广泛应用于各种湿度监测系统中。通过使用dht.zip软件,用户可以轻松快速地建立一个湿度监测系统,对环境湿度进行实时监测,以保证环境的舒适性和安全性。 使用dht.zip软件不仅方便易用,而且功能强大。它支持多种编程语言,包括C、C++、Python等,可以在多种平台上运行。用户可以通过dht.zip软件获取DHT11传感器模块所采集到的湿度数据,并进行数据处理和分析。此外,dht.zip软件还支持数据的实时传输和存储,让用户可以随时随地了解环境湿度的变化情况。 总之,dht.zip是一款功能强大、易于使用的专门针对DHT11模块湿度传感器软件,它为用户提供了实时监测、数据处理和分析等多种功能,有助于提高环境监测的精度和效率。 ### 回答3: dht.zip文件是针对湿度传感器DHT11模块设计的专用文件。DHT11模块是一种数字湿度传感器,由于数据传输是数字信号,所以具有抗干扰能力强,精度高等特点。DHT11模块可以应用在各种场合,例如空气质量检测、环境监测等。为了更好地使用DHT11模块,需要在电脑上安装DHT.zip文件。DHT.zip文件中包含了DHT11的驱动程序和使用说明书。驱动程序可以让DHT11模块更好地与电脑进行数据交互,使用说明书则可以让用户更加详细地了解DHT11模块的使用方法和注意事项。在安装DHT.zip文件之后,用户就可以利用电脑对DHT11模块进行各种操作,例如读取湿度数值、设置数据采集间隔等等。通过DHT11模块的应用,可以实时监测环境湿度变化,从而提高生活和工作的舒适度和安全性。
评论 14
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值