欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

传感器学习——DHT11

程序员文章站 2022-04-18 08:26:18
...

DHT11简介

        DHT11 与单片机之间能采用简单的单总线进行通信,仅仅需要一个 I/O 口。
传感器内部湿度和温度数据 40Bit 的数据一次性传给单片机

      DHT11 的技术参数如下:

     工作电压范围: 3.3V-5.5V
 工作电流 :平均 0.5mA
 输出:单总线数字信号
 测量范围: 湿度 20~90%RH,温度 0~50℃
 精度 :湿度±5%,温度±2℃
 分辨率 :湿度 1%,温度 1℃


DHT11数据格式

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

                                 传感器学习——DHT11

         湿度= byte4 . byte3=45.0 (%RH)
         温度= byte2 . byte1=28.0 ( ℃)
         校验= byte4+ byte3+ byte2+ byte1=73(=湿度+温度)
DHT11发送顺序为从低位到高位,Byte是先湿度后温度,先整数后小数,最后校验和。


DHT11通信方式

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

                       传感器学习——DHT11

        DHT11发送的数据不是传统的“高电平就是1,低电平就是0”,而是在每发送一个bit前,拉低电平 12 ~14us。数据是体现在拉高电平时间的长短,拉高电平26 ~28us,就为0,拉高电平116 ~118us就为1。

                        传感器学习——DHT11

 

程序源码


dht11.c

#include "dht11.h"
#include "delay.h"

//复位 DHT11 
void DHT11_Rst(void)    
{                 
 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(void)     
{   
 u8 retry=0;
 DHT11_IO_IN();//SET INPUT  
    while (DHT11_DQ_IN&&retry<100)//DHT11 会拉低 40~80us 
 {
  retry++;
  delay_us(1);
 };  
  if(retry>=100)return 1;
 else retry=0;
    while (!DHT11_DQ_IN&&retry<100))//DHT11 拉低后会再次拉高 40~80us 
 {
  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)//等待变为低电平 
 {
  retry++;
  delay_us(1);
 }
 retry=0;
  while(!DHT11_DQ_IN&&retry<100)//等待变高电平 
 {
  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 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 口 DQ 同时检测 DHT11 的存在 //返回 1:不存在 //返回 0:存在      
 u8 DHT11_Init(void) 
{
 GPIO_InitTypeDef  GPIO_InitStructure;

RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOG, ENABLE);//使能 GPIOG 时钟 
 //GPIOF9,F10 初始化设置   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 ;   GPIO_InitStructure.GPIO_Mode =GPIO_Mode_OUT;//普通输出模式 
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//推挽输出   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//50MHz   GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉 
GPIO_Init(GPIOG, &GPIO_InitStructure);//初始化 DHT11_Rst();
return DHT11_Check(); 
}

dht11.h

#ifndef __DHT11_H
#define __DHT11_H 
#include "sys.h"   


//IO方向设置
#define DHT11_IO_IN()  {GPIOG->MODER&=~(3<<(9*2));GPIOG->MODER|=0<<9*2;} //PG9输入模式
#define DHT11_IO_OUT() {GPIOG->MODER&=~(3<<(9*2));GPIOG->MODER|=1<<9*2;}  //PG9输出模式
////IO操作函数
#define DHT11_DQ_OUT PGout(9) //数据端口 PG9 
#define DHT11_DQ_IN  PGin(9)  //数据端口 PG9 
u8 DHT11_Init(void);//初始化DHT11
u8 DHT11_Read_Data(u8 *temp,u8 *humi);//读取温湿度
u8 DHT11_Read_Byte(void);//读出一个字节
u8 DHT11_Read_Bit(void);//读出一个位
u8 DHT11_Check(void);//检测是否存在DHT11
void DHT11_Rst(void);//复位DHT11    
#endif


————————————————
版权声明:本文为CSDN博主「互相学习3」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_46156693/article/details/104460599

https://blog.csdn.net/weixin_46156693/article/details/104460599

相关标签: 传感器