3回答

0收藏

[分享] GD32F207读DHT11传感器的温湿度值

GD32 GD32 5089 人阅读 | 3 人回复 | 2016-02-04

本帖最后由 党国特派员 于 2016-2-5 00:25 编辑

1、DHT11介绍
DHT11是一款比较便宜的温湿度传感器模块。读取数据只需要占用一个IO口。能够同时测量温度和相对湿度。
2、接口说明
建议连接线长度短于20米时用5K上拉电阻,大于20米时根据实际情况使用合适的上拉电阻

3、电源引脚
DHT11的供电电压为 3-5.5V。传感器上电后,要等待 1s 以越过不稳定状态在此期间无需发送任何指令。电源引脚(VDD,GND)之间可增加一个100nF 的电容,用以去耦滤波。
4、串行接口(单纯双向)
DATA 用于微处理器与 DHT11之间的通讯和同步,采用单总线数据格式,一次通讯时间4ms左右,数据分小数部分和整数部分,具体格式在下面说明,当前小数部分用于以后扩展,现读出为零.操作流程如下:
一次完整的数据传输为40bit,高位先出。
数据格式:8bit湿度整数数据+8bit湿度小数数据
+8bi温度整数数据+8bit温度小数数据
         +8bit校验和
数据传送正确时校验和数据等于8bit湿度整数数据+8bit湿度小数数据+8bi温度整数数据+8bit温度小数数据所得结果的末8位。
用户MCU发送一次开始信号后,DHT11从低功耗模式转换到高速模式,等待主机开始信号结束后,DHT11发送响应信号,送出40bit的数据,并触发一次信号采集,用户可选择读取部分数据.从模式下,DHT11接收到开始信号触发一次温湿度采集,如果没有接收到主机发送开始信号,DHT11不会主动进行温湿度采集.采集数据后转换到低速模式。
5、驱动代码
dht11.h
  1. /**
  2. ****************************************************************************************
  3. *
  4. * @file dht11.h
  5. *
  6. * @brief dht11传感器操作模块头文件
  7. *
  8. * Copyright (C) sunsjw 2015
  9. *
  10. * $Rev: 1.0 $
  11. *
  12. ****************************************************************************************
  13. */
  14. #ifndef __DHT11_H
  15. #define __DHT11_H

  16. #include <stdint.h>
  17. //IO操作函数        


  18. #define PBout(n) BITBAND_REG(PTB->PDOR,n)
  19. #define PBin(n) BITBAND_REG(PTB->PDIR,n)

  20. #define        DHT11_DQ_OUT PBout(0) //数据端口        PB0
  21. #define        DHT11_DQ_IN  GPIO_ReadInputBit(GPIOC,GPIO_PIN_0)  //数据端口        PB0

  22. #define DHT11_SETOUT    GPIOC->CTLR1 = (GPIOC->CTLR1 & 0xFFFFFFF0 | 0x01)
  23. #define DHT11_SETIN     GPIOC->CTLR1 = (GPIOC->CTLR1 & 0xFFFFFFF0 | 0x08)

  24. #define DHT11_HIGH      GPIO_SetBits(GPIOC,GPIO_PIN_0)
  25. #define DHT11_LOW       GPIO_ResetBits(GPIOC,GPIO_PIN_0)

  26. void DHT11_Init(void);               //初始化DHT11
  27. uint16_t DHT11_Read_Data(void);        //读取温湿度
  28. uint8_t DHT11_Read_Byte(void);  //读出一个字节
  29. uint8_t DHT11_Read_Bit(void);   //读出一个位
  30. uint8_t DHT11_Check(void);      //检测是否存在DHT11
  31. void DHT11_Rst(void);           //复位DHT11  


  32. #endif
