首页 > 其他分享 >STM32cubemx配置驱动DHT11模块

STM32cubemx配置驱动DHT11模块

时间:2023-06-09 12:33:06浏览次数:46  
标签:DH11 u8 void STM32cubemx 模块 GPIO DATA 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即可得到源码。

标签:DH11,u8,void,STM32cubemx,模块,GPIO,DATA,DHT11
From: https://blog.51cto.com/u_16153875/6446754

相关文章

  • Linux驱动基础(HC-SR04超声波模块)
    (文章目录)前言本篇文章将讲解HC-SR04超声波模块的驱动程序编写,有了上篇SR501模块驱动程序编写的基础后这篇文章大家将会学的非常轻松。一、HC-SR04超声波模块介绍HC-SR04超声波模块是一种常用于距离测量和障碍物检测的模块。它通过发射超声波信号并接收回波来计算所测量物体......
  • 模块的动态导入与重载
    1、动态导入__import__(name,globals=None,locals=None,fromlist=(),level=0)->module该函数是builtins模块函数,用于动态加载模块name,str类型,可以指向某个py文件,也可以指向某个包。但是必须存在,否则会报错fromlist,tuple(str)类型,如果想加载其它包下的py文件,可以由name......
  • 实验7 面向对象编程与内置模块
    实验任务1实验源码classAccount:'''一个模拟银行账户的简单类'''def__init__(self,name,account_number,initial_amount=10):'''构造新账户'''self._name=nameself._card_no=account_......
  • 实验7 面向对象编程与内置模块
    实验任务1:模拟银行账户,理解类的封装特性'''银行账户数据:持卡人姓名、账号、当前余额操作:取款、存款、打印账户信息、返回账户余额'''classAccount:'''一个模拟银行账户的简单类'''def__init__(self,name,account_number,initial_amount=10):'&......
  • apache 使用 mod_fcgid.so模块时 配置指令
    FcgidBusyScanInterval指令说明:扫描繁忙超时进程的间隔语法: FcgidBusyScanInterval seconds默认:FcgidBusyScanInterval120环境: 服务器配置状态:外部对应的老指令:BusyScanInterval该模块将执行FcgidBusyTimeout检查,在此区间。FcgidBusyTimeout指令说明:杀死处理请求超过Fcgi......
  • 正则表达式、re模块
    正则表达式的介绍定义:"""它是一门独立的语言,跟Python等的语言没有任何的关系,但是其他语言可以使用正则表达式来做一些功能,主要是用来筛选数据的。"""什么......
  • 正则表达式 re模块
    目录正则表达式字符组字符量词贪婪匹配和非贪婪匹配转义符\re模块常用方法无名分组和有名分组正则表达式正则表达式是对字符串操作的一种逻辑公式,就是用事先定义好的一些特定字符、及这些特定字符的组合,组成一个“规则字符串”,这个“规则字符串”用来表达对字符串的一种过滤逻......
  • Nginx 安装 ModSecurity 模块
    1、安装ModSecuritycd/usr/localgitclonehttps://github.com/SpiderLabs/ModSecurity.gitcdModSecuritygitsubmoduleinitgitsubmoduleupdateshbuild.sh./configuremakemakeinstall2、安装ModSecurity-nginxcd/usr/localgitclonehttps://github.com/SpiderLabs/ModSec......
  • Python使用os模块创建带时间戳的文件
    直接上源码:importosimporttime#定义函数名:在py文件路径下创建cache的txt文件deftxt(name,text):#os.getcwd()获取当前的工作路径;new=os.getcwd()+'/cache/'#判断当前路径是否存在,没有则创建new文件夹ifnotos.path.exists(new):......
  • 智能座舱之蓝牙模块测试要点
    智能座舱蓝牙模块是车辆中的一项重要功能,用于提供与移动设备的无线连接,例如手机、音乐播放器等。下面是对智能座舱蓝牙模块测试的详细介绍:1.连接和配对测试测试蓝牙模块的连接性能,验证其能够与各种类型的设备进行配对和连接。验证蓝牙模块的连接稳定性,包括在连接过程中的自......