当前位置:   article > 正文

基于stm32单片机的DHT11温湿度模块使用_dht11模块

dht11模块

目录

一、DHT11模块介绍

目录

一、DHT11模块介绍

1、DHT11功能

2、DHT11数据传输

二、使用方法

1、时序介绍

2、数据包发送

3、代码实现


一、DHT11模块介绍

1、DHT11功能

对于温湿度模块来说,DHT11算是很经典的了,使用起来比较简单,但相对的功能上也没有那么强大。DHT11的湿度测量精度范围为20-90%RH(相对湿度),温度测量精度范围为0-50°C。但需要注意的是,DHT11的精度可能会受到环境因素的影响,如温度变化、湿度变化、气流等。因此,在使用DHT11进行测量时,应该尽量选择稳定的环境条件,以提高测量的准确度。

 

 DTH11有三个引脚的,也有四个引脚的,通常4个引脚的NC那个引脚也用不到,所以3个引脚的就够我们使用了。使用时把GND接地,VDD电源电压接高电平就行了,DATA则连上具体要用的单片机的GPIO口的引脚上。

2、DHT11数据传输

DHT11模块使用单线制数字信号串行通信。该通信协议称为DHT协议。在该协议中,DHT11模块只需要一根数据线就可以和主控设备进行通信。主控设备发送起始信号,DHT11响应并发送数据。每个数据包由40位二进制数据组成,其中包括16位湿度数据、16位温度数据和8位校验和。发送时序和接收时序都是非常重要的因素,对数据的准确性有很大影响。

二、使用方法

1、时序介绍

首先主机发送开始信号,即:拉低数据线,保持至少18ms时间t1,然后拉高数据线至少20~40us时间t2,然后读取DHT11的响应,正常的话,DHT11会拉低数据线,保持40~50us时间t3,作为响应信号,然后DHT11拉高数据线,保持40~50us时间t4后,开始输出数据。(如下图所示)

输出数据0,1的时序图如下:

DHT11会先拉低数据线12~14us时间,然后拉高数据线26~28us时间表示输出'0';在接着会重复的拉低数据线发送下一个bit,同样先拉低数据线至少12~14us时间,然后再拉高数据线至少116~118us的时间表示发送‘1’

2、数据包发送

通常发送40bit数据(5字节数据)来传送所检测到的温湿度数据。

数据格式:40bit数据=8位湿度整数+8位湿度小数+8位温度整数+8位温度小数+8位校验位;

例子:接收40位bit数据如下:

0000  0010      0000  0010          0000  0001    0000  0010          0000  0111

                湿度数据                                    温度数据                        校验和

 湿度高8位 + 湿度低8位 + 温度高8位 + 温度低8位  = 校验和

例如:0000 0001+0000 0010+0011 0001+0000 0010=0011 0110

二进制湿度数据0000  0010  0000 0010==>转化为十进制:514,除于10即为湿度值;

湿度=51.4%RH

二进制温度数据0000  0001  0000 0010==>转化为十进制:258,除于10即为湿度值;

温度=25.8℃

当温度低于0℃时温度数据的低八位最高位置1

例如:-34.1℃表示为 0010 0010 1000 0001

