STM32使用DHT11温湿度传感器模块实现数据采集

一、DHT11模块介绍

​DHT11数字温湿度传感器是一款含有已校准数字信号输出的温湿度复合传感器,它应用专用的数字模块采集技术和温湿度传感技术,确保产品具有极高的可靠性和卓越的长期稳定性。传感器包括一个电阻式感湿元件和一个NTC测温元件,并与一个高性能8位单片机相连接。因此该产品具有品质卓越、超快响应、抗干扰能力强、性价比极高等优点。每个DHT11传感器都在极为精确的湿度校验室中进行校准。校准系数以程序的形式存在OTP内存中,传感器内部在检测信号的处理过程中要调用这些校准系数。单线制串行接口,使系统集成变得简易快捷。超小的体积、极低的功耗,使其成为该类应用中,在苛刻应用场合的最佳选择。产品为4针单排引脚封装,连接方便。测量范围:湿度20%-95%,温度0-50℃,广泛应用于加湿器、温湿度计、空调等领域。

二、典型应用电路

DHT11第一脚接电源正,第四脚接电源地端。数据为第二脚。可直接接单片机 I/O 口。为提高稳定性,建议在数据脚和电源正级之间接5.1K 的上拉电阻。第三管脚悬空不接。

三、时序

DHT11 采用单总线协议与单片机通信,单片机发送一次复位信号后,DHT11 等待主机复位结束后,DHT11 发送响应信号,并拉高总线准备传输数据。

3.1开始信号

首先主机拉低总线至少 18ms,然后再拉高总线,延时 20~40us,等待DHT11的响应信号。

3.2响应信号

DHT11接收到主机的开始信号后,等待主机开始信号结束后,发送80us低电平响应信号,再把总线拉高80us;之后开始传输数据。

3.3数据信号

DHT11每 1bit 数据都以 50us 低电平开始。DHT11 以高电平的长短定义数据位是 0 还是 1, 50us 低电平后拉高总线,高电平持续 26~28us 表示数据“0”;持续 70us 表示数据“1”当最后 1bit 数据传送完毕后,DHT11 拉低总线 50us,表示数据传输完毕,随后总线由上拉电阻拉高进入空闲状态。只需在 50us 低电平后延时 40us ,然后检测总线状态,如果为高,说明数据为“1”;如果为低,说明此时数据为“0”。

四、代码

DHT11.H

#ifndef __DHT11_H
#define __DHT11_H
#include "stm32f10x.h"
#include "delay.h"

/*连接单片机PB6引脚*/
#define DHT11_IO 		            GPIOB
#define DHT11_PIN		            GPIO_Pin_6
#define DHT11_APB2PeriphRCC     RCC_APB2Periph_GPIOB
u8 DHT11_Init(void);
u8 DHT11_Read_Data(u8 *temp,u8 *humi);

#endif

DHT11.C

#include "DHT11.h"

GPIO_InitTypeDef GPIO_InitStructure;	
                                      
static void GPIO_OUT(void);
static void GPIO_IN(void);
static u8 DHT11_Check(void);


/**********************************************
函数名:static void DHT11_Rst(void)
参数说明:无
返回值:无
***********************************************/
static void DHT11_Rst(void)     
{                 
	GPIO_OUT();											//输出模式
    GPIO_ResetBits(DHT11_IO,DHT11_PIN); //拉低数据线
    Delay_ms(20);    									//拉低至少18ms
    GPIO_SetBits(DHT11_IO,DHT11_PIN); 	//拉高数据线 
	Delay_us(30);     									//主机拉高20~40us
	GPIO_ResetBits(DHT11_IO,DHT11_PIN);
}


