DHT11温湿度传感器开发

单总线说明

  DHT11 器件采用简化的单总线通信。单总线即只有一根数据线,系统中的数据交换、控制均由单总线完成。设备(主机或从机)通过一个漏枀开路或三态端口连至该数据线,以允许设备在不发送数据时能够释放总线,而让其它设备使用总线;单总线通常要求外接一个约 5.1kΩ 的上拉电阻,这样,当总线闲置时,其状态为高电平。由于它们是主从结极,只有主机呼叫从机时,从机才能应答,因此主机访问器件都必须严格遵循单总线序列,如果出现序列混乱,器件将不响应主机。

单总线传送数据位定义

DATA引脚用于微处理器与 DHT11 之间的通讯和同步,采用单总线数据格式,一次传送 40 位数据,高位先出。

数据格式

8bit 湿度整数数据 + 8bit 湿度小数数据+8bit 温度整数数据 + 8bit 温度小数数据+8bit 校验位。 注:其中温湿度小数部分为 0。

校验位数据定义 “8bit 湿度整数数据 + 8bit 湿度小数数据+8bit 温度整数数据 + 8bit 温度小数数据”8bit 校验位等于所 得结果的末 8 位。
在这里插入图片描述

数据时序图

用户主机(MCU)发送一次开始信号后,DHT11 从低功耗模式转换到高速模式,待主机开始信号结束 后,DHT11 发送响应信号,送出 40bit 的数据,并触发一次信采集。信号发送如图所示。

外设读取步骤

主机和从机之间的通信可通过如下几个步骤完成(外设(如微处理器)读取 DHT11 的数据的步骤)。

步骤一:

DHT11 上电后(DHT11 上电后要等待 1S 以越过不稳定状态在此期间不能发送任何指令),测试环境 温湿度数据,并记录数据,同时 DHT11 的 DATA 数据线由上拉电阻拉高一直保持高电平;此时 DHT11 的 DATA 引脚处于输入状态,时刻检测外部信号。

步骤二:

微处理器的 I/O 设置为输出同时输出低电平,且低电平保持时间不能小于 18ms,然后微处理器的 I/O 设置为输入状态,由于上拉电阻,微处理器的 I/O 即 DHT11 的 DATA 数据线也随之变高,等待 DHT11 作 出回答信号,发送信号如图所示:
在这里插入图片描述

步骤三:

DHT11 的 DATA 引脚检测到外部信号有低电平时,等待外部信号低电平结束,延迟后 DHT11 的 DATA 引脚处于输出状态,输出 80 微秒的低电平作为应答信号,紧接着输出 80 微秒的高电平通知外设准备接 收数据,微处理器的 I/O 此时处于输入状态,检测到 I/O 有低电平(DHT11 回应信号)后,等待 80 微秒 的高电平后的数据接收,发送信号如图所示:
在这里插入图片描述

步骤四:

由 DHT11 的 DATA 引脚输出 40 位数据,微处理器根据 I/O 电平的变化接收 40 位数据,位数据“0” 的格式为: 50 微秒的低电平和 26-28 微秒的高电平,位数据“1”的格式为: 50 微秒的低电平加 70 微秒的高电平。位数据“0”、“1”格式信号如图所示:
在这里插入图片描述

结束信号:

DHT11 的 DATA 引脚输出 40 位数据后,继续输出低电平 50 微秒后转为输入状态,由于上拉电阻随 之变为高电平。但 DHT11 内部重测环境温湿度数据,并记录数据,等待外部信号的到来。

例程(cc2530):

#include <ioCC2530.h>
#include "OnBoard.h"

typedef unsigned char uchar;
typedef unsigned int  uint;

#define DATA_PIN P0_7

void Delay_us(void);
void Delay_10us(void);
void Delay_ms(uint Time);
void COM(void);
void DHT11(void);

