STM32学习之路:第十五天(温湿度传感DHT11的使用)

温湿度传感器DHT11的使用函数

 

DHT11数据传输的总时序图以下:ui


开始传输数据前的信号时序图ip


数据接收时的时序图ci



DHT11与单片机的链接图
it


从DHT11读取数据的代码编写步骤:io

1-初始化单片机和DHT11链接的PE2口变量

2-配置PE2口的输入输出模式函数配置

3-配置8位接收数据函数,根据DHT11数据传输时序图编写循环

4-创建数据存储变量,根据老是时序图编写从DHT11上接收数据函数im


例程:

bsp_dht11.c文件

#include "bsp_dht11.h"

#include "bsp_systick.h"

 

/*==================1-初始化单片机和DHT11链接的PE2口======================*/

void DHT11_GPIO_Config(void)

{

       GPIO_InitTypeDefGPIO_InitStruct;

      

       RCC_AHB1PeriphClockCmd(DHT11_CLK, ENABLE);

      

       GPIO_InitStruct.GPIO_Pin    = DHT11_PIN;

       GPIO_InitStruct.GPIO_Mode   = GPIO_Mode_OUT;

       GPIO_InitStruct.GPIO_OType  = GPIO_OType_PP;

       GPIO_InitStruct.GPIO_Speed  = GPIO_Speed_50MHz;  

       GPIO_InitStruct.GPIO_PuPd   = GPIO_PuPd_UP;

      

       GPIO_Init(DHT11_PORT,&GPIO_InitStruct);

      

}

/*=================2-配置GPIO口的输入模式函数=========================*/

static void DHT11_Mode_IPU(void)

{

       GPIO_InitTypeDefGPIO_InitStruct;

      

       RCC_AHB1PeriphClockCmd(DHT11_CLK, ENABLE);

      

       GPIO_InitStruct.GPIO_Pin    = DHT11_PIN;

       GPIO_InitStruct.GPIO_Mode   = GPIO_Mode_IN;

       GPIO_InitStruct.GPIO_Speed  = GPIO_Speed_50MHz;  

       GPIO_InitStruct.GPIO_PuPd   = GPIO_PuPd_NOPULL;

      

       GPIO_Init(DHT11_PORT,&GPIO_InitStruct);

}

 

/*=================2-配置GPIO口的输出模式函数=========================*/

static void DHT11_Mode_OUT_PP(void)

{

       GPIO_InitTypeDefGPIO_InitStruct;

      

       RCC_AHB1PeriphClockCmd(DHT11_CLK, ENABLE);

      

       GPIO_InitStruct.GPIO_Pin    = DHT11_PIN;

       GPIO_InitStruct.GPIO_Mode   = GPIO_Mode_OUT;

       GPIO_InitStruct.GPIO_OType  = GPIO_OType_PP;

       GPIO_InitStruct.GPIO_Speed  = GPIO_Speed_50MHz;  

       GPIO_InitStruct.GPIO_PuPd   = GPIO_PuPd_UP;

      

       GPIO_Init(DHT11_PORT,&GPIO_InitStruct);

}

 

/*=================3-配置8位接收数据函数,根据DHT11数据传输时序图编写=====================*/

static uint8_t Read_Byte(void)

{

       uint8_t  i,temp;

      

       for(i=0;i<8;i++)

       {

              /*每个bit都是以50us的低电平开始,等电平置高,则跳出循环*/

              while(DHT11_DATA_IN() == Bit_RESET );

              /*‘0’表示的置高时间太短,可直接判断‘1’表示的时间,但滞留时间不宜过长,以防跳出下一位的开始时间*/

              Delay_us(35);

              if(DHT11_DATA_IN() == Bit_SET )

              {

                     /*等待跳出‘1’置高表示的时间*/

                     while(DHT11_DATA_IN()== Bit_SET);

                     /*把第(7-i)位置 '1'*/

                     temp|=(uint8_t)(0x01<<(7-i)); 

              }

              else

              {

                     /*把第(7-i)位置 '0'*/

                     temp&=(uint8_t)~(0x01<<(7-i));

              }

       }

       return temp;

}

 

/*=================4-根据总时序图编写接收数据函数===================================*/

uint8_t Read_DHT11(DHT11_Data_TypeDef*DHT11_Data)

{

       uint16_t  count;

       /*将主机设为输出模式*/

       DHT11_Mode_OUT_PP();

       /*将主机拉低*/

       DHT11_DATA_OUT(DHT11_LOW);

       /*配置主机拉低时间,至少拉低18ms*/

       Delay_ms(18);

       /*将主机拉高*/

       DHT11_DATA_OUT(DHT11_HIGH);

       /*配置主机拉高时间*/

       Delay_us(30);

       /*将主机设置为输入模式*/

       DHT11_Mode_IPU();

       if(DHT11_DATA_IN()== Bit_RESET)

       {

              count=0;

              /*等待DHT11置低响应结束,达到必定时间后,响应失败,返回0*/

              while(DHT11_DATA_IN()== Bit_RESET)

              {

                     count++;

                     if(count> 1000) return 0;

              }

              count=0;

              /*等待DHT11置高响应结束,达到必定时间后,响应失败,返回0*/

              while(DHT11_DATA_IN()== Bit_SET)

              {

                     count++;

                     if(count> 1000) return 0;

              }

             

              /*开始接收数据*/  

              DHT11_Data->humi_int=Read_Byte();

              DHT11_Data->humi_deci=Read_Byte();

              DHT11_Data->temp_int=Read_Byte();

              DHT11_Data->temp_deci=Read_Byte();

              DHT11_Data->check_sum=Read_Byte();

 

              /*读取结束,将主机设为输出模式*/

              DHT11_Mode_OUT_PP();

              /*主机拉高*/

              DHT11_DATA_OUT(DHT11_HIGH);

             

              /*检查读取的数据是否正确*/

              if(DHT11_Data->check_sum== DHT11_Data->humi_int + DHT11_Data->humi_deci +DHT11_Data->temp_int+ DHT11_Data->temp_deci)

                     return 1;

              else

                     return 0;

       }

       else

              return 0;

      

}

 

bsp_dht11.h文件

#ifndef __BSP_DHT11_H

#define __BSP_DHT11_H

 

#include "stm32f4xx.h"

 

#include "stm32f4xx_gpio.h"

#include "stm32f4xx_rcc.h"

 

#define DHT11_HIGH  1

#define DHT11_LOW   0

 

#define DHT11_CLK     RCC_AHB1Periph_GPIOE

#define DHT11_PIN     GPIO_Pin_2              

#define DHT11_PORT    GPIOE

 

#define DHT11_DATA_IN()     GPIO_ReadInputDataBit(DHT11_PORT,DHT11_PIN)

 

#define DHT11_DATA_OUT(a)    if (a) \

                                  GPIO_SetBits(DHT11_PORT,DHT11_PIN);\

                                   else          \

                                  GPIO_ResetBits(DHT11_PORT,DHT11_PIN)

                                                                                                                        

/*定义一个结构体,储存从DHT11读取的数据*/

typedef struct

{

       uint8_t  humi_int;        //湿度的整数部分

       uint8_t  humi_deci;          //湿度的小数部分

       uint8_t  temp_int;      //温度的整数部分

       uint8_t  temp_deci;          //温度的小数部分

       uint8_t  check_sum;         //校验和

}DHT11_Data_TypeDef;

 

void DHT11_GPIO_Config(void);

uint8_t Read_DHT11(DHT11_Data_TypeDef*DHT11_Data);

 

#endif /*__BSP_DHT11_H*/