赞
踩
目录
目录
对于温湿度模块来说,DHT11算是很经典的了,使用起来比较简单,但相对的功能上也没有那么强大。DHT11的湿度测量精度范围为20-90%RH(相对湿度),温度测量精度范围为0-50°C。但需要注意的是,DHT11的精度可能会受到环境因素的影响,如温度变化、湿度变化、气流等。因此,在使用DHT11进行测量时,应该尽量选择稳定的环境条件,以提高测量的准确度。
DTH11有三个引脚的,也有四个引脚的,通常4个引脚的NC那个引脚也用不到,所以3个引脚的就够我们使用了。使用时把GND接地,VDD电源电压接高电平就行了,DATA则连上具体要用的单片机的GPIO口的引脚上。
DHT11模块使用单线制数字信号串行通信。该通信协议称为DHT协议。在该协议中,DHT11模块只需要一根数据线就可以和主控设备进行通信。主控设备发送起始信号,DHT11响应并发送数据。每个数据包由40位二进制数据组成,其中包括16位湿度数据、16位温度数据和8位校验和。发送时序和接收时序都是非常重要的因素,对数据的准确性有很大影响。
首先主机发送开始信号,即:拉低数据线,保持至少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’
通常发送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
DHT11.c:
- #include "stm32f10x.h"
- #include "DHT11.h"
-
- void DHT11_IO_IN(void)//温湿度模块端口输入初始化
- {
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);//端口复用
-
- GPIO_InitTypeDef GPIO_InitStructure;
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
- GPIO_Init(GPIOB, &GPIO_InitStructure);
- }
-
- void DHT11_IO_OUT(void)//温湿度模块端口输出初始化
- {
- GPIO_InitTypeDef GPIO_InitStructure;
-
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
- GPIO_Init(GPIOB, &GPIO_InitStructure);
- }
-
- //复位DHT11
- void DHT11_Rst(void)
- {
- DHT11_IO_OUT(); //SET OUTPUT
- GPIO_ResetBits(GPIOB,GPIO_Pin_9)
- DelayXms(20); //拉低至少18ms
- GPIO_SetBits(GPIOB,GPIO_Pin_9);
- DelayUs(30); //主机拉高20~40us
- }
-
- //等待DHT11的回应
- //返回1:未检测到DHT11的存在
- //返回0:存在
- u8 DHT11_Check(void)
- {
- u8 retry = 0; //定义临时变量
- DHT11_IO_IN();//SET INPUT
- while ((GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_9) == 1) && retry < 100) //DHT11会拉低40~80us
- {
- retry++;
- DelayUs(1);
- };
- if(retry >= 100)return 1;
- else retry = 0;
- while ((GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_9) == 0) && retry < 100) //DHT11拉低后会再次拉高40~80us
- {
- retry++;
- DelayUs(1);
- };
- if(retry >= 100)return 1;
- return 0;
- }
- //从DHT11读取一个位
- //返回值:1/0
- u8 DHT11_Read_Bit(void)
- {
- u8 retry = 0;
- while((GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_9) == 1) && retry < 100) //等待变为低电平
- {
- retry++;
- DelayUs(1);
- }
- retry = 0;
- while((GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_9) == 0) && retry < 100) //等待变高电平
- {
- retry++;
- DelayUs(1);
- }
- DelayUs(40);//等待40us
- if(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_9) == 1)
- return 1;
- else
- return 0;
- }
- //从DHT11读取一个字节
- //返回值:读到的数据
- u8 DHT11_Read_Byte(void)
- {
- u8 i, dat;
- dat = 0;
- for (i = 0; i < 8; i++)
- {
- dat <<= 1;
- dat |= DHT11_Read_Bit();
- }
- return dat;
- }
-
- //从DHT11读取一次数据
- //temp:温度值(范围:0~50°)
- //humi:湿度值(范围:20%~90%)
- //返回值:0,正常;1,读取失败
- u8 DHT11_Read_Data(u8 *temp, u8 *humi)
- {
- u8 buf[5];
- u8 i;
- DHT11_Rst();
- if(DHT11_Check() == 0)
- {
- for(i = 0; i < 5; i++) //读取40位数据
- {
- buf[i] = DHT11_Read_Byte();
- }
- if((buf[0] + buf[1] + buf[2] + buf[3]) == buf[4])
- {
- *humi = buf[0];//小数部分不再计算
- *temp = buf[2];//小数部分不再计算
- }
- }
- else return 1;
- return 0;
- }
- //初始化DHT11的IO口 同时检测DHT11的存在
- //返回1:不存在
- //返回0:存在
- void DHT11_Init(void)
- {
- DHT11_Rst(); //复位DHT11
- DHT11_Check();//等待DHT11的回应
- }
main.c:
- #include "delay.h"
- #include "sys.h"
- #include "oled.h"
- #include "bmp.h"//汉字库
- #include "DHT11.h"
- #include "usart.h"
-
- int main(void)
- {
-
- u8 wd=0;
- u8 sd=0;
-
- NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
- Delay_Init();
- uart_init(115200);
-
- DHT11_Init();
-
- OLED_Init();
- OLED_ColorTurn(0);//0正常显示,1 反色显示
- OLED_DisplayTurn(0);//0正常显示 1 屏幕翻转显示
- while(1)
- {
-
- DHT11_Read_Data(&wd,&sd);//读取温湿度值
-
-
- printf("当前环境温度: %d ℃\r\n",wd); //串口打印温湿度
- printf("当前环境湿度: %d %%\r\n",sd);
-
-
- OLED_ShowChinese(0,0,0,16,1); //温 x,y
- OLED_ShowChinese(18,0,1,16,1);//度
- OLED_ShowNum(50,0,wd,2,16,1); //显示温度值
- OLED_ShowString(36,0,":",16,1);
-
- OLED_ShowChinese(0,16,2,16,1);//湿
- OLED_ShowChinese(18,16,1,16,1);//度
- OLED_ShowNum(50,16,sd,2,16,1); //显示湿度值
- OLED_ShowString(36,16,":",16,1);
- OLED_ShowString(68,16,"%",16,1); //
- delay_ms(1000);
-
- OLED_Refresh();
-
- }
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。