您当前的位置: 首页 >  ide

正点原子

暂无认证

  • 0浏览

    0关注

    382博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

【正点原子MP157连载】第二十七章 DHT11数字温湿度传感器实验-摘自【正点原子】STM32MP1 M4裸机CubeIDE开发指南

正点原子 发布时间:2022-03-26 14:58:39 ,浏览量:0

1)实验平台:正点原子STM32MP157开发板 2)购买链接:https://item.taobao.com/item.htm?&id=629270721801 3)全套实验源码+手册+视频下载地址:http://www.openedv.com/thread-318813-1-1.html 4)正点原子官方B站:https://space.bilibili.com/394620890 5)正点原子STM32MP157技术交流群:691905614 在这里插入图片描述

第二十七章 DHT11数字温湿度传感器实验

本章,我们将介绍数字温湿度传感器DHT11的使用,与前一章的DS18B20温度传感器相比,该传感器不但能测温度,还能测湿度。我们将学习如何获取DHT11传感器的温湿度数据,并把数据通过串口打印出来。 本章分为如下几个小节: 27.1、DHT11简介; 27.2、硬件设计; 27.3、软件设计; 27.4、编译和测试; 27.1 DHT11简介 27.1.1 DHT11简介 DHT11是一款温湿度一体化的数字传感器。该传感器包括一个电阻式测湿元件和一个NTC测温元件,并与一个高性能8位单片机相连接。通过单片机等微处理器简单的电路连接就能够实时的采集本地湿度和温度。DHT11与单片机之间能采用简单的单总线进行通信,仅仅需要一个I/O口。传感器内部湿度和温度数据共有40 bit的数据一次性传给单片机,数据采用校验和方式进行校验,有效的保证数据传输的准确性。DHT11功耗很低,5V电源电压下,工作平均最大电流0.5mA。 DHT11的技术参数如下: 工作电压范围:3.3V ~ 5.5V 工作电流:平均0.5mA 输出:单总线数字信号 测量范围:湿度2090%RH,温度050℃ 精度:湿度±5%,温度±2℃ 分辨率:湿度1%,温度1℃ DHT11的管脚排列如图43.1.1所示: 在这里插入图片描述

图27.1.1.1 DHT11管脚排列图 DHT11广泛应用于暖通空调、除湿器、农业、冷链仓储、测试及检测设备、消费品、 汽车、自动控制、数据记录器、气象站、家电、湿度调节器、医疗等相关温湿度检测控制领域。 27.1.2 DHT11工作时序简介

  1. 单总线结构 DHT11器件采用单总线通信,只有一根数据线,系统中的数据交换、控制均由单总线完成。单总线接一个约4.7kΩ的上拉电阻,当总线空闲时,总线状态为高电平。关于单总线我们在前面的DS18B20章节已经讲解过,后面编写程序时注意的是,要配置总线占用的IO口为开漏输出模式。
  2. 数据结构 单总线上的设备属于主从结构,只有主机呼叫从机时,从机才能应答,因此主机访问器件都必须严格遵循单总线序列,如果出现序列混乱,器件将不响应主机。虽然DHT11与DS18B20类似,都是单总线访问,但是DHT11的访问,相对DS18B20来说简单很多。下面我们先来看看DHT11的数据结构。 单总线上一次传送5 byte(40 bit)的数据,且高位先发送,数据分小数部分和整数部分,DHT11的数据格式为: 8bit湿度整数数据+8bit湿度小数数据+8bit温度整数数据+8bit温度小数数据+8bit校验位。 其中校验和数据为前面四个字节相加。传感器数据输出的是未编码的二进制数据,数据(湿度、温度、整数、小数)之间应该分开处理。 (1)温度是正数的情况 例如,某次从DHT11读到的数据如下图所示: byte4 byte3 byte2 byte1 byte0 00110101 00000000 00011000 00000100 01010001 湿度高8位 湿度低8位 温度高8位 温度低8位 校验位 整数 小数 整数 小数 校验位 根据以上的数据进行计算: 1)检查数据接收 00110101+00000000+00011000+00000100=01010001 计算结果和校验位相等,接收数据正确,如果计算得到的值和校验位不一致,那么本次接收的数据不正确,放弃,重新接收数据。 2)计算湿度和温度的值 湿度: 00110101(整数)=35H=53%RH 00000000(小数)=00H=0.0%RH 最后湿度=>53%RH+0.0%RH=53.0%RH 温度: 00011000(整数)=18H=24℃ 00000100 (小数)=04H=0.4℃ 最后温度=>24℃+0.4℃=24.4℃ (2)温度是负数的情况 如果,当温度低于0℃时,温度数据的低8位的最高位置为1,计算时,该位可以视为0。如果温度是负数,校验位和湿度计算和上面的情况一样,这里说明一下温度计算,如-10.1℃表示为00001010 10000001,计算方法为: 0000 1010(整数)=0AH=10℃ 00000001(小数)=01H=0.1℃ 最后温度=>-(10℃+0.1℃)=-10.1℃
  3. DHT11时序 DHT11上电后(DHT11上电后要等待1S以越过不稳定状态,在此期间不能发送任何指令),待1s过后,可以测试环境温湿度数据,DHT11的DATA数据线由上拉电阻拉高一直保持高电平,此时DHT11的DATA引脚处于输入状态,时刻检测外部信号。下面我们看看DHT11的时序: 1)复位信号和应答信号时序 首先主机发送开始信号(也叫复位信号),即:拉低数据线,保持t1(至少18ms,最大不得超过30ms)时间,然后主机拉高数据线t2(2040us)时间,然后主机读取DHT11的响应,正常的话,DHT11会拉低数据线,并保持t3(4050us)时间来作为响应信号,然后DHT11拉高数据线,保持t4(40~50us)时间后,DHT11开始输出数据。 在这里插入图片描述

