传感器学习——DHT11

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)时间后,开始输出数据。

                                 在这里插入图片描述

         湿度= 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发送的数据不是传统的“高电平就是1,低电平就是0”,而是在每发送一个bit前,拉低电平 12 ~14us。数据是体现在拉高电平时间的长短,拉高电平26 ~28us,就为0,拉高电平116 ~118us就为1。

                        在这里插入图片描述

 

程序源码


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

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值