STM32cubemx配置驱动DHT11模块

简介: STM32cubemx配置驱动DHT11模块

前言

本篇文章将带大家学习使用DHT11湿温度模块,使用这个模块可以获取当前的温度和湿度数据。DHT11可以用于智能家居,蔬菜大棚等项目当中适用范围广。


一、DHT11模块介绍

DHT11 是一种数字式温湿度传感器,由杜邦公司推出。它可以测量环境中的温度和湿度,并将测量结果以数字形式传输给微控制器或其他电子设备,适用于通过数字信号读取环境温湿度的应用场景。

DHT11 传感器使用单总线数据交换协议,可以通过一个 I/O 引脚进行控制和数据传输。它的测量精度为±2℃(在 0℃~50℃ 温度范围内)和±5%RH(在 20%~80%RH 湿度范围内),在低功耗和成本方面也表现优异。DHT11 传感器适用于许多应用场景,比如室内恒温恒湿、气象站、温室农业以及测量仓库、办公室等场所的温湿度等。

使用 DHT11 传感器的过程中需要注意一些事项。首先,DHT11 传感器测量时间较长,一般需要 1~2 秒左右才能完成一次温湿度测量。另外,传感器的电源电压范围必须在 3V~5V 之间,而且传感器的输出信号是串行数字信号,需要使用微控制器或其他数字电路进行采集和解析。因此,在接入 DHT11 传感器之前,需要对其进行一些电路设计和通信协议的处理才能正常使用。


二、DHT11引脚连接及cubemx配置

VCC----5V

GND----GND

S------信号引脚(接一个GPIO)

cubemx配置:

这里只需要配置一个定时器当作us级延时定时器来使用。GPIO的初始工作放到代码中实现。

配置一个串口来打印温度湿度数据:

三、DHT11时序分析

DHT11只需要通过一根数据闲就可以实现和单片机的通信:

根据时序图我们可以知道驱动DHT11首先需要发送一个起始信号,发送完毕后等待应答信号。

起始信号:引脚发送至少18ms低电平,然后再发送20-40us的高电平。

应答信号:低电平持续80us,高电平持续80us。

接收数据:

当等待到应答信号后就可以开始接受DHT11的数据了。

通过观察可以得知数据1和数据0起始部分都是50us的低电平,数据0高电平时间为26-28us之间,数据高电平时间为70us。我们主要就是根据高电平时间来区分到底是数据0还是数据1。

数据0:

数据1:

通过手册我们可以知道数据由小数部分和整数部分组成。完整的数据传输是40位,并且传感器首先发送更高的数据位。

这 40 位二进制数的组成如下:

8 位湿度整数数据位。

8 位湿度小数数据位。

8 位温度整数数据位。

8 位温度小数数据位。

8 位校验和数据位。

四、DHT11代码编写

有了上面时序图的分析我们就可以开始编写代码部分了。

代码部分需要注意的就是在发送完起始信号后对应数据线的GPIO要配置为输入模式,等待DHT11传输过来的应答信号和数据。在每次发送开始信号的时候都需要重新将数据引脚配置为输出引脚。

dht11.h

#ifndef _DH11_H_
#define _DH11_H_
#include"main.h"
#define u8 unsigned char 
#define u16 unsigned short
#define u32 unsigned int
//DATA IO的定义
#define DATA_SET() HAL_GPIO_WritePin(DATA_GPIO_Port, DATA_Pin, GPIO_PIN_SET)
#define DATA_RESET() HAL_GPIO_WritePin(DATA_GPIO_Port, DATA_Pin, GPIO_PIN_RESET)
#define DATA_READ() HAL_GPIO_ReadPin(DATA_GPIO_Port,DATA_Pin)
typedef struct
{
  u8 Data[5];//数据存放数组
  u8 index;
  u8 temp;//温度
  u8 humidity;//湿度
}DH11_DATA;
extern DH11_DATA DH11_data;//DH11属性封装
void DH11_Task(void);//后台轮询调用
#define DATA_Pin GPIO_PIN_7
#define DATA_GPIO_Port GPIOA
#endif

dht11.c

