源自:https://blog.csdn.net/qq_34952376/article/details/81193938

在我们刚开始进入单片机的学习中,练习写传感器的时序是必不可少的,其实我比较推荐大家刚开始练习的时候使用DHT11来练习。

推荐的原因:

  1. 因为DHT11的时序简单。
  2. DHT11是国产的,全中文的参考手册,不用担心英文看不懂。
  3. 功能少,就只有一个测量温湿度的功能。

综上,因此DHT11我认为是非常适合刚开始入门单片机的朋友学习的。

那么在使用传感器前,我们必须要先看数据手册,并不需要全部浏览,我们只需要看他重要的点,就OK了。

这就是DHT11温湿度传感器的外观,我们了解一下就好。

接下来我们看一起DHT11的参数特性

用红框圈出来的,就是重点,我们必须知道,这个DHT11温湿度传感器的测量范围,以及精度、分辨率。如果超出了这个范围,那么DHT11就不能够使用了。

接下来看一下引脚说明。            我们要注意的是:这个器件使用的是单总线协议是总所周知的了,但是他的供电范围我们也需要了解一下,范围是3.5-5.5v。如果超出这个范围,传感器可能会烧、假如低于这个范围,可能传感器会读出错误的温湿度数据或者压根就罢工了。   因此,我们在使用那些3.3v单片机做编程的时候,就要注意这一点了。

这个是数据手册上显示的DHT11典型的电路连接方法,我们再数据口上要接上一个上拉电阻。供电所使用的为7805的稳压电源,也就是5V。实际上,只要我们满足他的供电电压范围,都是能够工作的。

接下来我们看一下它的数据格式(重点)

DHT11用的是单总线协议,一次传送40位的数据。     注意了,看到这一句话,也就是说我们每次读取DHT11的数据时,都要一次性读取40次,也就是读取40位。并且数据前16位是与湿度相关的,中间16位是与温度相关的,最后八位是用来校验的,当我们校验成功后,证明这一次的温湿度结果正确的,我们单片机就可以使用这个温湿度值;如果校验不通过,那么就代表我们这次读取出来的温湿度值,是错误的(也许是我们的时序错误了,也许是传感器的问题),我们不进行采样。

同时呢,商家的数据手册还给出了一个校验数据的示例图,而且还是全中文的,所以说我说的没错吧,这个器件是真的简单到不能再简单了,非常适合新手入门练习如何写时序。

DHT11的总体通信流程。第一步:主机先发送开始信号,从机会返回一个相应信号进行应答。    第二步:主机信号线拉高准备接收数据。    第三部:开始接收数据(一次接收40位)。

那么这个就是一个人数据读取的一个流程,那么我们每一个流程又应该怎么做呢?

步骤一:DHT11 上电后(DHT11 上电后要等待 1S 以越过不稳定状态在此期间不能发送任何指令),测试环境
温湿度数据,幵记录数据,同时 DHT11 的 DATA 数据线由上拉电阻拉高一直保持高电平;此时 DHT11 的
DATA 引脚处于输入状态,时刻检测外部信号。

步骤二:微处理器的 I/O 设置为输出同时输出低电平,且低电平保持时间不能小于 18ms,然后微处理器的 I/O
设置为输入状态,由于上拉电阻,微处理器的 I/O 即 DHT11 的 DATA 数据线也随之变高,等待 DHT11 作
出回答信号,发送信号如图所示:

步骤三:DHT11 的 DATA 引脚检测到外部信号有低电平时,等待外部信号低电平结束,延迟后 DHT11 的 DATA
引脚处于输出状态,输出 80 微秒的低电平作为应答信号,紧接着输出 80 微秒的高电平通知外设准备接
收数据,微处理器的 I/O 此时处于输入状态,检测到 I/O 有低电平(DHT11 回应信号)后,等待 80 微秒
的高电平后的数据接收,发送信号如图所示:

步骤四:由 DHT11 的 DATA 引脚输出 40 位数据,微处理器根据 I/O 电平的变化接收 40 位数据,位数据“0”
的格式为: 50 微秒的低电平和 26-28 微秒的高电平,位数据“1”的格式为: 50 微秒的低电平加 70
微秒的高电平。位数据“0”、“1”格式信号如图所示:

(我们可以把这一段的时序理解为,我们主机先把数据线拉低50us,然后延时等待40us,然后再去读取信号线的电平,如果为低电平,则为位“0”;如果为高电平,则为位“1”)。

结束信号:DHT11 的 DATA 引脚输出 40 位数据后,继续输出低电平 50 微秒后转为输入状态,由于上拉电阻随
之变为高电平。但 DHT11 内部重测环境温湿度数据,幵记录数据,等待外部信号的到来。

我们在数据手册上了解的就这么多就可以了。

同时,我自己也对DHT11的时序做了一个总结

一. 单片机上点后1s内不读取(不重要)

二. 主机(单片机)发送起始信号:1.主机先拉高data。2.拉低data延迟18ms。
                                3.拉高data(单片机引脚设置为输入)。
                                