/**********************************************
函数名:u8 DHT11_Init(void)
参数说明:无
返回值:u8 ,返回1代表初始化成功
***********************************************/
u8 DHT11_Init(void){
	
	//IO口初始化配置
	
	RCC_APB2PeriphClockCmd(DHT11_APB2PeriphRCC,ENABLE);
	
	GPIO_InitStructure.GPIO_Pin = DHT11_PIN;         
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
	//GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
	GPIO_InitStructure.GPIO_Speed =GPIO_Speed_50MHz;  
	GPIO_Init(DHT11_IO,&GPIO_InitStructure);
	
	DHT11_Rst();//发送开始信号
	
	return DHT11_Check();//检测DHT11
}


/**********************************************
函数名:static void GPIO_OUT(void)
参数说明:无
返回值:无
***********************************************/
static void GPIO_OUT(void)
{
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
	GPIO_Init(DHT11_IO,&GPIO_InitStructure);
	
}


/**********************************************
函数名:static void GPIO_IN(void)
参数说明:无
返回值:无
***********************************************/
static void GPIO_IN(void)
{
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //浮空输入
	GPIO_Init(DHT11_IO,&GPIO_InitStructure);
}


/**********************************************
函数名:static u8 DHT11_Check(void)
参数说明:无
返回值:检测到回应-->返回1,否则0
***********************************************/
static u8 DHT11_Check(void) 	   
{   
	u8 retry=0;
	GPIO_IN();			//设置为输入模式	
	
  while (!GPIO_ReadInputDataBit(DHT11_IO,DHT11_PIN) && retry<100)//DHT11会拉低40~50us
	{
		retry++;
		Delay_us(1);
	}
	if(retry >= 100)	
		return 0;
	else 
		retry = 0;
  while (GPIO_ReadInputDataBit(DHT11_IO,DHT11_PIN) && retry<100)
	{
		retry++;
		Delay_us(1);
	}
	if(retry>=100)		//超时
		return 0;
	return 1;			//检测到DHT11
}


/**********************************************
函数名:static u8 DHT11_Read_Bit(void)
参数说明:无
返回值:返回DHT11一个Bit数据
***********************************************/
static u8 DHT11_Read_Bit(void)
{
 	u8 retry = 0;
	while(GPIO_ReadInputDataBit(DHT11_IO,DHT11_PIN) && retry<100)//等待变为低电平
	{
		retry++;
		Delay_us(1);
	}
	retry = 0;
	while(!GPIO_ReadInputDataBit(DHT11_IO,DHT11_PIN) && retry<100)//等待变高电平
	{
		retry++;
		Delay_us(1);
	}
	Delay_us(30);
	if(GPIO_ReadInputDataBit(DHT11_IO,DHT11_PIN)) return 1;
	else return 0;		   
}


/***********************************************************************
函数名:static u8 DHT11_Read_Byte(void)
参数说明:无
返回值:返回DHT11一个byte数据
************************************************************************/
static u8 DHT11_Read_Byte(void)    
{        
  u8 i,dat;
  dat=0;
	
	for (i=0;i<8;i++) 
	{
   	dat<<=1; 
	  dat|=DHT11_Read_Bit();
  }	
	
  return dat;
}


/**************************************************************************
函数名:u8 DHT11_Read_Data(u8 *temp,u8 *humi)
参数说明:temp:存放温度值,humi:存放湿度值
返回值:1:成功读取数据,0:读取数据出错
***************************************************************************/
u8 DHT11_Read_Data(u8 *temp,u8 *humi)
{        
 	u8 buf[5];
	u8 i;
	DHT11_Rst();
	if(DHT11_Check()==1)	//设备响应正常
	{
		for(i=0;i<5;i++)//读取40位数据
		{
			buf[i]=DHT11_Read_Byte();
		}
		if((buf[0]+buf[1]+buf[2]+buf[3])==buf[4])//进行校验
		{
			*humi=buf[0];
			*temp=buf[2];
		}
	}else return 0;		//设备未成功响应,返回0
	return 1;					//读取数据成功返回1
}


作者:m0_62397193

物联沃分享整理
物联沃-IOTWORD物联网 » STM32使用DHT11温湿度传感器模块实现数据采集

发表评论