图27.1.2.1 开始信号和应答信号 2)DHT11输出数字‘0’时序 DHT11每发送的1 bit 数据都以低电平开始,低电平延时时间约为1214us,然后DHT11拉高总线,如果总线拉高2628us,表示发送0,然后DHT11再将总线拉低12~14us,为下一次发送数据做准备。(注意,此时序图中,为按位发送。) 在这里插入图片描述

图27.1.2.2 DHT11输出数字‘0’ 3)DHT11输出数字‘1’时序 如果DHT11拉低总线1214us后,再将总线拉高116118us,表示发送数字1,然后DHT11再将总线拉低12~14us,为下一次发送数据做准备。(注意,此时序图中,为按位发送。) 在这里插入图片描述

图27.1.2.3 DHT11输出数字‘1’ 27.2 硬件设计

  1. 例程功能 把DHT11传感器插在预留的接口上,测试当前的环境温度和湿度,并将温度和湿度通过串口打印出来。实验中通过观察LED0闪烁提示程序在运行。预留的接口在开发板底板的位置如下: 在这里插入图片描述

图27.2.1 开发板硬件示意图 上图中的开发板预留接口的4个引脚从左到右依次为VCC、DQ、GND、GND,所以DHT11这样插入开发板(注意,不要插错!): 在这里插入图片描述

图27.2.2硬件连接示意图 2. 硬件资源 1)LED灯:LED0 2)UART4 3)DS18B20(接在PF2上) 在这里插入图片描述

表27.2.1硬件资源 3. 原理图 如下图,DS18B20接在PF2上,我们通过该IO口模拟单总线的时序来控制DS18B20: 在这里插入图片描述

图27.2.3原理图部分 27.3 软件设计 本实验配置好的实验工程已经放到了开发板光盘中,路径为:开发板光盘A-基础资料\1、程序源码\11、M4 CubeIDE裸机驱动例程\CubeIDE_project\ 20 DHT11。 27.3.1 新建和配置工程 新建工程DHT11,然后配置LED0和UART4,再配置PF2为开漏输出、上拉、高速模式: 在这里插入图片描述

