This is the 9th day of my participation in the August More Text Challenge. For details, see:August is more challenging

DHT11 is a temperature and humidity sensor, is also the use of a bus to drive, the use method and DS18B20 temperature sensor is very similar.

  • The supply voltage ranges from 3.3 V DC to 5.5V DC
  • Measurement range Humidity 5% to 95%RH, temperature -20 ° C to +60 ° C
  • Accuracy Humidity ±5%RH, temperature ±2℃
  • Distinguishing rate Humidity 1%RH, temperature 0.1℃

The physical picture is shown below

Pin sequence is 1, 2, 3 and 4 from left to right. Pin functions are as follows:

1 Vcc Power supply pin power supply range 3.5V to 5.5V
2 Data Output temperature and humidity values over a single bus
3 NC No use, use the suspension of the line.
4 Ground grounding

Typical application circuit is as follows:

Since the level of the single bus is high in the idle state during communication, an external pull-up resistor should be connected to pin 2. In this way, when there is no data transmission on the bus, the external pull-up resistor will force the level of the data pin to be set to high.

When reading data through a single bus, there are three steps:

  1. The host sends the request instruction
  2. The slave machine returns the corresponding instruction
  3. The host starts reading data from the slave

1. Request instruction:

When the host sends the request instruction, the bus needs to be pulled down at least 18ms, and then release the bus 40us.

2. Respond to instructions

When the sensor detects the host request, it will send a response instruction to the host, telling the host that the communication has been successful. The response instruction returned by the sensor is 54US low and 80us high.

3. Read data

After the sensor sends the response command, it sends 40 bits of data. The 8 bits are one bit of data, and there are five data in total, including the current temperature and humidity data. The first two data points are the integer part and the fractional part of the humidity data. The following two numbers are the integer and fractional parts of the temperature data. The last data is the checksum of the first four.

The overall data format is 8-bit humidity integer data + 8-bit humidity decimal data + 8BI temperature integer data + 8-bit temperature decimal data + 8-bit parity sum.

During data transmission, the length of time it takes for the high and low levels to indicate whether the data sent is “0” or “1”.

Bit ‘0’ : ~54uS low and ~24uS high

Bit ‘1’ : ~54uS low and ~70uS high

End sign:

When the data transmission is complete, the sensor will pull the bus down 54us and then release the bus, which represents the end of data transmission. At this point, the sensor will go to sleep and wait for the next request signal to wake up again.

The complete time sequence of data read is shown below:

First, MCU sends the request command, and then waits for the sensor response. After the sensor response is complete, it sends 40bit data, and then sends the end flag. It then automatically goes into sleep mode and waits for the MCU to wake up again.

With the timing clear, you can start writing code.

The code is as follows:

#include "dht11.h"
#include "stm8s103f3p.h"
#include "delay.h"
/ / IO operation
_Bool  DHT11_DQ_OUT @PD_ODR:3;
_Bool  DHT11_DQ_IN  @PD_IDR:3;
//PD3 direction Settings
void DHT11_IO_IN(void)
{
    PD_DDR&=~(1<<3);    / / input PD3
    PD_CR1|=(1<<3);     //
}
void DHT11_IO_OUT(void)
{
    PD_DDR|=(1<<3);     / / output PD3
    PD_CR1|=(1<<3);     //
}
// Send the start signal low level for 18ms
void DHT11_Rst(void)
{
    DHT11_IO_OUT(); // Set to output
    DHT11_DQ_OUT=0; / / low DQ
    delay_ms(20);   // Pull down at least 18ms
    DHT11_DQ_OUT=1; / / high DQ
    delay_us(30);   // raise the host by 20--40us
}
// Wait for DHT11 to respond
// Return 1: DHT11 is not detected
// Return 0: exists
unsigned char DHT11_Check(void)
{
    //DHT outputs 80US low level as the response signal
    // The DHT outputs a high level of 80US to notify the processor that it is ready to receive data
    unsigned char retry=0;
    DHT11_IO_IN();//SET INPUT	 
    while(! DHT11_DQ_IN&&retry<100)//DHT11 will drag down 40~80us
	{
		retry++;
		delay_us(1);
	};	 
	if(retry>=100)return 1;
	else retry=0;
    while (DHT11_DQ_IN&&retry<100)// after the DHT11 is pulled down, it will be pulled up again by 40~80us
	{
		retry++;
		delay_us(1);
	};
	if(retry>=100)return 1;	    
	return 0;
}
// Read a bit from DHT11
// Return value: 1/0
unsigned char DHT11_Read_Bit(void)
{
// data is in "0" format: low level of 50us + high level of 26-28us
// the data is in "1" format: 50us low + 70us high
   unsigned char retry=0;
   while(DHT11_DQ_IN && retry<100)// If the level is high, the data transmission of the last bit is not finished. Wait for the level to change to low
	{
		retry++;
		delay_us(1);
	}
	retry=0;
    while(! DHT11_DQ_IN && retry<100)// If it is low, the data transmission has not started, wait for the high level
	{
		retry++;
		delay_us(1);
	}
    delay_us(40);// Wait 40US 0 for 50us low level 26-28us High level 1 for 50us low level 70us high level
    if(DHT11_DQ_IN) return 1;
    else  return 0;
}
// Read a byte from DHT11
// Return value: read data
unsigned char DHT11_Read_Byte(void)
{
    unsigned char i,dat;
    dat=0;
    for(i=0; i<8; i++) { dat<<=1;
        dat|=DHT11_Read_Bit();
    }
    return dat;
}
// Read the data from DHT11 once
//temp: temperature value (range :0~50°)
//humi: humidity value (range :20%~90%)
// Return value: 0, normal; 1. Read failed
unsigned char DHT11_Read_Data(unsigned char *temp,unsigned char *humi)
{
    unsigned char buf[5];
    unsigned char i;
    DHT11_Rst();
    if(DHT11_Check()==0)    // Read 40 bits of data
    {
      for(i=0; i<5; i++) { buf[i]=DHT11_Read_Byte(); }if(buf[0]+buf[1]+buf[2]+buf[3]==buf[4])// Humidity Integer humidity decimal temperature Integer decimal temperature check sum
      {
          *humi=buf[0];     
          *temp=buf[2]; }}else return 1;
  return 0;
}
// Initialize the DHT11 I/O port DQ and check the DHT11 presence
// Return 1: none
// Return 0: exists
unsigned char DHT11_Init(void)
{
    DHT11_IO_OUT();
    DHT11_DQ_OUT=1;
    DHT11_Rst();
    return DHT11_Check();
}
Copy the code

Called directly in the main function when the temperature is read

#include "stm8s103f3p.h"
#include "delay.h"
#include "dht11.h"

// set the clock to 16Mhz
void CLK_Init(void)
{
	CLK_SWR=0xe1; 			 //HSI 16MHz CPU clock frequency of the primary clock source
	CLK_CKDIVR=0x00;		// The CPU clock is 0 and the system clock is 0
}
// Read the temperature and humidity data
void read_tem_hum(void)
{
    unsigned char temperature[2] = {0};
    unsigned char humidity[2] = {0};
    DHT11_Read_Data(temperature,humidity);   
}

main()
{
    _asm("sim");			// Close all interrupt
    CLK_Init();
    delay_init(16);
    _asm("rim");			// Open all interrupt
  while (1) { read_tem_hum(); }}Copy the code

Through the MCU IO port output high and low levels to simulate the timing of a single bus, so that the temperature and humidity data can be read out.