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

温湿度传感器DHT11的使用

程序员文章站 2022-07-13 17:15:54
...

DHTDAT和单片机引脚相连。
温湿度传感器DHT11的使用
1、VDD 供电3.3~5.5V DC
2、DATA 串行数据,单总线
3、NC 空脚
4、GND 接地,电源负极

单总线传送数据位定义

DATA用于微处理器与DHT11之间的通讯和同步,采用单总线数据格式,一次传送40位数据,高位先出。
数据格式:
8bit湿度整数数据+8bit湿度小数数据+8bit温度整数数据+8bit温度小数数据+8bit校验位。
注:其中湿度小数部分为0。
校验位数据定义
“8bit湿度整数数据+8bit湿度小数数据+8bit温度整数数据+8bit温度小数数据”8bit校验
位等于所得结果的末8位。
Timing图:
温湿度传感器DHT11的使用
从上图可以看出上电开始时主机信号要保持高电平,可以看出,由上拉电阻拉高。然后主机发送一个低电平信号作为起始信号,根据数据手册,低电平时间为18-30ms,之后微处理器将电平拉高等待传感器发送低电平响应信号,响应信号结束后传感器输出一段时间的高电平准备输出数据,从图中可以看出,输出数据0或者数据1的区别在于输出高电平的时间不同,而在表示数据位的高电平之前均输出相同时间低电平,查询数据手册可以得出高电平时间为23-27us表示数据位0,68-74us表示数据位1,因此可以在输出数据位之前的低电平结束术后延时30us,通过读取此时数据总线的状态,来判断输出的是0还是1。
Proteus仿真图
温湿度传感器DHT11的使用
程序
MAIN.H

#ifndef _MAIN_H
#define _MAIN_H
/*--------------------------------------------*/

#include "iodefine.h"				//自定义内容

/*--------------------------------------------*/
#define DHT11
#define interruptInit				//在DHT文件中
#define DELAY
//#define  _TEST_CHANGE_

/*--------------------------------------------*/
#ifdef DHT11
void start_DHT11();
void time_Tgo();                	//主机释放总线时间,13us
//void time_Trel();               	//DHT11响应低电平时间,83us
//void time_Treh();               	//DHT11响应高电平时间,87us
/*void time_Tlow_en();            	//信号 0 1 低电平时间 = 传感器释放总线时间,54us
void time_Th0();                	//信号0高电平时间,24us
void time_Th1();                	//信号1高电平时间,71us
*/
void time_delay30us();
uchar getDHT11_byte();				//获得一个字节数据
void getDHT11_allData();			//获得所有40位数据,存放在sensor_DATA[4]中
void DHT_seg7diplay();				//前两位显示湿度 百分比,后两位显示温度 摄氏度
#endif

/*--------------------------------------------*/
#ifdef DELAY
#define DELAY_MS_US
void delay_ms(uint xms);
void delay_us(uint Xus);
#endif

/*--------------------------------------------*/
#ifdef interruptInit
void interrupt_Init(void);
#endif


/*--------------------------------------------*/
#endif

IODEF.H

#ifndef _IODEF_H_
#define _IODEF_H_

#include<REG52.H>
#include <INTRINS.H>
#include <ABSACC.H>

#define uchar unsigned char
#define uint unsigned int
/*
#define seg70 P2_0					//湿度十位数//ADC千位
#define seg71 P2_1					//湿度个位数//ADC百位
#define seg72 P2_2					//温度十位数//ADC十位
#define seg73 P2_3					//温度个位数//ADC个位
*/
#define segA P1_4
#define segB P1_5					//用74HC139节省IO资源

#define flagled P1_1				//DTH11校验正确显示灯
sbit P0_0 = P0^0;
sbit P0_1 = P0^1;
sbit P0_2 = P0^2;
sbit P0_3 = P0^3;
sbit P0_4 = P0^4;
sbit P0_5 = P0^5;
sbit P0_6 = P0^6;
sbit P0_7 = P0^7;

sbit P1_0 = P1^0;
sbit P1_1 = P1^1;
sbit P1_2 = P1^2;
sbit P1_3 = P1^3;
sbit P1_4 = P1^4;
sbit P1_5 = P1^5;
sbit P1_6 = P1^6;
sbit P1_7 = P1^7;

sbit P2_0 = P2^0;
sbit P2_1 = P2^1;
sbit P2_2 = P2^2;
sbit P2_3 = P2^3;
sbit P2_4 = P2^4;
sbit P2_5 = P2^5;
sbit P2_6 = P2^6;
sbit P2_7 = P2^7;

sbit P3_0 = P3^0;
sbit P3_1 = P3^1;
sbit P3_2 = P3^2;
sbit P3_3 = P3^3;
sbit P3_4 = P3^4;
sbit P3_5 = P3^5;
sbit P3_6 = P3^6;
sbit P3_7 = P3^7;

#endif

DELAY.C

#include"main.h"

