STM32F103C8T6 Temperature and Humidity DHT11 Driver

1 Introduction to DHT11

DHT11 digital temperature and humidity sensor is a temperature and humidity composite sensor with calibrated digital signal output. It applies special digital module acquisition technology and temperature and humidity sensing technology to ensure that the product has extremely high reliability and excellent long-term stability. The sensor includes a resistive humidity sensing element and an NTC temperature measuring element, and is connected with a high-performance 8-bit microcontroller. Therefore, the product has the advantages of excellent quality, ultra-fast response, strong anti-interference ability, and high cost performance. Each DHT11 sensor is calibrated in an extremely precise humidity calibration chamber. The calibration coefficients are stored in the OTP memory in the form of a program, and these calibration coefficients are called in the sensor during the processing of the detection signal. Single-wire serial interface makes system integration easy and fast. The ultra-small size and extremely low power consumption make it the best choice for this type of application in harsh applications. The product is a 4-pin single-row pin package, which is easy to connect.

DHT11 temperature and humidity sensor pin description
insert image description here
DHT11 temperature and humidity sensor pin description
insert image description hereDHT11 digital humidity temperature sensor adopts single bus data format. A single data pin port completes input and output bidirectional transmission.

Its data packet consists of 5Byte (40Bit). The data is divided into a fractional part and an integer part, and a complete data transmission is 40bit, and the high bit is first out.

The data format of DHT11 is: 8bit humidity integer data + 8bit humidity decimal data + 8bit temperature integer data + 8bit temperature decimal data + 8bit checksum.

The checksum data is the addition of the first four bytes. Sensor data output is unencoded binary data. Data (humidity, temperature, integer, decimal) should be processed separately.

Sensor data output is unencoded binary data. Data (humidity, temperature, integer, decimal) should be processed separately.

DHT11 starts to send the data process
insert image description here. After the host sends the start signal, wait for 20us-40us after the delay to read the response signal of DH11T. The bus is low, indicating that DHT11 sends the response signal. After DHT11 sends the response signal, the bus is pulled high. , ready to send data, each bit of data starts with a low level, the format is shown in the figure below. If the reading response signal is high level, then DHT11 has no response, please check whether the line is connected normally.
First, the host sends a start signal, that is: pull down the data line, keep it for t1 (at least 18ms), then pull up the data line for t2 (20-40us), and then read the response of DHT11. If it is normal, DHT11 will pull down the data line , keep t3 (40-50us) time, as a response signal, then DHT11 pulls the data line high, and after t4 (40~50us) time, it starts to output data.

Host reset signal and DHT11 response signal
insert image description here

Digital '0' signal representation method
insert image description hereinsert image description here

The program needs to distinguish the format of data 0 and data 1: first judge the level status of the pin at this time, if it is low level, wait in a loop until the high level appears, delay 40us after the high level appears, and read The level status after the delay, if it is high level at this time, the data is 1, otherwise it is 0

After the 40-bit data is transmitted, the sensor outputs a low level for 50us again, and then releases the data bus, and the acquisition process ends.

Schematic:

insert image description here

2 drivers

dht11.c


#include "DHT11.h"

GPIO_InitTypeDef GPIO_InitStructure;	//后面会改变输入输出状态
                                      //结构体声明在最开头
static void GPIO_SETOUT(void);
static void GPIO_SETIN(void);
static u8 DHT11_Check(void);


/**********************************************
函数名:static void DHT11_Rst(void)
参数说明:无
返回值:无
函数作用:主机发送开始信号
***********************************************/
//这是它的物理工作原理,根据原理拉高或拉低它的引脚来唤醒dht11
static void DHT11_Rst(void)     
{                 
	GPIO_SETOUT();											//配置成输出模式
    GPIO_ResetBits(DHT11_IO,DHT11_PIN); //拉低数据线
    Delay_ms(30);    										//拉低至少18ms
    GPIO_SetBits(DHT11_IO,DHT11_PIN); 	//拉高数据线 
	Delay_us(30);     									//主机拉高20~40us
	GPIO_ResetBits(DHT11_IO,DHT11_PIN);        //需要手动拉低?之前自动拉低一直没数据
}


/**********************************************
函数名:u8 DHT11_Init(void)
参数说明:无
返回值:u8 ,返回1代表初始化成功,0则失败
函数作用:配置IO口,并发送开始信号
***********************************************/
u8 DHT11_Init(void){
	
	//IO口初始化配置
	
	RCC_APB2PeriphClockCmd(DHT11_APB2PeriphRCC,ENABLE);//换IO口需要修改,时钟设置
	
	GPIO_InitStructure.GPIO_Pin = DHT11_PIN;          //调用引脚
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出,如果需要考虑到IC的电流驱动能力时要接上拉电阻(5K)
	//GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
	GPIO_InitStructure.GPIO_Speed =GPIO_Speed_50MHz;  //speed 可随意
	GPIO_Init(DHT11_IO,&GPIO_InitStructure);
	
	DHT11_Rst();//发送开始信号
	
	return DHT11_Check();//检测DHT11的响应
}


/**********************************************
函数名:static void GPIO_SETOUT(void)
参数说明:无
返回值:无
函数作用:配置IO口为推挽输出模式
***********************************************/
static void GPIO_SETOUT(void)
{
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出,如果需要考虑到IC的电流驱动能力时要接上拉电阻(5K)
	GPIO_Init(DHT11_IO,&GPIO_InitStructure);
	
}