#include "dht11.h"
extern TIM_HandleTypeDef htim1;
static void DATA_OUTPUT(u8 flg);//DATA输出
static u8 DATA_INPUT(void);//DATA输入
static u8 DH11_Read_Byte(void);//DH11读信号
u8 DH11_Read(void);//读取DH11温度和湿度
static void Test(void);//测试程序
DH11_DATA DH11_data;
void Delay_us(uint16_t us)
{     //微秒延时
  uint16_t differ = 0xffff-us-5;        
  __HAL_TIM_SET_COUNTER(&htim1,differ); //设定TIM1计数器起始值
  HAL_TIM_Base_Start(&htim1);   //启动定时器 
  while(differ < 0xffff-5){ //判断
    differ = __HAL_TIM_GET_COUNTER(&htim1);   //查询计数器的计数值
  }
  HAL_TIM_Base_Stop(&htim1);
}
void DATA_OUTPUT(u8 flg)
{
    GPIO_InitTypeDef GPIO_InitStruct = {0};
  GPIO_InitStruct.Pin = DATA_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
  HAL_GPIO_Init(DATA_GPIO_Port, &GPIO_InitStruct);
  if(flg==0)
  {
    DATA_RESET();
  }
  else
  {
    DATA_SET();
  }
}
u8 DATA_INPUT(void)
{
    GPIO_InitTypeDef GPIO_InitStruct = {0};
  u8 flg=0;
  GPIO_InitStruct.Pin = DATA_Pin;
    GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
    GPIO_InitStruct.Pull = GPIO_PULLUP;
    HAL_GPIO_Init(DATA_GPIO_Port, &GPIO_InitStruct);
  if(DATA_READ()==GPIO_PIN_RESET)
  {
    flg=0;
  }
  else 
  {
    flg=1;
  }
  return flg;
}
u8 DH11_Read_Byte(void)
{
    u8 ReadDat=0;
    u8 temp=0;
    u8 retry=0;
    u8 i=0;
    for(i=0;i<8;i++)
    {
      while(DATA_READ()==0&&retry<100)//等待直到DHT11输出高电平
      {
        Delay_us(1);
        retry++;
      }
      retry=0;
      Delay_us(40);
      if(DATA_READ()==1)
      {
        temp=1;
      }
      else
      {
        temp=0;
      }
      while(DATA_READ()==1&&retry<100)//等待直到DHT11输出低电平,表示退出。本轮1bit信号接收完毕。
      {
        Delay_us(1);
        retry++;
      }
      retry=0;
      ReadDat<<=1;
      ReadDat|=temp;
    }
    return ReadDat;
}
u8 DH11_Read(void)
{
  u8 retry=0;
  u8 i=0;
  DATA_OUTPUT(0);//设置为输出模式MCU向DH11发送信号
  HAL_Delay(18);
  DATA_SET();
  Delay_us(20);
  DATA_INPUT();//设置为输入模式DH11向MCU发送信号
  Delay_us(20);
  if(DATA_READ()==0)
  {
    while(DATA_READ()==0&&retry<100)
    {
      Delay_us(1);
      retry=0;
    }
    retry=0;
    while(DATA_READ()==1&&retry<100)
    {
      Delay_us(1);
      retry++;
    }
    retry=0;
    for(i=0;i<5;i++)//Data[0]湿度, Data[2]温度。Data[1]和Data[3]分别为0和2的小数位。Data[4]用于校验。
    {
      DH11_data.Data[i]=DH11_Read_Byte();
    }
    Delay_us(50);
  }
  u32 sum=DH11_data.Data[0]+DH11_data.Data[1]+DH11_data.Data[2]+DH11_data.Data[3];//校验
  if((sum)==DH11_data.Data[4])
  {
    DH11_data.humidity=DH11_data.Data[0];//获取湿度
    DH11_data.temp=DH11_data.Data[2];//获取温度
    return 1;    
  }
  else
  {
    return 0;
  }
}
void Test(void)
{
  if(DH11_Read())
  {
    DH11_data.index++;
    if(DH11_data.index>=128)
    {
      DH11_data.index=0;
    }
  }
}
void DH11_Task(void)
{
     Test();
}

main函数测试代码:

这里需要注意的就是DHT11的数据读取不要太快了,因为DHT11数据转换也是需要一定时间的。

  DH11_Task();
  printf("Temp is %d\r\n", DH11_data.temp);
  printf("Hum is %d\r\n", DH11_data.humidity);
    HAL_Delay(3000);

总结

本篇文章就介绍到这里,大家可以自己尝试进行DHT11的驱动程序编写。

源码将放到公众号中:回复数字8即可得到源码。

相关文章
STM32Cubemx PWM驱动加湿器模拟火山喷发效果
STM32Cubemx PWM驱动加湿器模拟火山喷发效果
269 14
STM32Cubemx PWM驱动SG90舵机
STM32Cubemx PWM驱动SG90舵机
626 13
STM32CubeMX mpu6050驱动
STM32CubeMX mpu6050驱动
211 10
STM32CubeMX EC11旋转编码器驱动
STM32CubeMX EC11旋转编码器驱动
1096 10
STM32CubeMX OLED驱动
STM32CubeMX OLED驱动
211 10
|
芯片
STM32CubeMX TM1637驱动数码管
STM32CubeMX TM1637驱动数码管
738 6
|
传感器
手把手在STM32F103C8T6上构建可扩展可移植的DHT11驱动
【8月更文挑战第29天】本文详细介绍在STM32F103C8T6上构建可扩展且可移植的DHT11温湿度传感器驱动的步骤,包括硬件与软件准备、硬件连接、驱动代码编写及测试。通过这些步骤,可根据实际项目需求优化和扩展代码。
593 0
STM32CubeMX WS2812B灯驱动
STM32CubeMX WS2812B灯驱动
881 1
STM32CubeMX ULN2003步进电机驱动
STM32CubeMX ULN2003步进电机驱动
326 0
STM32Cubemx TB6612直流电机驱动
STM32Cubemx TB6612直流电机驱动
755 0