三. 从机(DHT11)收到起始信号后进行应答:
        从机拉低data,主机读取到data线被拉低持续80us后从机拉高data线,
        持续80us,直到高电平结束,意味着主机可以开始接受数据。
       
四. 主机开始接收数据:
        1.主机先把data线拉高(io设置为输入)。
        2.从机把data线拉低,主机读取data线电平,直到低电平结束(大约50us)
        从机拉高data线后,延迟40us左右(28~70us之间)主机再次读取data线
        电平,如果为低电平,则为“0”,如果为高电平,则为“1”。
        3.继续重复上述1,2步骤累计40次。

五. data线拉低50us代表读取结束

六. 校验数据

那么我们在程序上应该如何设计呢?(这里我的程序是基于stm32微处理器来讲解的,其他单片机也一样的操作,时序都是相同的)

准备阶段我们先要有3个函数,数据引脚初始化函数,还有数据引脚切换输入输出方向的函数。

  1.  
    void dht11_init (void )
  2.  
    {
  3.  
    GPIO_InitTypeDef GPIO_InitStructure;
  4.  
    /* Enable clock */
  5.  
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA , ENABLE);
  6.  
     
  7.  
    /* Configure Ports */
  8.  
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
  9.  
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  10.  
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
  11.  
    GPIO_Init(GPIOA, &GPIO_InitStructure);
  12.  
     
  13.  
    GPIO_SetBits(GPIOA, GPIO_Pin_7);
  14.  
    }
  15.  
     
  16.  
    void mode_input(void )
  17.  
    {
  18.  
    GPIO_InitTypeDef GPIO_InitStructure;
  19.  
     
  20.  
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
  21.  
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
  22.  
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
  23.  
    GPIO_Init(GPIOA, &GPIO_InitStructure);
  24.  
    }
  25.  
     
  26.  
    void mode_output(void )
  27.  
    {
  28.  
    GPIO_InitTypeDef GPIO_InitStructure;
  29.  
     
  30.  
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
  31.  
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  32.  
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
  33.  
    GPIO_Init(GPIOA, &GPIO_InitStructure);
  34.  
    }

接下来我们就再写一个函数,来读取dht11数据即可

  1.  
    unsigned int dht11_read(void)
  2.  
    {
  3.  
    int i;
  4.  
    long long val;
  5.  
    int timeout;
  6.  
     
  7.  
    GPIO_ResetBits(GPIOA, GPIO_Pin_7);
  8.  
    delay_us(18000); //pulldown for 18ms
  9.  
    GPIO_SetBits(GPIOA, GPIO_Pin_7);
  10.  
    delay_us( 20 ); //pullup for 30us
  11.  
     
  12.  
    mode_input();
  13.  
     
  14.  
    //等待dht11拉高80us
  15.  
    timeout = 5000;
  16.  
    while( (! GPIO_ReadInputDataBit (GPIOA, GPIO_Pin_7)) && (timeout > 0) ) timeout--; //wait HIGH
  17.  
     
  18.  
    //等待dht11拉低80us
  19.  
    timeout = 5000;
  20.  
    while( GPIO_ReadInputDataBit (GPIOA, GPIO_Pin_7) && (timeout > 0) ) timeout-- ; //wait LOW
  21.  
     
  22.  
    #define CHECK_TIME 28
  23.  
     
  24.  
    for(i=0;i<40;i++)
  25.  
    {
  26.  
    timeout = 5000;
  27.  
    while( (! GPIO_ReadInputDataBit (GPIOA, GPIO_Pin_7)) && (timeout > 0) ) timeout--; //wait HIGH
  28.  
     
  29.  
    delay_us(CHECK_TIME);
  30.  
    if ( GPIO_ReadInputDataBit (GPIOA, GPIO_Pin_7) )
  31.  
    {
  32.  
    val=(val<<1)+1;
  33.  
    } else {
  34.  
    val<<=1;
  35.  
    }
  36.  
     
  37.  
    timeout = 5000;
  38.  
    while( GPIO_ReadInputDataBit (GPIOA, GPIO_Pin_7) && (timeout > 0) ) timeout-- ; //wait LOW
  39.  
    }
  40.  
     
  41.  
    mode_output();
  42.  
    GPIO_SetBits(GPIOA, GPIO_Pin_7);
  43.  
     
  44.  
    if (((val>>32)+(val>>24)+(val>>16)+(val>>8) -val ) & 0xff ) return 0; //校验
  45.  
    else return val>>8;
  46.  
     
  47.  
    }

只要按照上述的时序步骤来操作,就能够读取出DHT11的温湿度值啦。

同时我们要注意,只有读出来的数据校验通过了,我们才使用这一次的温湿度数据。

还有他读取出来40位数据的数据结构: 8位湿度整数数据+8位湿度小数数据+8位温度整数数据+8位温度小数数据+8位校验位