3、代码实现

 DHT11.c:

  1. #include "stm32f10x.h"
  2. #include "DHT11.h"
  3. void DHT11_IO_IN(void)//温湿度模块端口输入初始化
  4. {
  5. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
  6. RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);//端口复用
  7. GPIO_InitTypeDef GPIO_InitStructure;
  8. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
  9. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
  10. GPIO_Init(GPIOB, &GPIO_InitStructure);
  11. }
  12. void DHT11_IO_OUT(void)//温湿度模块端口输出初始化
  13. {
  14. GPIO_InitTypeDef GPIO_InitStructure;
  15. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
  16. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  17. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  18. GPIO_Init(GPIOB, &GPIO_InitStructure);
  19. }
  20. //复位DHT11
  21. void DHT11_Rst(void)
  22. {
  23. DHT11_IO_OUT(); //SET OUTPUT
  24. GPIO_ResetBits(GPIOB,GPIO_Pin_9)
  25. DelayXms(20); //拉低至少18ms
  26. GPIO_SetBits(GPIOB,GPIO_Pin_9);
  27. DelayUs(30); //主机拉高20~40us
  28. }
  29. //等待DHT11的回应
  30. //返回1:未检测到DHT11的存在
  31. //返回0:存在
  32. u8 DHT11_Check(void)
  33. {
  34. u8 retry = 0; //定义临时变量
  35. DHT11_IO_IN();//SET INPUT
  36. while ((GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_9) == 1) && retry < 100) //DHT11会拉低40~80us
  37. {
  38. retry++;
  39. DelayUs(1);
  40. };
  41. if(retry >= 100)return 1;
  42. else retry = 0;
  43. while ((GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_9) == 0) && retry < 100) //DHT11拉低后会再次拉高40~80us
  44. {
  45. retry++;
  46. DelayUs(1);
  47. };
  48. if(retry >= 100)return 1;
  49. return 0;
  50. }
  51. //从DHT11读取一个位
  52. //返回值:1/0
  53. u8 DHT11_Read_Bit(void)
  54. {
  55. u8 retry = 0;
  56. while((GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_9) == 1) && retry < 100) //等待变为低电平
  57. {
  58. retry++;
  59. DelayUs(1);
  60. }
  61. retry = 0;
  62. while((GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_9) == 0) && retry < 100) //等待变高电平
  63. {
  64. retry++;
  65. DelayUs(1);
  66. }
  67. DelayUs(40);//等待40us
  68. if(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_9) == 1)
  69. return 1;
  70. else
  71. return 0;
  72. }
  73. //从DHT11读取一个字节
  74. //返回值:读到的数据
  75. u8 DHT11_Read_Byte(void)
  76. {
  77. u8 i, dat;
  78. dat = 0;
  79. for (i = 0; i < 8; i++)
  80. {
  81. dat <<= 1;
  82. dat |= DHT11_Read_Bit();
  83. }
  84. return dat;
  85. }
  86. //从DHT11读取一次数据
  87. //temp:温度值(范围:0~50°)
  88. //humi:湿度值(范围:20%~90%)
  89. //返回值:0,正常;1,读取失败
  90. u8 DHT11_Read_Data(u8 *temp, u8 *humi)
  91. {
  92. u8 buf[5];
  93. u8 i;
  94. DHT11_Rst();
  95. if(DHT11_Check() == 0)
  96. {
  97. for(i = 0; i < 5; i++) //读取40位数据
  98. {
  99. buf[i] = DHT11_Read_Byte();
  100. }
  101. if((buf[0] + buf[1] + buf[2] + buf[3]) == buf[4])
  102. {
  103. *humi = buf[0];//小数部分不再计算
  104. *temp = buf[2];//小数部分不再计算
  105. }
  106. }
  107. else return 1;
  108. return 0;
  109. }
  110. //初始化DHT11的IO口 同时检测DHT11的存在
  111. //返回1:不存在
  112. //返回0:存在
  113. void DHT11_Init(void)
  114. {
  115. DHT11_Rst(); //复位DHT11
  116. DHT11_Check();//等待DHT11的回应
  117. }

 main.c:

  1. #include "delay.h"
  2. #include "sys.h"
  3. #include "oled.h"
  4. #include "bmp.h"//汉字库
  5. #include "DHT11.h"
  6. #include "usart.h"
  7. int main(void)
  8. {
  9. u8 wd=0;
  10. u8 sd=0;
  11. NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
  12. Delay_Init();
  13. uart_init(115200);
  14. DHT11_Init();
  15. OLED_Init();
  16. OLED_ColorTurn(0);//0正常显示,1 反色显示
  17. OLED_DisplayTurn(0);//0正常显示 1 屏幕翻转显示
  18. while(1)
  19. {
  20. DHT11_Read_Data(&wd,&sd);//读取温湿度值
  21. printf("当前环境温度: %d ℃\r\n",wd); //串口打印温湿度
  22. printf("当前环境湿度: %d %%\r\n",sd);
  23. OLED_ShowChinese(0,0,0,16,1); //温 x,y
  24. OLED_ShowChinese(18,0,1,16,1);//度
  25. OLED_ShowNum(50,0,wd,2,16,1); //显示温度值
  26. OLED_ShowString(36,0,":",16,1);
  27. OLED_ShowChinese(0,16,2,16,1);//湿
  28. OLED_ShowChinese(18,16,1,16,1);//度
  29. OLED_ShowNum(50,16,sd,2,16,1); //显示湿度值
  30. OLED_ShowString(36,16,":",16,1);
  31. OLED_ShowString(68,16,"%",16,1); //
  32. delay_ms(1000);
  33. OLED_Refresh();
  34. }
  35. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/AllinToyou/article/detail/606509
推荐阅读
相关标签
  

闽ICP备14008679号