图26.3.1.1 配置GPIO 本节实验会用到微秒延时函数,需要将第二十三章实验的delay.h和delay.c文件。将上一章节实验的BSP文件夹拷贝到M4工程的Core/Src下,然后在BSP文件夹下新建dht11.c文件,在BSP/Include下新建dht11.h文件,最后的部分工程如下: 在这里插入图片描述

图26.3.2 工程部分目录 27.3.2 添加用户代码 关于LED0和UART4相关的代码请参考前面实验章节部分,DHT11驱动代码我们把它放在dht11.c和dht11.h文件中。首先我们先看一下dht11.c头文件里面的内容。

1. dht11.h文件代码
	dht11.h文件代码如下:
#ifndef __DHT11_H
#define __DHT11_H 
#include"gpio.h"
/* DHT11 引脚 定义 */
#define DHT11_DQ_GPIO_PORT            GPIOF
#define DHT11_DQ_GPIO_PIN             GPIO_PIN_2
/* PF口时钟使能 */
#define DHT11_DQ_GPIO_CLK_ENABLE()    do{ __HAL_RCC_GPIOF_CLK_ENABLE(); }while(0)   

/* IO操作函数 */
#define DHT11_DQ_OUT(x)   do{ x ? \
	HAL_GPIO_WritePin(DHT11_DQ_GPIO_PORT, DHT11_DQ_GPIO_PIN, GPIO_PIN_SET) : \	HAL_GPIO_WritePin(DHT11_DQ_GPIO_PORT, DHT11_DQ_GPIO_PIN, GPIO_PIN_RESET); \							}while(0)   /* 数据端口输出 */
/* 数据端口输入 */
#define DHT11_DQ_IN       HAL_GPIO_ReadPin(DHT11_DQ_GPIO_PORT, DHT11_DQ_GPIO_PIN)  

uint8_t dht11_init(void);               /* 初始化DHT11 */
uint8_t dht11_check(void);              /* 检测是否存在DHT11 */
uint8_t dht11_read_data(uint8_t *temp,uint8_t *humi);   /* 读取温湿度 */

#endif

以上主要是对DHT11的相关引脚、时钟使能和IO操作函数进行宏定义,方便程序中调用。 2. dht11.c文件代码 根据前面对DHT11的时序分析,我们按照时序部分进行程序设计,首先是复位DHT11函数,如下: (1)复位DHT11

/**
 * @brief       复位DHT11
 * @param       无
 * @retval      无
 */
static void dht11_reset(void)
{
    DHT11_DQ_OUT(0);    	/* 拉低DQ */
    delay_ms(20);       	/* 拉低至少18ms */
    DHT11_DQ_OUT(1);    	/* DQ=1 */
    delay_us(30);       	/* 主机拉高20~40us */
}
(2)等待DHT11应答
/**
 * @brief       等待DHT11的回应
 * @param       无
 * @retval      0, DHT11正常
 *              	1, DHT11异常/不存在
 */
uint8_t dht11_check(void)
{
    uint8_t retry = 0;
    uint8_t rval = 0;
    while (DHT11_DQ_IN && retry = 100)                       	/* 超时,DHT11异常 */
    {
        rval = 1;
    }
    else
    {
        retry = 0;
        while (!DHT11_DQ_IN && retry = 100) rval = 1;        	/* 超时,DHT11异常 */
    }  
    return rval;
}
应答信号也是按照前面的时序图进行编写的,首先DHT11将总线拉低,所以程序先等待总线变为低电平,这里在测试引脚电平的时候,设置最大的检测时间是100us,如果超过100us内电平没有变化,则认为DHT11异常。如果DHT11拉低总线后,再释放总线,则总线为高电平,所以,在测试总线拉低以后,再检测总线是否被拉高。

(3)从DHT11读取一个位 和DS18B20不一样,DHT11不需要写的过程,直接可以读取温湿度数据:

1   /**
2    * @brief       从DHT11读取一个位
3    * @param       无
4    * @retval      读取到的位值: 0 / 1
5    */
6   uint8_t dht11_read_bit(void)
7   {
8       uint8_t retry = 0;
9       while (DHT11_DQ_IN && retry             
关注
打赏
1665308814
查看更多评论
0.1261s