//温湿度定义
uchar ucharFLAG,uchartemp;
uchar shidu_shi,shidu_ge,wendu_shi,wendu_ge=4;
uchar ucharT_data_H,ucharT_data_L,ucharRH_data_H,ucharRH_data_L,ucharcheckdata;
uchar ucharT_data_H_temp,ucharT_data_L_temp,ucharRH_data_H_temp,ucharRH_data_L_temp,ucharcheckdata_temp;
uchar ucharcomdata;

//延时函数
void Delay_us(void) //1 us延时
{
    MicroWait(1);   
}

void Delay_10us(void) //10 us延时
{
   MicroWait(10);
}

void Delay_ms(uint Time)//n ms延时
{
  unsigned char i;
  while(Time--)
  {
    for(i=0;i<100;i++)
     Delay_10us();
  }
}

//温湿度传感
void COM(void)    // 温湿写入
{     
    uchar i;         
    for(i=0;i<8;i++)    
    {
        ucharFLAG=2; 
        while((!DATA_PIN)&&ucharFLAG++);//DHT11发送的数据0为50us低电平和26-28us高电平;数据1为50us低电平和70us高电平
        Delay_10us();                   
        Delay_10us();
        Delay_10us();
        uchartemp=0;                    
        if(DATA_PIN)uchartemp=1;    //等30us后,判断引脚是否还为高电平,如果是则发送的是数据1,否则是数据0
        ucharFLAG=2;
        while((DATA_PIN)&&ucharFLAG++);   //等发送的第一位数据的时序走完,io会变成0
        if(ucharFLAG==1)break;    
        ucharcomdata<<=1;         //一位位送入ucharcomdata,一共八位,即为一个湿度高八位数据,以此内推
        ucharcomdata|=uchartemp; 
    }    
}

void DHT11(void)   //温湿传感启动
{
    DATA_PIN=0;    //给DHT11发送起始信号
    Delay_ms(19);  //>18MS
    DATA_PIN=1;    //输出高,并设置io口为输入
    P0DIR &= ~0x80; //重新配置IO口方向为输入
    Delay_10us();   //延时一下,时长小于80us,因为当dht11收到起始信号会发出80us的响应信号
    Delay_10us();                        
    Delay_10us();
    Delay_10us();  
    if(!DATA_PIN) //此时由于DHT11仍在发出响应信号0,读取引脚为0,进入if
    {
        ucharFLAG=2; 
        while((!DATA_PIN)&&ucharFLAG++);//一直while等待DHT11发送响应信号0的80us走完
        ucharFLAG=2;
        while((DATA_PIN)&&ucharFLAG++); //此时DHT11会发出80us高电平提示准备接受数据,等80us走完,开始发送温湿度数据
        COM();                          //接受湿度高八位数据
        ucharRH_data_H_temp=ucharcomdata;
        COM();                          //接受湿度低八位数据
        ucharRH_data_L_temp=ucharcomdata;
        COM();                          //接受温度高八位数据
        ucharT_data_H_temp=ucharcomdata;
        COM();                          //接受温度低八位数据
        ucharT_data_L_temp=ucharcomdata;
        COM();                          //接受校验位数据
        ucharcheckdata_temp=ucharcomdata;
        DATA_PIN=1; 
        uchartemp=(ucharT_data_H_temp+ucharT_data_L_temp+ucharRH_data_H_temp+ucharRH_data_L_temp);
        if(uchartemp==ucharcheckdata_temp)  //正确的校验位为前面接受的四次数据相加
        {
            ucharRH_data_H=ucharRH_data_H_temp;
            ucharRH_data_L=ucharRH_data_L_temp;
            ucharT_data_H=ucharT_data_H_temp;
            ucharT_data_L=ucharT_data_L_temp;
            ucharcheckdata=ucharcheckdata_temp;
        }
        wendu_shi=ucharT_data_H/10; 
        wendu_ge=ucharT_data_H%10;
        
        shidu_shi=ucharRH_data_H/10; 
        shidu_ge=ucharRH_data_H%10;        
    } 
    else //没用成功读取,返回0
    {
        wendu_shi=0; 
        wendu_ge=0;
        
        shidu_shi=0; 
        shidu_ge=0;  
    } 
    
    P0DIR |= 0x80; //IO口需要重新配置 
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值