DHT11

dht11_drive_function.h

#ifndef __DHT11_DRIVE_FUNCTION_H
#define __DHT11_DRIVE_FUNCTION_H


#include "main.h"


//数据输入输出端    
#define DHT11_DATA_GPIO_PORT        GPIOG
#define DHT11_DATA_GPIO_PIN            GPIO_Pin_2


#define DHT11_GPIO_CLK                RCC_APB2Periph_GPIOG
#define DHT11_GPIO_ClockCmd          RCC_APB2PeriphClockCmd



#define DHT11_DATA_L()                GPIO_ResetBits(DHT11_DATA_GPIO_PORT, DHT11_DATA_GPIO_PIN)
#define DHT11_DATA_H()                GPIO_SetBits(DHT11_DATA_GPIO_PORT, DHT11_DATA_GPIO_PIN)


#define DHT11_DATA_READ()              GPIO_ReadInputDataBit(DHT11_DATA_GPIO_PORT, DHT11_DATA_GPIO_PIN)


#define DHT11_Delay_US               SysTick_Delay_US 
#define DHT11_Delay_MS               SysTick_Delay_MS 



typedef struct Humiture_Typedef
{
    uint8_t temperature;    //温度
    uint8_t humidity;        //湿度
}Humiture_Typedef;
 
extern Humiture_Typedef Humiture_Data;

void DHT11_Config_Init(void);

uint8_t DHT11_Read_Data(Humiture_Typedef* Humiture);
#endif

 

dht11_drive_function.c

#include "dht11_drive_function.h"

Humiture_Typedef Humiture_Data;


/********************************************************************************
                                    引脚IO配置
*******************************************************************************/


/**********************************************************************
  * @ 函数名  :DHT11_GPIO_Config
  * @ 功能说明:配置DHT11的引脚
  * @ 参数    :无  
  * @ 返回值  :无
**********************************************************************/ 
static void DHT11_GPIO_Config(void)
{    
    DHT11_GPIO_ClockCmd(DHT11_GPIO_CLK,ENABLE);            //开启引脚时钟

    GPIO_InitTypeDef GPIO_InitStructure;
        
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

    
    GPIO_InitStructure.GPIO_Pin = DHT11_DATA_GPIO_PIN;
    GPIO_Init(DHT11_DATA_GPIO_PORT, &GPIO_InitStructure);
}



/**********************************************************************
  * @ 函数名  :DHT11_Config_Init
  * @ 功能说明:DHT11引脚初始化
  * @ 参数    :无  
  * @ 返回值  :无
**********************************************************************/ 
void DHT11_Config_Init(void)
{
    DHT11_GPIO_Config();
}
 

/**********************************************************************
  * @ 函数名  :DHT11_DATA_INTPUT
  * @ 功能说明:配置DATA引脚为输入
  * @ 参数    :无  
  * @ 返回值  :无
**********************************************************************/ 
static void DHT11_DATA_INTPUT(void)
{
    DHT11_GPIO_ClockCmd(DHT11_GPIO_CLK, ENABLE);    //打开GPIO时钟

    GPIO_InitTypeDef GPIO_InitStructure;    

    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;          

    GPIO_InitStructure.GPIO_Pin = DHT11_DATA_GPIO_PIN;    
    GPIO_Init(DHT11_DATA_GPIO_PORT, &GPIO_InitStructure); 
}


/**********************************************************************
  * @ 函数名  :DHT11_DATA_OUTPUT
  * @ 功能说明:配置DATA引脚为输出
  * @ 参数    :无  
  * @ 返回值  :无
**********************************************************************/ 
static void DHT11_DATA_OUTPUT(void)
{
    DHT11_GPIO_ClockCmd(DHT11_GPIO_CLK, ENABLE);    //打开GPIO时钟

    GPIO_InitTypeDef GPIO_InitStructure;    

    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;        //推挽输出 

    GPIO_InitStructure.GPIO_Pin = DHT11_DATA_GPIO_PIN;    
    GPIO_Init(DHT11_DATA_GPIO_PORT, &GPIO_InitStructure); 
}





