文章目录
- 前言
- 一、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版本驱动函数的编写