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).
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: ❤️ ❤️ ❤️
- 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;
- 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: ❤️ ❤️
- DHT11 initializes the pins ;
- Set the delay function to perform the receiving function according to the timing ;
- 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: ❤️ ❤️
- 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 ;
- 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;
- **#define delay_us(X) delayd(X*72/5)** may calculate a relatively accurate delay function through debugging;
- 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;
- 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 ;
- 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.
- 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 .
- 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
- dht11_read() returns 32-bit data , and the 8-bit checksum data has been removed;
- When obtaining temperature and humidity respectively, pay attention to the number of digits shifted to the right ;
2. Knowledge points learned
- ① According to the timing of DHT11 transmission data, write the driver to obtain DHT11 temperature and humidity;
- ② Master the corresponding temperature and humidity data obtained through shifting;
- ③ Learn to use the while loop to wait for a specific response signal;
- ④ When judging the sensor data output 0 or 1, the maximum duration of 28us can be judged to output 0;
❤️ ❤️ ❤️ ❤️ ❤️ ❤️