/********************************************************************************
                                    驱动函数
*******************************************************************************/

/**********************************************************************
  * @ 函数名  :DHT11_Reset
  * @ 功能说明:起始信号,拉低数据线,保持至少 18ms时间,然后拉高数据线20~40us时间
  * @ 参数    :无  
  * @ 返回值  :无
**********************************************************************/       
static void DHT11_Start(void)       
{                 
    DHT11_DATA_OUTPUT();
    DHT11_DATA_L();
    DHT11_Delay_MS(20);            //拉低至少18ms
    DHT11_DATA_H();    
    DHT11_Delay_US(30);         //主机拉高20~40us
}



/**********************************************************************
  * @ 函数名  :DHT11_Check
  * @ 功能说明:产生起始信号后等待DHT11的响应
  * @ 参数    :无  
  * @ 返回值  :0:检测到DHT11   1:未检测到DHT11
**********************************************************************/    
static uint8_t DHT11_Check(void)        
{   
    uint8_t temp=0;
    
    DHT11_DATA_INTPUT();

    //DHT11响应时先拉低数据线,保持40~50us
    while(DHT11_DATA_READ() && temp < 100)  //DHT11会拉低40~50us
    {
        temp++;
        DHT11_Delay_US(1);
    };    
    if(temp >= 100)
    {
        return 1;
    }

    temp=0;
    
    //DHT11拉低后会再次拉高40~80us
    while(!DHT11_DATA_READ() && temp<100)//DHT11拉低后会再次拉高40~80us
    {
        temp++;
        DHT11_Delay_US(1);
    };
    if(temp >= 100)
    {
        return 1;
    }
    
    return 0;
}


/**********************************************************************
  * @ 函数名  :DHT11_Read_Bit
  * @ 功能说明:从DHT11读取一位数据
  * @ 参数    :无  
  * @ 返回值  :数据0或1
**********************************************************************/ 
static uint8_t DHT11_Read_Bit(void)              
{
     uint8_t temp=0;
    while(DHT11_DATA_READ() && temp < 100)//等待变为低电平
    {
        temp++;
        DHT11_Delay_US(1);
    }
    
    temp=0;
    
    while(!DHT11_DATA_READ()&& temp < 100)//等待变高电平
    {
        temp++;
        DHT11_Delay_US(1);
    }
    
    DHT11_Delay_US(40);//等待40us
    
    if(DHT11_DATA_READ())
    {
        return 1;
    }
    else 
    {
        return 0;
    }        
}


/**********************************************************************
  * @ 函数名  :DHT11_Read_Byte
  * @ 功能说明:从DHT11读取一个字节
  * @ 参数    :无  
  * @ 返回值  :读取的数据
**********************************************************************/ 
static uint8_t DHT11_Read_Byte(void)    
{        
    uint8_t Read_Data;

    for(uint8_t i=0;i<8;i++) 
    {
           Read_Data <<= 1; 
        Read_Data |= DHT11_Read_Bit();
    }
    
    return Read_Data;
}



/**********************************************************************
  * @ 函数名  :DHT11_Read_Data
  * @ 功能说明:从DHT11读取一次数据
  * @ 参数    :Humiture:温湿度 
  * @ 返回值  :0:正常  1:读取失败
**********************************************************************/ 
uint8_t DHT11_Read_Data(Humiture_Typedef* Humiture)    
{        
     uint8_t data_buffer[5];

    DHT11_Start();
    if(DHT11_Check() == 0)
    {
        for(uint8_t i=0;i<5;i++)//读取40位数据
        {
            data_buffer[i] = DHT11_Read_Byte();
        }
        
        if((data_buffer[0] + data_buffer[1] + data_buffer[2] + data_buffer[3]) == data_buffer[4])
        {
            Humiture->humidity = data_buffer[0];
            Humiture->temperature = data_buffer[2];
        }
    }
    else 
    {
        return 1;
    }
    
    return 0;        
}

 

posted @ 2020-08-13 22:16  孤情剑客  阅读(368)  评论(0)    收藏  举报