资讯详情

基于STM32的DHT11温湿度传感器设计

文章目录

  • 前言
  • 一、DHT什么是温湿度传感器
  • 二、DHT详解11驱动程序
    • 1.相关宏定义
    • 2.输入输出GPIO配置
    • 2.GPIO初始化设计
    • 3.检测DHT11工作是否正常
    • 4.读取DHT11数据
    • 5.显示温湿度数据
  • 三、DHT11驱动源码
  • 总结


前言

DHT11作为一种低成本、入门级的温湿度传感器,常用于我们的单片机设计实例;采用特殊的数字模块采集技术和温湿度传感技术,确保产品具有高可靠性和优异的长期稳定性。传感器包括电阻湿度感应元件和NTC与高性能8位单片机连接的测温元件。 DHT11为 4 针单排引脚包装,如下图所示,采用单线串行接口,只需添加适当的上拉电阻,信号传输距离可达20米以上,成为各种应用甚至最苛刻的应用场合的最佳选择。

在这里插入图片描述


一、DHT什么是温湿度传感器?

详见:物联网外设学习笔记-数字温湿度传感器

二、DHT详解11驱动程序

1.相关宏定义

由上可知DHT11温湿度传感器接入STM32,GPIOG,如下图所示,11引脚。

2.输入输出GPIO配置

代码如下

2.GPIO初始化设计

总线,主机拉下总线等待DHT11响应时,主机必须拉低总线18m秒以上,以确保DHT起始信号可以检测到。DHT11收到主机的开始信号后,等待主机开始信号结束,然后发送80us低电平响应信号.主机发送开始信号后,,读取DHT11响应信号,主机发送开始信号后,可切换到输入模式,或平均输出高电, 。 代码如下

3.检测DHT11工作是否正常

检查DHT11是否正常,单片机发送启动信号后,传感器返回80us低电平,然后发送80us高电平。即证明DHT11工作正常,函数工作正常返回0,否则返回1,在函数中使用while循环检测在一定时间内的电平变化,以后经常使用。

4.读取DHT11数据

  • 8bit湿度数据 8bit湿度小数据 8bi温度整数据 8bit温度小数据 8bit校验和
  • 读取数据并将数据存储在数组中,这里只保留温度数据的整数位,注意数据比较方法,验证和数据等于最后八个结果。

5.显示温湿度数据

三、DHT11驱动源码

#ifndef _dht11_H #define _dht11_H  #include "system.h" #include "SysTick.h"   #define DHT11 (GPIO_Pin_11) //PG11 #define GPIO_DHT11 GPIOG  #define DHT11_DQ_IN PGin(11) //输入 #define DHT11_DQ_OUT PGout(11) //输出  void DHT11_IO_OUT(void); void DHT11_IO_IN(void); u8 DHT11_Init(void); void DHT11_Rst(void); u8 DHT11_Check(void); u8 DHT11_Read_Bit(void); u8 DHT11_Read_Byte(void);
u8 DHT11_Read_Data(u8 *temp,u8 *humi);


#endif

#include "dht11.h"


//DHT11初始化
//返回0:初始化成功,1:失败
u8 DHT11_Init()
{ 
        
    GPIO_InitTypeDef GPIO_InitStructure;

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOG,ENABLE);

    GPIO_InitStructure.GPIO_Pin=DHT11;
    GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
    GPIO_Init(GPIO_DHT11,&GPIO_InitStructure);
	
    GPIO_SetBits(GPIO_DHT11,DHT11);	   //拉高

    DHT11_Rst();
    return DHT11_Check();
}

//复位DHT11
void DHT11_Rst()
{ 
        
    DHT11_IO_OUT(); 	//SET OUTPUT
    DHT11_DQ_OUT=0; 	//拉低DQ
    delay_ms(20);    	//拉低至少18ms
    DHT11_DQ_OUT=1; 	//DQ=1
    delay_us(30);     	//主机拉高20~40us
}