DHT11温湿度传感器编程思路以及代码的实现(转载)的更多相关文章

  1. STC15系列通用-STC15F2K60S2/STCW4K32S4读取DHT11温湿度传感器数据串口输出代码实例工程免费下载

    //为了方便大家调试,另附程序工程共大家下载,下载地址:https://www.90pan.com/b1908750 ​ //************************** //程序说明:stc ...

  2. 在树莓派上读取DHT11温湿度传感器-python代码实现及常见问题(全面简单易懂)

    最近由于自己的课题需要,想要用在树莓派上使用DHT11温湿度传感器来读取空气中温湿度,遇到了几个问题,解决之后也对之前的知识进行了回顾,总结,特整理如下,希望能给也在学习树莓派的小伙伴们带来一些帮助. ...

  3. Arduino和C51开发DHT11温湿度传感器

    技术:51单片机.Arduino.DHT11.温湿度传感器.传感器   概述 学习单片机离不开对传感器的学习,本文主要介绍DHT11温湿度传感器的使用方法,同学也可以了解更多的传感器,这对你以后开发产 ...

  4. DHT11温湿度传感器模块使用方法和驱动代码实现

    DHT11模块简介 DHT11是一款价格便宜,易于使用的温度湿度测量二合一传感器.它具有超小体积.极低功耗的特点.它使用单根总线与单片机进行双向的串行数据传输,信号传输距离可达20米以上.非常适用于对 ...

  5. 【雕爷学编程】Arduino动手做(55)--DHT11温湿度传感器

    37款传感器与模块的提法,在网络上广泛流传,其实Arduino能够兼容的传感器模块肯定是不止37种的.鉴于本人手头积累了一些传感器和模块,依照实践(动手试试)出真知的理念,以学习和交流为目的,这里准备 ...

  6. 树莓派使用DHT11温湿度传感器

    一.相关介绍 DHT11介绍: DHT11是一款比较便宜的温湿度传感器模块.读取数据只需要占用一个IO口.能够同时测量温度和相对湿度. DHT11的数据手册可以看这里:http://wenku.bai ...

  7. 玩转X-CTR100 l STM32F4 l DHT11温湿度传感器

    我造轮子,你造车,创客一起造起来!塔克创新资讯[塔克社区 www.xtark.cn ][塔克博客 www.cnblogs.com/xtark/ ] DHT11数字温湿度传感器是一款含有已校准数字信号输 ...

  8. 四博智慧物联系统入门示例-1.增加一个DHT11温湿度传感器

    1.准备工作 DOIT农业控制开发板或者esp32模组,并下载 四博智慧物联系统快速入门-2.准备工作 章节中的固件 DHT11连接在端口01 使用快速入门注册的管理账号和用户 2.配置网络 3.绑定 ...

  9. STM32驱动DHT11温湿度传感器

    DHT11 是一款湿温度一体化的数字传感器.该传感器包括一个电阻式测湿元件和一个 NTC 测温元件,并与一个高性能 8 位单片机相连接.通过单片机等微处理器简单的电路连接就能够 实时的采集本地湿度和温 ...

随机推荐

  1. March 11 2017 Week 10 Saturday

    Wisdom outweighs any wealth. 智慧比财富更有价值. Wisdom can create wealth if used in proper ways, it can help ...

  2. 深入浅出C/C++中的正则表达式库

    写在前面: 本文是面向有正则表达式基础的读者朋友的,如果你还不知道正则表达式是什么,请先到这里学习一下  :http://en.wikipedia.org/wiki/Regular_expressio ...

  3. 如何在Kubernetes里给PostgreSQL创建secret

    创建一个initdb.sql文件,输入如下内容: -- This is a postgres initialization script for the postgres container. -- ...

  4. 【转载】#446 - Deciding Between an Abstract Class and an Interface

    An abstract class is a base class that may have some members not implemented in the base class, but ...

  5. Android应用经典主界面框架之中的一个:仿QQ (使用Fragment, 附源代码)

    备注:代码已传至https://github.com/yanzi1225627/FragmentProject_QQ 欢迎fork,如今来审视这份代码,非常多地方写的不太好,欢迎大家指正.有时间我会继 ...

  6. 20165322 实验二《Java面向对象程序设计》实验报告

    实验二<Java面向对象程序设计>实验报告 实验内容 初步掌握单元测试和TDD 理解并掌握面向对象三要素:封装.继承.多态 初步掌握UML建模 熟悉S.O.L.I.D原则 了解设计模式 实 ...

  7. 布局方式-float布局

    float的特性一 .元素‘浮动’ .脱离文档流 .但不脱离文本流 首先看一个案例,直观的了解下float的特性 <style> .container{ background: red; ...

  8. 【转】JS模块化工具requirejs教程(二):基本知识

    前一篇:JS模块化工具requirejs教程(一):初识requirejs 我们以非常简单的方式引入了requirejs,这一篇将讲述一下requirejs中的一些基本知识,包括API使用方式等. 基 ...

  9. JS动态修改微信浏览器中的title

    JS动态修改微信浏览器中的title我们的原理是设置一个ifame然后我们再加载一下就可以实现了,具体的例子如下所示. 平时使用JS修改title,直接document.title=新标题就好了 这样 ...

  10. 【luogu P2746 [USACO5.3]校园网Network of Schools】 题解

    题目链接:https://www.luogu.org/problemnew/show/P2812 注意:判断出入度是否为0的时候枚举只需到颜色的数量. 坑点:当只有一个强连通分量时,不需要再添加新边. ...