/**********************************************
函数名:static void GPIO_SETIN(void)
参数说明:无
返回值:无
函数作用:配置IO口为浮空输入模式
***********************************************/
static void GPIO_SETIN(void)
{
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //浮空输入模式
	GPIO_Init(DHT11_IO,&GPIO_InitStructure);
}


/**********************************************
函数名:static u8 DHT11_Check(void)
参数说明:无
返回值:检测到回应-->返回1,否则0
函数作用:检测DHT11的响应信号
***********************************************/
static u8 DHT11_Check(void) 	   
{   
	u8 retry=0;
	GPIO_SETIN();			//设置为输入模式	
	
  while (!GPIO_ReadInputDataBit(DHT11_IO,DHT11_PIN) && retry<100)//DHT11会拉低40~50us
	{
		retry++;
		Delay_us(1);
	}
	if(retry >= 100)	//超时未响应/未收到开始信号,退出检测
	{
		//while(1);
		return 0;
	}
	else 
		retry = 0;
  while (GPIO_ReadInputDataBit(DHT11_IO,DHT11_PIN) && retry<100)//DHT11拉低后会再次拉高40~50us
	{
		retry++;
		Delay_us(1);
	}
	if(retry>=100)		//超时,DHT11工作出错,退出检测
		return 0;
	return 1;					//设备正常响应,可以正常工作
}


/**********************************************
函数名:static u8 DHT11_Read_Bit(void)
参数说明:无
返回值:返回从DHT11上读取的一个Bit数据
函数作用:从DHT11上读取一个Bit数据
***********************************************/
static u8 DHT11_Read_Bit(void)
{
 	u8 retry = 0;
	//DHT11的Bit开始信号为12-14us低电平
	while(GPIO_ReadInputDataBit(DHT11_IO,DHT11_PIN) && retry<100)//等待变为低电平(等待Bit开始信号)
	{
		retry++;
		Delay_us(1);
	}
	retry = 0;
	while(!GPIO_ReadInputDataBit(DHT11_IO,DHT11_PIN) && retry<100)//等待变高电平(代表数据开始传输)
	{
		retry++;
		Delay_us(1);
	}
	Delay_us(30);//等待30us
	//0信号为26-28us,1信号则为116-118us,所以说超过30us去读取引脚状态就可以知道传输的值了
	if(GPIO_ReadInputDataBit(DHT11_IO,DHT11_PIN)) return 1;
	else return 0;		   
}


/***********************************************************************
函数名:static u8 DHT11_Read_Byte(void)
参数说明:无
返回值:返回从DHT11上读取的一个byte数据
函数作用:从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:用于存放温度值(范围:0~50°),humi:用于存放湿度值(范围:20%~90%)
返回值:1:成功读取数据,0:读取数据出错
函数作用:从DHT11上读取温湿度数据(这里省略小数值)
***************************************************************************/
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
}


dht11.h

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


/* 设置GPIO脚,默认为PB11 */
#define DHT11_IO 		            GPIOB
#define DHT11_PIN		            GPIO_Pin_7
#define DHT11_APB2PeriphRCC     RCC_APB2Periph_GPIOB
/* 初始化函数,如果DHT11存在响应则返回1,否则0 */
u8 DHT11_Init(void);
/* 从DHT11读取数据,没有小数部分 */
 u8 DHT11_Read_Data(u8 *temp,u8 *humi);

#endif

main

char dis0[16];			   //???????
char dis1[16];			   //???????

//char DHTdata1[5];




int main()
{

	u8 tem1=0;
	u8 hum1=0;
	
	Init();
	//printf("starting stm32 system loding\r\n");
	

	//delay_ms(500);
	//LCD_screen_write_data('2');
	
		printf("wecome to DHT11\n");
	 //???DHT11(?BUG,?????????,???????????)
	 if(!DHT11_Init()){
		 printf(" Error! T DHT11 HAS NO RESPOND...\n");
		 
	 }
	 printf("\r\n THE DHT11 HAS RESPOND");
	 Delay_ms(10);		//????10ms?????,?????????,??DHT11?????

	while(1)
	{
		

		//DHT11--------------start		
		 if(DHT11_Read_Data(&tem1,&hum1))     //&temp?????*temp??,??????
		 {
			printf("\r\n temp: %d,humi: %d",tem1,hum1);  //'%'?????,???????
			sprintf(dis1,"TEMP%dTUM%d",tem1,hum1);
			LCD1602_ShowStr(0,1,dis1);//?? ??
		 }
		 else
		 printf("\r\n EEROR! THE DHT11 HAS NO RESPOND...");//????????,?????????????,

		
		delay_ms(500);
		delay_ms(500);
		//DHT11--------------end			

3 problems encountered

Nothing is displayed while simulating

 At first, I thought it was a code problem. After many revisions and tests, it still didn’t work. Then, through the physical verification, it was found that the real thing is ok,,,, I can only say that the simulation of the counterfeit version bought on Taobao still does not support it, and there is no solution for the temporary simulation .

Guess you like

Origin blog.csdn.net/weixin_51248645/article/details/130342397