复制代码
dht11.c
  1. /**
  2. ****************************************************************************************
  3. *
  4. * @file dht11.c
  5. *
  6. * @brief dht11传感器操作模块文件
  7. *
  8. * Copyright (C) sunsjw 2015
  9. *
  10. * $Rev: 1.0 $
  11. *
  12. ****************************************************************************************
  13. */
  14. #include "gd32f20x_gpio.h"              // Keil::Device:StdPeriph Drivers:GPIO

  15. #include "dht11.h"
  16. #include "delay.h"

  17. /*!
  18. * @brief 复位DHT11
  19. *
  20. * @param None
  21. *
  22. * @return None
  23. */
  24. void DHT11_Rst(void)
  25. {
  26.     DHT11_SETOUT;
  27.         DelayUs(1);
  28.     DHT11_LOW;             //拉低DQ
  29.     DelayMs(20);    //拉低至少18ms
  30.     DHT11_HIGH;         //DQ=1
  31.     DelayUs(30);    //主机拉高20~40us        
  32. }

  33. /*!
  34. * @brief 等待DHT11的回应
  35. *
  36. * @param None
  37. *
  38. * @return 0:未检测到DHT11的存在,(低电平80us,高电平80us),1:存在
  39. */
  40. uint8_t DHT11_Check(void)
  41. {
  42.     uint8_t retry=0;
  43.     DHT11_SETIN;
  44.     //DHT11_IO_IN();//SET INPUT
  45.     while (DHT11_DQ_IN&&retry<100)//DHT11会拉低40~80us
  46.     {
  47.         retry++;
  48.         DelayUs(1);
  49.     };
  50.     if(retry>=100)
  51.       return 0;
  52.     else
  53.       retry=0;
  54.     while (!DHT11_DQ_IN&&retry<100)//DHT11拉低后会再次拉高40~80us
  55.     {
  56.         retry++;
  57.         DelayUs(1);
  58.     };
  59.     if(retry>=100)
  60.       return 0;
  61.     return 1;
  62. }

  63. /*!
  64. * @brief 从DHT11读取一个位 (起始位50us低电平,26-28us高电平代表0,70us高电平代表1)
  65. *
  66. * @param None
  67. *
  68. * @return 1/0
  69. */
  70. uint8_t DHT11_Read_Bit(void)
  71. {
  72.     uint8_t retry=0;
  73.     while(DHT11_DQ_IN&&retry<100)//等待变为低电平
  74.     {
  75.         retry++;
  76.         DelayUs(1);
  77.     }
  78.     retry=0;
  79.     while(!DHT11_DQ_IN&&retry<100)//等待变高电平
  80.     {
  81.         retry++;
  82.         DelayUs(1);
  83.     }

  84.     DelayUs(35);//等待40us
  85.     if(DHT11_DQ_IN)
  86.       return 1;
  87.     else
  88.       return 0;
  89. }

  90. /*!
  91. * @brief 从DHT11读取一个字节
  92. *
  93. * @param None
  94. *
  95. * @return 读到的数据
  96. */
  97. uint8_t DHT11_Read_Byte(void)
  98. {
  99.     uint8_t i,dat;
  100.     DHT11_SETIN;
  101.     dat=0;
  102.     for (i=0; i<8; i++)
  103.     {
  104.         dat<<=1;
  105.         dat|=DHT11_Read_Bit();
  106.     }
  107.     return dat;
  108. }

  109. /*!
  110. * @brief 从DHT11读取一次数据
  111. *
  112. * @param None
  113. * @param[in,out] temp:温度值(范围:0~50°),humi:湿度值(范围:20%~90%)
  114. * @return 0:读取失败,非0值:高8位是温度值,低8位是湿度值
  115. */
  116. uint16_t DHT11_Read_Data()
  117. {
  118.     uint8_t buf[5];
  119.         uint16_t result;
  120.     uint8_t i;
  121.     DHT11_Rst();
  122.     if(DHT11_Check())
  123.     {
  124.         for(i=0; i<5; i++) //读取40位数据
  125.         {
  126.             buf[i]=DHT11_Read_Byte();
  127.         }
  128.         if((buf[0]+buf[1]+buf[2]+buf[3])==buf[4])
  129.         {
  130.                         result = buf[2];
  131.                         result <<= 8;
  132.             result |= buf[0];
  133.         }
  134.     }
  135.     else
  136.       return 0;
  137.     return result;
  138. }

  139. /*!
  140. * @brief 初始化DHT11的IO口 DQ 同时检测DHT11的存在
  141. *
  142. * @param None
  143. *
  144. * @return None
  145. */
  146. void DHT11_Init(void)
  147. {
  148.         GPIO_InitPara gpio_stru;
  149.         /*初始化DHT11使用的GPIO*/
  150.         gpio_stru.GPIO_Mode = GPIO_MODE_OUT_PP;
  151.         gpio_stru.GPIO_Pin = GPIO_PIN_0;
  152.         gpio_stru.GPIO_Speed = GPIO_SPEED_10MHZ;
  153.         
  154.         GPIO_Init(GPIOC,&gpio_stru);
  155.         GPIO_SetBits(GPIOC,GPIO_PIN_0);
  156.         
  157. }







