收藏官网首页
查看: 10736|回复: 3

DHT11温湿度传感器驱动

321

主题

1054

帖子

4430

积分

论坛元老

Rank: 8Rank: 8

积分
4430
QQ
发表于 2017-5-11 20:05:48 | 显示全部楼层 |阅读模式
校园创客福利
本帖最后由 bigfanofloT 于 2017-5-16 19:44 编辑

一、DHT11介绍
DHT11是一款有已校准数字信号输出的温湿度传感器。它应用专用的数字模块采集技术和温湿度传感技术,确保产品具有极高的可靠性和卓越的长期稳定性。传感器包括一个电阻式感湿元件和一个NTC测温元件,并与一个高性能8位单片机相连接。因此该产品具有品质卓越、超快响应、抗干扰能力强、性价比极高等优点。每个DHT11传感器都在极为精确的湿度校验室中进行校准。校准系数以程序的形式存在OTP内存中,传感器内部在检测信号的处理过程中要调用这些校准系数。单线制串行接口,使系统集成变得简易快捷。超小的体积、极低的功耗,使其成为该类应用中,在苛刻应用场合的最佳选择。产品为4针单排引脚封装,连接方便。
主要性能指标如下:
测量范围:湿度20-90%RH, 温度0~50℃
分辨率:湿度1%RH, 温度1℃
精度:湿度+/-5%RH, 温度+/-2℃
量程:湿度20-90%RH, 温度0~50℃
供电电压 :3.3~5.5V DC
输 出:单总线数字信号
长期稳定性: <±1%RH/年

DHT11实物.jpg
图1 DHT11实物图

DHT11输出单总线数字信号,可以十分方便的与MCU连接,典型使用方法如图2所示:
DHT11典型电路.png
图2 DHT11典型应用电路
二、硬件连线
对于gokit V2.3扩展板,板载DHT11的数字输出IO连接到了arduino UNO接口的D3,如图3所示:
DHT11原理图1.png
图3 Gokit V2.3扩展板DHT11原理图
根据Nucleo-F767ZI的原理图,图4可以知道,STM32F767ZIT6的GPIO PE13连接到了Arduino UNO接口的D3,因此在后面我们将配置PE13与DHT11通信,根据DHT11时序编写驱动。
DHT11原理图2.png
图4 Nucleo-F767ZI的Arduino UNO接口原理图

三、DHT11时序
DATA 用于微处理器与 DHT11之间的通讯和同步,采用单总线数据格式,一次通讯时间4ms左右,数据分小数部分和整数部分,具体格式在下面说明,当前小数部分用于以后扩展,现读出为零。
操作流程如下:
一次完整的数据传输为40bit,高位先出。
数据格式:8bit湿度整数数据+8bit湿度小数数据+8bi温度整数数据+8bit温度小数数据+8bit校验和
数据传送正确时校验和数据等于“8bit湿度整数数据+8bit湿度小数数据+8bi温度整数数据+8bit温度小数数据”所得结果的末8位。

用户MCU发送一次开始信号后,DHT11从低功耗模式转换到高速模式,等待主机开始信号结束后,DHT11发送响应信号,送出40bit的数据,并触发一次信号采集,用户可选择读取部分数据.从模式下,DHT11接收到开始信号触发一次温湿度采集,如果没有接收到主机发送开始信号,DHT11不会主动进行温湿度采集.采集数据后转换到低速模式。
通讯过程如下图:

11.jpg
总线空闲状态为高电平,主机把总线拉低等待DHT11响应,主机把总线拉低必须大于18毫秒,保证DHT11能检测到起始信号。DHT11接收到主机的开始信号后,等待主机开始信号结束,然后发送80us低电平响应信号.主机发送开始信号结束后,延时等待20-40us后, 读取DHT11的响应信号,主机发送开始信号后,可以切换到输入模式,或者输出高电平均可, 总线由上拉电阻拉高。
22.jpg

总线为低电平,说明DHT11发送响应信号,DHT11发送响应信号后,再把总线拉高80us,准备发送数据,每一bit数据都以50us低电平时隙开始,高电平的长短定了数据位是0还是1.格式见下面图示.如果读取响应信号为高电平,则DHT11没有响应,请检查线路是否连接正常.当最后一bit数据传送完毕后,DHT11拉低总线50us,随后总线由上拉电阻拉高进入空闲状态。        
数字0信号表示方法如下图:

33.jpg
数字1信号表示方法.如下图:
44.jpg
四、完整程序
如下是DHT11驱动的完整代码,用户可以十分方便的移植到其它型号STM32或者MCU,只需修改GPIO定义、GPIO读写即可。Hal_temp_hum.h文件如下:
  1. #ifndef _HAL_HEMP_HUM_H
  2. #define _HAL_HEMP_HUM_H

  3. #include <stdio.h>
  4. #include "stm32f7xx_hal.h"<font color="#008000">//若用户使用了其它MCU,需要修改此处MCU相关头文件</font>

  5. <font color="#008000">//Set GPIO Direction,若用户使用不同的GPIO请修改此处</font>
  6. #define DHT11_DIN_Pin GPIO_PIN_13
  7. #define DHT11_DIN_GPIO_Port GPIOE
  8.         <font color="#008000">//控制GPIO输出高低电平宏</font>
  9. #define        DHT11_DQ_OUT_1         HAL_GPIO_WritePin(DHT11_DIN_GPIO_Port, DHT11_DIN_Pin, GPIO_PIN_SET)
  10. #define        DHT11_DQ_OUT_0          HAL_GPIO_WritePin(DHT11_DIN_GPIO_Port, DHT11_DIN_Pin, GPIO_PIN_RESET)
  11. <font color="#008000">//读取GPIO电平</font>
  12. #define        DHT11_DQ_IN            HAL_GPIO_ReadPin(DHT11_DIN_GPIO_Port, DHT11_DIN_Pin)

  13. #define MEAN_NUM            10

  14. typedef struct
  15. {
  16.     uint8_t curI;
  17.     uint8_t thAmount;
  18.     uint8_t thBufs[10][2];
  19. }thTypedef_t;

  20. /* Function declaration */
  21. uint8_t dht11Init(void); //Init DHT11
  22. uint8_t dht11Read(uint8_t *temperature, uint8_t *humidity); //Read DHT11 Value
  23. static uint8_t dht11ReadData(uint8_t *temperature, uint8_t *humidity);
  24. static uint8_t dht11ReadByte(void);//Read One Byte
  25. static uint8_t dht11ReadBit(void);//Read One Bit
  26. static uint8_t dht11Check(void);//Chack DHT11
  27. static void dht11Rst(void);//Reset DHT11   
  28. void dht11SensorTest(void);

  29. #endif /*_HAL_HEMP_HUM_H*/
复制代码