//等待DHT11的回应
//返回1:未检测到DHT11的存在
//返回0:存在
u8 DHT11_Check()
{ 
        
    u8 retry=0;
    DHT11_IO_IN();//SET INPUT
    while (DHT11_DQ_IN&&retry<100)//DHT11会拉低40~50us
    { 
        
        retry++;
        delay_us(1);
    };
    if(retry>=100)return 1;
    else retry=0;
    while (!DHT11_DQ_IN&&retry<100)//DHT11拉低后会再次拉高40~50us
    { 
        
        retry++;
        delay_us(1);
    };
    if(retry>=100)return 1;
    return 0;
}

//从DHT11读取一个位
//返回值:1/0
u8 DHT11_Read_Bit(void)
{ 
        
    u8 retry=0;
    while(DHT11_DQ_IN&&retry<100)//等待变为低电平 12-14us 开始
    { 
        
        retry++;
        delay_us(1);
    }
    retry=0;
    while(!DHT11_DQ_IN&&retry<100)//等待变高电平 26-28us表示0,116-118us表示1
    { 
        
        retry++;
        delay_us(1);
    }
    delay_us(40);//等待40us
    if(DHT11_DQ_IN)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输出模式配置
void DHT11_IO_OUT()
{ 
        
    GPIO_InitTypeDef GPIO_InitStructure;
    GPIO_InitStructure.GPIO_Pin=DHT11;
    GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;	 //推挽输出
    GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
    GPIO_Init(GPIO_DHT11,&GPIO_InitStructure);
}

//DHT11输入模式配置
void DHT11_IO_IN()
{ 
        
    GPIO_InitTypeDef GPIO_InitStructure;
    GPIO_InitStructure.GPIO_Pin=DHT11;
    GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU;	 //上拉输入模式
    GPIO_Init(GPIO_DHT11,&GPIO_InitStructure);
}

#include "system.h"
#include "SysTick.h"
#include "led.h"
#include "usart.h"
#include "tftlcd.h"
#include "dht11.h"


void data_pros()	//数据处理函数
{ 
        
	u8 temp;  	    
	u8 humi;
	u8 temp_buf[3],humi_buf[3];
	DHT11_Read_Data(&temp,&humi);
	temp_buf[0]=temp/10+0x30;	
	temp_buf[1]=temp%10+0x30;
	temp_buf[2]='\0';
	LCD_ShowString(80,100,tftlcd_data.width,tftlcd_data.height,16,temp_buf);
		
	humi_buf[0]=humi/10+0x30;	
	humi_buf[1]=humi%10+0x30;
	humi_buf[2]='\0';
	LCD_ShowString(80,130,tftlcd_data.width,tftlcd_data.height,16,humi_buf);		
}

int main()
{ 
        
	u8 i=0;
	SysTick_Init(72);
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);  //中断优先级分组 分2组
	LED_Init();
// USART1_Init(9600);
	TFTLCD_Init();			//LCD初始化
	
	LCD_Printf("Temp: C",10,100,24,2,WHITE,BLACK);
	LCD_Printf("Humi: %RH",10,130,24,2,WHITE,BLACK);	
	while(DHT11_Init())	//检测DHT11是否纯在
	{ 
        
		LCD_Printf("DHT11 Init Error",30,50,24,2,WHITE,BLACK);
		delay_ms(500);		
	}
	LCD_Printf("DHT11 Init Success",30,50,24,2,WHITE,BLACK);
	
	while(1)
	{ 
        
		
		i++;
		if(i%20==0)
		{ 
        
			led1=!led1;
			data_pros();  	 //读取一次DHT11数据最少要大于100ms
		}
		delay_ms(10);
			
	}
}


总结

以上就是今天要讲的内容,本文仅仅简单介绍了DHT11温湿度传感器,及STM32版本驱动函数的编写

标签: 推挽式传感器纯数字式传感器

锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

锐单商城 - 一站式电子元器件采购平台