复制代码
主程序main.c
  1. #include <stdio.h>
  2. #include "gd32f20x.h"                   // Device header
  3. #include "cmsis_os.h"                   // ARM::CMSIS:RTOS:Keil RTX

  4. #include "delay.h"
  5. #include "dht11.h"
  6. #include "oled.h"


  7. uint8_t showBuffer[32];

  8. void RCC_config(void);
  9. void GPIO_config(void);
  10. void SPI_config(void);


  11. void ShowDHT11(void);


  12. void thread_led(const void *arg)
  13. {
  14.         uint16_t pin = (uint16_t)arg;
  15.         for(;;)
  16.         {
  17.                 if(GPIO_ReadOutputBit(GPIOD,pin))
  18.                         GPIO_ResetBits(GPIOD,pin);
  19.                 else
  20.                         GPIO_SetBits(GPIOD,pin);
  21.                
  22.                 osDelay(pin);
  23.         }
  24. }



  25. void task_dht11(const void* arg)
  26. {
  27.         for(;;)
  28.         {
  29.                 ShowDHT11();
  30.                 osDelay(1000);
  31.         }
  32. }

  33. osThreadDef(thread_led,osPriorityNormal,3,0);
  34. osThreadDef(task_dht11,osPriorityHigh,1,0);


  35. int main()
  36. {   
  37.         osKernelInitialize();
  38.         
  39.         RCC_config();
  40.         GPIO_config();
  41.         SPI_config();

  42.         
  43.         DelayInit();
  44.         DHT11_Init();
  45.         OLED_Init();
  46.         OLED_Clear();
  47.         GP2Y_init();
  48.         
  49.         osThreadCreate(osThread(thread_led),(void*)GPIO_PIN_11);
  50.         
  51.         osThreadCreate(osThread(task_dht11),NULL);
  52.         
  53.         osKernelStart();
  54.         while(1)
  55.         {
  56.                 osDelay(1000);
  57.         }
  58. }

  59. void RCC_config(void)
  60. {
  61.     RCC_APB2PeriphClock_Enable(RCC_APB2PERIPH_GPIOA|RCC_APB2PERIPH_GPIOD|RCC_APB2PERIPH_GPIOC,ENABLE);

  62.         RCC_APB2PeriphClock_Enable(RCC_APB2PERIPH_SPI1,ENABLE);
  63.         RCC_APB2PeriphClock_Enable(RCC_APB2PERIPH_ADC1,ENABLE);
  64.         
  65.         RCC_APB1PeriphClock_Enable(RCC_APB1PERIPH_USART2,ENABLE);
  66.         RCC_APB1PeriphClock_Enable(RCC_APB1PERIPH_TIMER6,ENABLE);
  67.         RCC_ADCCLKConfig(RCC_ADCCLK_APB2_DIV6);
  68. }

  69. void GPIO_config(void)
  70. {
  71.         /*初始化LED灯的GPIO*/
  72.         GPIO_InitPara gpio_stru;
  73.         gpio_stru.GPIO_Mode = GPIO_MODE_OUT_PP;
  74.         gpio_stru.GPIO_Speed = GPIO_SPEED_10MHZ;
  75.         gpio_stru.GPIO_Pin = GPIO_PIN_11|GPIO_PIN_12|GPIO_PIN_13;
  76.         
  77.         GPIO_Init(GPIOD,&gpio_stru);
  78. }


  79. void SPI_config(void)
  80. {
  81.         SPI_InitPara spi_stru;
  82.         
  83.         spi_stru.SPI_FirstBit = SPI_FIRSTBIT_MSB;
  84.         spi_stru.SPI_FrameFormat =  SPI_FRAMEFORMAT_8BIT;
  85.         spi_stru.SPI_Mode = SPI_MODE_MASTER;
  86.         spi_stru.SPI_PSC = SPI_PSC_64;
  87.         spi_stru.SPI_SCKPH = SPI_SCKPH_1EDGE;
  88.         spi_stru.SPI_SCKPL = SPI_SCKPL_LOW;
  89.         spi_stru.SPI_SWNSSEN = SPI_SWNSS_SOFT;
  90.         spi_stru.SPI_TransType = SPI_TRANSTYPE_BDMTX;
  91.         spi_stru.SPI_CRCPOL = 7;
  92.         
  93.         SPI_Init(SPI1,&spi_stru);
  94.         SPI_CRC_Enable(SPI1,DISABLE);
  95.         SPI_Enable(SPI1,ENABLE);
  96. }


  97. void ShowDHT11(void)
  98. {
  99.         uint16_t data = DHT11_Read_Data();

  100.         sprintf((char*)showBuffer,":%3d",data>>8);
  101.         OLED_ShowCHinese(0,2,6);//显示汉字温
  102.         OLED_ShowCHinese(16,2,8);//显示汉字度
  103.         OLED_ShowString(32,2,showBuffer);
  104.         OLED_ShowCHinese(64,2,9);//显示℃

  105.         sprintf((char*)showBuffer,":%3d",data & 0xFF);
  106.         OLED_ShowCHinese(0,4,7);//显示汉字温
  107.         OLED_ShowCHinese(16,4,8);//显示汉字度
  108.         OLED_ShowString(32,4,showBuffer);
  109.         OLED_ShowCHinese(64,4,11);//显示%
  110. }
复制代码
实验效果:




喜欢在构思妙想,电子产品DIY是工作,也是一种爱好。
分享到:
回复

使用道具 举报

回答|共 3 个

倒序浏览

沙发

糖悦之果飞

发表于 2016-2-16 13:59:10 | 只看该作者

亲,可以将内容一并发到经验频道,很有机会获得每月之星的呢http://jingyan.eeboard.com/
板凳

党国特派员

发表于 2016-2-17 10:12:22 | 只看该作者

糖悦之果飞 发表于 2016-2-16 13:59
亲,可以将内容一并发到经验频道,很有机会获得每月之星的呢http://jingyan.eeboard.com/ ...

我申请了四篇,才通过一篇呢?
喜欢在构思妙想,电子产品DIY是工作,也是一种爱好。
地板

糖悦之果飞

发表于 2016-2-17 16:12:23 | 只看该作者

党国特派员 发表于 2016-2-17 10:12
我申请了四篇,才通过一篇呢?

都通过了的呢,工程师比较慢,有时候审核比较慢些,请谅解
您需要登录后才可以回帖 注册/登录

本版积分规则

关闭

站长推荐上一条 /3 下一条