#ifdef DELAY_MS_US
void delay_ms(uint xms)	
{
    uint loop;
    for (loop = 0; loop < xms; loop++)
    {
        /* 1ms_code 误差	+0.306315ms/2000ms */
        uchar i, j;
        _nop_();
		i = 2;
		j = 195;
		do
		{
			while (--j);
		} while (--i);
    }
}
/*--------------------------*/
void delay_us(uint Xus)
{
  uint i,j;
  for(i=0;i<8;i++){
     for(j=0;j<Xus;j++){
         _nop_();
     }
  }
}
#endif

DHT11.C

#include"main.h"

#ifdef DHT11
#define DATA_DHT11 P3_5				//DHTDAT

uchar data sensor_DATA[4]={0x0,0x0,0x0,0x0};
uchar num;							//数组第几个
uchar code SEG7_yin[] = {
    0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,
};

#ifdef _TEST_CHANGE_

void testChange()
{
  uchar i = 0x56;
  sensor_DATA[2] = i;
}
#endif

void start_DHT11()
{
    DATA_DHT11 = 1;
	_nop_();_nop_();_nop_();_nop_();
    DATA_DHT11 = 0;
    delay_ms(20);
    DATA_DHT11 = 1;             //微处理器的I/O设置为输入状态,由上拉电阻拉高
    time_Tgo();               	//释放总线,13us,等待回应时间应大于proteus上的时间30us
	time_Tgo();
	time_Tgo();					//3*13us
	//DATA_DHT11 = 1;
}

void time_Tgo()
{
    uchar i;
	_nop_();
	i = 3;
	while (--i);
}
/*
void time_Trel()
{
    uchar i;
	_nop_();
	i = 35;
	while (--i); 
}

void time_Treh()
{
    uchar i;
	_nop_();
	i = 37;
	while (--i); 
}

void time_Tlow_en()
{
    uchar i;
	i = 11;//22 == 54us
	while (--i);
}
*/
/*
void time_Th0()
{
    unchar i;
    _nop_();
	i = 8;
	while (--i);
}

void time_Th1()
{
    unchar i;
	i = 30;
	while (--i);
}
*/
void time_delay30us()
{
    uchar i;
	i = 11;
	while (--i);
}

uchar getDHT11_byte()
{
    uchar i,dat,temp;
    for ( i = 0; i < 8; i++)
    {
        //time_Tlow_en();//先过54us
        while(!DATA_DHT11);//先过54us,低电平
        time_delay30us();
		temp = 0;
        
        if(DATA_DHT11 == 1)
        {
            temp = 1;

        }
        while(DATA_DHT11);
		dat <<= 1;
		dat = dat|temp;
    }
	return dat;
    
}

void getDHT11_allData()
{
	
	uchar RH,RL,TH,TL,revise;
	start_DHT11();
	
	if(DATA_DHT11 == 0)                     //接收83us的应答信号,
	{	
		while(DATA_DHT11 == 0);             //等待拉高现在data为0     
		while(DATA_DHT11);              	//退出通知单片机接受信号,等87us
        RH=getDHT11_byte();                	//接收湿度高八位  
        RL=getDHT11_byte();                	//接收湿度低八位  
        TH=getDHT11_byte();                	//接收温度高八位  
        TL=getDHT11_byte();                	//接收温度低八位
        revise=getDHT11_byte();             //接收校正位
        //time_Tlow_en();                   //结束
        if((RH+RL+TH+TL)==revise)       	//校正
        {	
			flagled = 1;
			sensor_DATA[0] = RH;
	        sensor_DATA[1] = RL;
	        sensor_DATA[2] = TH;
	        sensor_DATA[3] = TL;
        }
	}
}
void DHT_seg7diplay()
{	
	P0 = 0;
	P0 = SEG7_yin[sensor_DATA[0]/10];
	segB = 0;
	segA = 0;
	delay_us(100);

	P0 = 0;
	P0 = SEG7_yin[sensor_DATA[0]%10];
	segB = 0;
	segA = 1;
	delay_us(100);
	
	P0 = 0;
	P0 = SEG7_yin[sensor_DATA[2]/10]; 
	segB = 1;
	segA = 0;
	delay_us(100);
	
	P0 = 0;
	P0 = SEG7_yin[sensor_DATA[2]%10];
	segB = 1;
	segA = 1;
	delay_us(100);

}
/*************************************************/

#ifdef	interruptInit
void interrupt_Init(void)
{
	EA = 1;
	IT0 = 1; //下降沿触发
	EX0 = 1; //INT0  P3.2
	PX0 = 0;
	IT1 = 1;
	EX1 = 1;
	PX1 = 1;
}
#endif
/*************************************************/
#endif

MAIN.C

#include "main.h"
#define led P1_0
void main()
{	
	interrupt_Init();
	delay_ms(1000);
	flagled = 0;
	while(1)
	{
			led = ~led;	
			DHT_seg7diplay();
	}	

}
void interrupt_getDHT11_Data() interrupt 0 			//EXTERNAL INT 0 0003h 
{
 	getDHT11_allData();								//19.75694ms
	delay_us(100);
	getDHT11_allData();								//连续获取两次以获得实时数据
}

^^Crystal