Embedded design and development project - DHT11 temperature and humidity sensor program design


Popularization of knowledge :
DHT11 is a single-wire interface digital temperature and humidity sensor. The temperature measurement range is 0 ~ 50°C , the humidity measurement range is 20% ~ 90%RH , the temperature measurement accuracy is ±2°C , and the humidity measurement accuracy is ±5%RH .
DHT11 includes a resistive humidity sensing element and an NTC (negative temperature coefficient) temperature measuring element . It outputs temperature and humidity data through a bidirectional single line, and outputs 40 bits of data at a time (the high bit comes first, which takes about 4ms). The data format is: 8 bits Humidity integer + 8-digit humidity decimal (0) + 8-digit temperature integer + 8-digit temperature decimal (0) + 8-digit checksum (the checksum is the last 8 digits of the sum of the first 4 8-bit data).
insert image description here

Timing learning process:
① When the single line is idle, it is at high level. When the MCU reads data, it first sends a start signal (outputs low level, and the duration must be greater than 18ms), and then switches to input mode (single line is pulled to high level by a pull-up resistor. Level) Waiting for DHT11;
② DHT11 triggers a data acquisition after detecting the start signal, and waits for the single line to become high level to output a response signal (low level, duration 80us)

1. Implemented functions

  • ① Complete the real-time collection and display of DHT11 temperature and humidity sensor data;
  • ②The 8 LED running water lights are controlled, one light is lit every 1s, and the above steps are repeated;
  • ③ Write the underlying driver of DHT11 temperature and humidity;

2. Realize the code according to the function

1. The main file main.c

#include"key.h"
#include"led.h"
#include"lcd.h"
#include"stdio.h"
#include"dht11.h"

unsigned int uiDht_Val;
unsigned char ucSec,ucSec1;
unsigned char pucStr[21];
unsigned long ulTick_ms;

void DHT_Proc(void);

int main(void)
{
    
    
	SysTick_Config(72000);	//定时1ms(HCLK = 72MHz)
	KEY_Init();
	LED_Init();
	
	STM3210B_LCD_Init();
	LCD_Clear(Blue);
	LCD_SetBackColor(Blue);
	LCD_SetTextColor(White);
	while(1)
	{
    
    
		LED_Disp(ucSec);
		DHT_Proc();
	}
}
	void DHT_Proc(void)
	{
    
    
		if(ucSec != ucSec1)
		{
    
    
			ucSec1 = ucSec;
			
			uiDht_Val = dht11_read();
			sprintf((char *)pucStr," Humidity: %2d%%",uiDht_Val >> 24);
			LCD_DisplayStringLine(Line3,pucStr);
			sprintf((char *)pucStr," Temperature: %dC",(uiDht_Val >> 8)&0xff);
			LCD_DisplayStringLine(Line5,pucStr);
		}
	}
	
//SysTick 中断处理程序
	void SysTick_Handler(void)
	{
    
    
		ulTick_ms++;
		if(ulTick_ms % 1000 ==0)
		ucSec++;
	}
	
	

Main function analysis: ❤️ ❤️ ❤️

  1. dht11_read() returns 36-bit data , and the lower eight-bit checksum of DHT11 has been castrated, so the integer bit of humidity is the collected data shifted to the right by 24 bits;
  2. The integer data of the greenhouse is the collected data uiDht_Val shifted to the right by 8 bits to take the lower eight bits of data;

2. The header file "dht11.h" of DHT11 temperature and humidity

#ifndef __DHT11_H
#define __DHT11_H

void dht11_init (void );
void delay(unsigned int n);

unsigned int dht11_read(void);
void DisplayDht11(void);

#endif

Brief analysis: ❤️ ❤️

  1. DHT11 initializes the pins ;
  2. Set the delay function to perform the receiving function according to the timing ;
  3. Obtain temperature and humidity data and return an unsigned integer data ;

3. The source file "dht11.c" of DHT11 temperature and humidity

#include "stm32f10x.h"

#define delay_us(X)  delayd(X*72/5)

void delayd(unsigned int n)
{
    
    
  while (n--);
}

void dht11_init (void )
{
    
    
  GPIO_InitTypeDef GPIO_InitStructure;
  /* Enable  clock */
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA  , ENABLE);
  
  /* Configure Ports */
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
  GPIO_Init(GPIOA, &GPIO_InitStructure);

  GPIO_SetBits(GPIOA, GPIO_Pin_7);

}