Hal_temp_hum.c文件如下:
  1. /**
  2. ******************
  3. *
  4. * @file      Hal_temp_hum.c
  5. * @author    Gizwtis
  6. * @version   V03010100
  7. * @date      2016-07-05
  8. *
  9. * @brief     机智云.只为智能硬件而生
  10. *            Gizwits Smart Cloud  for Smart Products
  11. *            链接|增值ֵ|开放|中立|安全|自有|自由|生态
  12. *            www.gizwits.com
  13. *
  14. ******************/
  15. #include "hal_temp_hum.h"
  16. #include <string.h>

  17. thTypedef_t temphumTypedef;

  18. void delayUs(uint32_t nus)
  19. {
  20. uint8_t i=0;  
  21. while(nus--)
  22. {
  23.                 i=100;  <font color="#008000">//自己定义,需根据系统时钟调整</font>
  24.                 while(i--) ;   
  25. }
  26. }


  27. void DHT11_IO_OUT(void)
  28. {
  29.                 GPIO_InitTypeDef myGPIO_InitStruct;
  30.                 myGPIO_InitStruct.Pin = DHT11_DIN_Pin;
  31.                 myGPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  32.                 myGPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
  33.                 HAL_GPIO_Init(DHT11_DIN_GPIO_Port, &myGPIO_InitStruct);
  34. }

  35. void DHT11_IO_IN(void)
  36. {
  37.                 GPIO_InitTypeDef myGPIO_InitStruct;
  38.                 myGPIO_InitStruct.Pin = DHT11_DIN_Pin;
  39.           myGPIO_InitStruct.Pull = GPIO_PULLUP;
  40.                 myGPIO_InitStruct.Mode = GPIO_MODE_INPUT;
  41.                 myGPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
  42.                 HAL_GPIO_Init(DHT11_DIN_GPIO_Port, &myGPIO_InitStruct);
  43. }
  44. //Reset DHT11
  45. static void dht11Rst(void)
  46. {
  47.     DHT11_IO_OUT();                                     //SET OUTPUT
  48.     DHT11_DQ_OUT_0;                                     //GPIOA.0=0
  49.     HAL_Delay(20);                                        //Pull down Least 18ms
  50.     DHT11_DQ_OUT_1;                                     //GPIOA.0=1
  51.     delayUs(30);                                         //Pull up 20~40us
  52. }

  53. static uint8_t dht11Check(void)
  54. {
  55.     uint8_t retry=0;
  56.     DHT11_IO_IN();                                              //SET INPUT
  57.     while (DHT11_DQ_IN && (retry<100))                          //DHT11 Pull down 40~80us
  58.     {
  59.         retry++;
  60.         delayUs(1);
  61.     }

  62.     if(retry >= 100)
  63.     {
  64.         return 1;
  65.     }
  66.     else
  67.     {
  68.         retry=0;
  69.     }

  70.     while (!DHT11_DQ_IN&& (retry < 100))                    //DHT11 Pull up 40~80us
  71.     {
  72.         retry++;
  73.         delayUs(1);
  74.     }

  75.     if(retry >= 100)
  76.     {
  77.         return 1;                                //check error
  78.     }        

  79.     return 0;
  80. }

  81. static uint8_t dht11ReadBit(void)
  82. {
  83.     uint8_t retry=0;
  84.     while(DHT11_DQ_IN && (retry<100))                           //wait become Low level
  85.     {
  86.         retry++;
  87.         delayUs(1);
  88.     }

  89.     retry = 0;
  90.     while(!DHT11_DQ_IN && (retry < 100))                    //wait become High level
  91.     {
  92.         retry++;
  93.         delayUs(1);
  94.     }

  95.     delayUs(30);//wait 40us

  96.     if(DHT11_DQ_IN)
  97.     {
  98.         return 1;
  99.     }
  100.     else
  101.     {
  102.         return 0;
  103.     }
  104. }

  105. static uint8_t dht11ReadByte(void)
  106. {
  107.     uint8_t i,dat;
  108.     dat=0;
  109.     for (i=0; i<8; i++)
  110.     {
  111.         dat<<=1;
  112.         dat |= dht11ReadBit();
  113.     }

  114.     return dat;
  115. }

  116. static uint8_t dht11ReadData(uint8_t *temperature, uint8_t *humidity)
  117. {
  118.     uint8_t buf[5];
  119.     uint8_t i;
  120.     dht11Rst();
  121.     if(0 == dht11Check())
  122.     {
  123.         for(i=0; i<5; i++)
  124.         {
  125.             buf[i] = dht11ReadByte();
  126.         }
  127.         if(buf[4] == (buf[0]+buf[1]+buf[2]+buf[3]))
  128.         {
  129.             *humidity = buf[0];
  130.             *temperature = buf[2];
  131.         }
  132.     }
  133.     else
  134.     {
  135.         return 1;
  136.     }

  137.     return 0;
  138. }

  139. uint8_t dht11Read(uint8_t *temperature, uint8_t *humidity)
  140. {
  141.     uint8_t curTem = 0, curHum = 0;
  142.     uint16_t temMeans = 0, humMeans = 0;
  143.     uint8_t curI = 0;
  144.     uint8_t ret = 0;

  145.     ret = dht11ReadData(&curTem, &curHum);

  146.     if(1 != ret)
  147.     {
  148.         //Cycle store ten times stronghold
  149.         if(MEAN_NUM > temphumTypedef.curI)
  150.         {
  151.             temphumTypedef.thBufs[temphumTypedef.curI][0] = curTem;
  152.             temphumTypedef.thBufs[temphumTypedef.curI][1] = curHum;

  153.             temphumTypedef.curI++;
  154.         }
  155.         else
  156.         {
  157.             temphumTypedef.curI = 0;

  158.             temphumTypedef.thBufs[temphumTypedef.curI][0] = curTem;
  159.             temphumTypedef.thBufs[temphumTypedef.curI][1] = curHum;

  160.             temphumTypedef.curI++;
  161.         }
  162.     }
  163.     else
  164.     {
  165.         return (1);
  166.     }
  167.    
  168.     if(MEAN_NUM <= temphumTypedef.curI)
  169.     {
  170.         temphumTypedef.thAmount = MEAN_NUM;
  171.     }

  172.     if(0 == temphumTypedef.thAmount)
  173.     {
  174.         //Calculate Before ten the mean
  175.         for(curI = 0; curI < temphumTypedef.curI; curI++)
  176.         {
  177.             temMeans += temphumTypedef.thBufs[curI][0];
  178.             humMeans += temphumTypedef.thBufs[curI][1];
  179.         }

  180.         temMeans = temMeans / temphumTypedef.curI;
  181.         humMeans = humMeans / temphumTypedef.curI;
  182.         
  183.         *temperature = temMeans;
  184.         *humidity = humMeans;
  185.     }
  186.     else if(MEAN_NUM == temphumTypedef.thAmount)
  187.     {
  188.         //Calculate After ten times the mean
  189.         for(curI = 0; curI < temphumTypedef.thAmount; curI++)
  190.         {
  191.             temMeans += temphumTypedef.thBufs[curI][0];
  192.             humMeans += temphumTypedef.thBufs[curI][1];
  193.         }

  194.         temMeans = temMeans / temphumTypedef.thAmount;
  195.         humMeans = humMeans / temphumTypedef.thAmount;
  196.         
  197.         *temperature = (uint8_t)temMeans;
  198.         *humidity = (uint8_t)humMeans;
  199.     }

  200.     return (0);
  201. }

  202. uint8_t dht11Init(void)
  203. {
  204.         GPIO_InitTypeDef GPIO_InitStruct;
  205.     /* Migrate your driver code */
  206. __HAL_RCC_GPIOE_CLK_ENABLE();
  207.         /*Configure GPIO pin Output Level */
  208.   HAL_GPIO_WritePin(GPIOE, DHT11_DIN_Pin, GPIO_PIN_RESET);
  209.   /*Configure GPIO pins : PBPin PBPin PBPin */
  210.   GPIO_InitStruct.Pin = DHT11_DIN_Pin;
  211.   GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  212.   GPIO_InitStruct.Pull = GPIO_NOPULL;
  213.   GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
  214.   HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);
  215.     dht11Rst();
  216.    
  217.     memset((uint8_t *)&temphumTypedef, 0, sizeof(thTypedef_t));
  218.    
  219.     printf("dh11Init \r\n");
  220.    
  221.     return dht11Check();
  222. }
