STM32 DHT11

STM32 DHT11

1. 开发平台

  • 野火STM32F429开发板
  • 使用标准库开发

2. DHT11介绍

  • DHT11温湿度传感器,是一个单总线传感器。
    在这里插入图片描述
    所以DHT11最先输出的是湿度然后在输出温度(最开始我没认真看,以为先输出温度再输出湿度,然后打印出来的数据是反的)

3. DHT11的时序

在这里插入图片描述

  • 先是主机发送开始信号
    在这里插入图片描述
  • 然后就DHT11响应
    在这里插入图片描述
  • DHT11发送数据
    在这里插入图片描述
  • 最后要把数据线拉高,释放总线

代码如下:

dht11 .h

#ifndef __DHT11__H
#define __DHT11__H

#include "stm32f4xx.h"
#include "systick.h"
#include "USART.h"
#include "stdio.h"

//DATA线引脚为PD6

#define DHT11_OUT_H      GPIO_SetBits(GPIOD,GPIO_Pin_6)
#define DHT11_OUT_L       GPIO_ResetBits(GPIOD,GPIO_Pin_6)
#define DHT11_READ   GPIO_ReadInputDataBit(GPIOD,GPIO_Pin_6)

#define DHT11_CLK    RCC_AHB1Periph_GPIOD
#define DHT11_PIN    GPIO_Pin_6
#define DHT11_PORT   GPIOD

void DHT11_Init (void);
void DHT11_MODE_IN(void);
void DHT11_MODE_OUT(void);
uint8_t DHT11_Read_Byte(void);
uint8_t DHT11_ReadData(uint8_t *temp,uint8_t *humi);
void DHT11_Data(void);


#endif

dht11.c

#include "DHT11.h"

uint8_t temp=0;
uint8_t humi=0;

//DHT11驱动
void DHT11_Init (void)
{
    RCC_AHB1PeriphClockCmd(DHT11_CLK,ENABLE);
    
    GPIO_InitTypeDef GPIO_InitStruct;
    GPIO_InitStruct.GPIO_OType=GPIO_OType_PP;
    GPIO_InitStruct.GPIO_Pin=DHT11_PIN;
    GPIO_InitStruct.GPIO_PuPd=GPIO_PuPd_UP;
    GPIO_InitStruct.GPIO_Speed=GPIO_Speed_100MHz;
    GPIO_InitStruct.GPIO_Mode=GPIO_Mode_OUT;
    GPIO_Init(DHT11_PORT,&GPIO_InitStruct);
}

//输入模式
void DHT11_MODE_IN(void)
{
    GPIO_InitTypeDef GPIO_InitStruct;
    GPIO_InitStruct.GPIO_OType=GPIO_OType_PP;
    GPIO_InitStruct.GPIO_Pin=DHT11_PIN;
    GPIO_InitStruct.GPIO_PuPd=GPIO_PuPd_UP;
    GPIO_InitStruct.GPIO_Speed=GPIO_Speed_100MHz;
    GPIO_InitStruct.GPIO_Mode=GPIO_Mode_IN;
    GPIO_Init(DHT11_PORT,&GPIO_InitStruct);
}

//输出模式
void DHT11_MODE_OUT(void)
{
    GPIO_InitTypeDef GPIO_InitStruct;
    GPIO_InitStruct.GPIO_OType=GPIO_OType_PP;
    GPIO_InitStruct.GPIO_Pin=DHT11_PIN;
    GPIO_InitStruct.GPIO_PuPd=GPIO_PuPd_UP;
    GPIO_InitStruct.GPIO_Speed=GPIO_Speed_100MHz;
    GPIO_InitStruct.GPIO_Mode=GPIO_Mode_OUT;
    GPIO_Init(DHT11_PORT,&GPIO_InitStruct);
}

//读取一个字节    
uint8_t DHT11_Read_Byte(void)
{
    uint8_t i,data;
    for(i=0;i<8;i++)
    {
        if(DHT11_READ==0)
        {
            while(DHT11_READ==0);
        }
        DELAY_us (40);   //40us
        if(DHT11_READ==1)
        {
            while(DHT11_READ==1);//这里要等待高电平结束,否者读取下一位的时候会因为高电平没有结束而跳过上一个if
            data|=(uint8_t)0x01<<(7-i);
        }
        else
            data&=(uint8_t)~0x01<<(7-i);
                     
    }
    return data;
}

//读五个字节
uint8_t DHT11_ReadData(uint8_t *temp,uint8_t *humi)
{
    uint8_t buf[5];
    uint8_t i;
    for(i=0;i<5;i++)
    {
        buf[i]=DHT11_Read_Byte();
        
    }
    if(buf[0]+buf[1]+buf[2]+buf[3]==buf[4])
    {
        *temp=buf[2];
        *humi=buf[0];
        return 1;
    }
    else
        return 0;    
}

//DHT11 读数据
void DHT11_Data(void)
{
    DHT11_Init ();
    DHT11_OUT_L;
    DELAY_us(20000);
    DHT11_OUT_H;
    DELAY_us(20);
    DHT11_MODE_IN();
    if(DHT11_READ==0)
    {
        while(DHT11_READ==0);
        while(DHT11_READ==1);
        DHT11_ReadData(&temp,&humi);
        printf("温度:%d      湿度:%d\n",temp,humi);
    }
    DHT11_MODE_OUT();
    DHT11_OUT_H;

}    
发布了13 篇原创文章 · 获赞 19 · 访问量 1818

猜你喜欢

转载自blog.csdn.net/qq_44622367/article/details/100540916