void mode_input(void )
{
    
    
  GPIO_InitTypeDef GPIO_InitStructure;

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
  GPIO_Init(GPIOA, &GPIO_InitStructure);
}
void mode_output(void )
{
    
    
  GPIO_InitTypeDef GPIO_InitStructure;

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
  GPIO_Init(GPIOA, &GPIO_InitStructure);
}

unsigned int dht11_read(void)
{
    
    
  int i;
  long long val;
  int timeout;

  GPIO_ResetBits(GPIOA, GPIO_Pin_7);
  delay_us(18000);  //pulldown  for 18ms
  GPIO_SetBits(GPIOA, GPIO_Pin_7);
  delay_us( 20 );	//pullup for 30us

  mode_input();

  //等待DHT11拉低,80us
  timeout = 5000;
  while( (! GPIO_ReadInputDataBit  (GPIOA, GPIO_Pin_7)) && (timeout > 0) ) timeout--;	 //wait LOW

  //等待DHT11拉高,80us
  timeout = 5000;
  while( GPIO_ReadInputDataBit (GPIOA, GPIO_Pin_7) && (timeout > 0) ) timeout-- ;	 //wait HIGH	

#define CHECK_TIME 28

  for(i=0;i<40;i++)
  {
    
    
	timeout = 5000;
	while( (! GPIO_ReadInputDataBit  (GPIOA, GPIO_Pin_7)) && (timeout > 0) ) timeout--;	 //wait HIGH

	delay_us(CHECK_TIME);
	if ( GPIO_ReadInputDataBit (GPIOA, GPIO_Pin_7) )
	{
    
    
	  val=(val<<1)+1;
	} else {
    
    
	  val<<=1;
	}

	timeout = 5000;
	while( GPIO_ReadInputDataBit (GPIOA, GPIO_Pin_7) && (timeout > 0) ) timeout-- ;	 //wait LOW
  }

  mode_output();
  GPIO_SetBits(GPIOA, GPIO_Pin_7);

  if (((val>>32)+(val>>24)+(val>>16)+(val>>8) -val ) & 0xff  ) return 0;
    else return val>>8; 

}


Brief analysis: ❤️ ❤️

  1. The DHT11 temperature and humidity sensor is connected to the PA7 pin of the chip, dht11_init() initializes the PA7 pin to push-pull output mode immediately, and sets PA7 to high level ;
  2. Configure the PA7 pin push-pull output mode and pull-up input mode at the same time , and perform corresponding sending and receiving according to the timing diagram;
  3. **#define delay_us(X) delayd(X*72/5)** may calculate a relatively accurate delay function through debugging;
  4. MCU first sends the start data ( output low level, the duration must be greater than 18ms to ensure that DHT11 can detect the start signal ), then switch to input mode ( the single line is pulled high by the pull-up resistor ), and wait for DHT11 to respond;
  5. After DHT11 detects the start signal, it triggers a data acquisition , and waits for the single line to become high level to output a response signal ( low level, duration 80us ), and then outputs high level ( duration 80us ) to prepare to output 40-bit data ;
  6. Each bit of data starts with a low level (50us duration), the high level duration is 26~28us when outputting 0, and the high level duration is 70us when outputting 1.
  7. After the last bit of data is output, it outputs a low level ( duration 50us ), and the single line is pulled to a high level by a pull-up resistor to enter an idle state .
  8. The MCU detects the response signal and reads 40 bits of data from the single line, and judges whether the checksum is correct . If it is correct, it is valid, otherwise it discards the data.

3. Attention and learning points in the process of realizing functions

1. Precautions

  1. dht11_read() returns 32-bit data , and the 8-bit checksum data has been removed;
  2. When obtaining temperature and humidity respectively, pay attention to the number of digits shifted to the right ;

2. Knowledge points learned

  1. According to the timing of DHT11 transmission data, write the driver to obtain DHT11 temperature and humidity;
  2. Master the corresponding temperature and humidity data obtained through shifting;
  3. Learn to use the while loop to wait for a specific response signal;
  4. When judging the sensor data output 0 or 1, the maximum duration of 28us can be judged to output 0;

❤️ ❤️ ❤️ ❤️ ❤️ ❤️

Guess you like

Origin blog.csdn.net/a6662580/article/details/124463517