复制代码


本系列帖子目录:
http://club.gizwits.com/thread-6544-1-1.html

1、机智云QQ群:G1群:104975951 G2群:491509598 G3群:287087942
机智云爱好者-APP开发群: 599735135
QQ群目前非常活跃,欢迎大家参与进来,交流,讨论,答疑,解惑~~
2、机智云微信公众号: 机智云 gizwits、 机智云智能宠物屋go-iot
关注机智云Gizwits官方公众号随时掌握最新资讯和活动信息

5

主题

21

帖子

183

积分

注册会员

Rank: 2

积分
183
发表于 2017-5-23 15:53:37 | 显示全部楼层
有f103c8t6的温湿度驱动吗

点评

有啊。你查看我其他帖子  详情 回复 发表于 2017-5-23 18:38

321

主题

1054

帖子

4430

积分

论坛元老

Rank: 8Rank: 8

积分
4430
QQ
 楼主| 发表于 2017-5-23 18:38:53 | 显示全部楼层
zhin 发表于 2017-5-23 15:53
有f103c8t6的温湿度驱动吗

有啊。你查看我其他帖子
1、机智云QQ群:G1群:104975951 G2群:491509598 G3群:287087942
机智云爱好者-APP开发群: 599735135
QQ群目前非常活跃,欢迎大家参与进来,交流,讨论,答疑,解惑~~
2、机智云微信公众号: 机智云 gizwits、 机智云智能宠物屋go-iot
关注机智云Gizwits官方公众号随时掌握最新资讯和活动信息

0

主题

7

帖子

127

积分

注册会员

Rank: 2

积分
127
发表于 2019-3-15 17:13:24 | 显示全部楼层
大佬你好,有红外传感器驱动和MQ-2烟雾传感器吗?
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

加入Q群 返回顶部

© 2006-2022 Gizwits IoT Technology Co., Ltd. ( 粤ICP备11090211号 )

快速回复 返回顶部 返回列表