温湿度传感器DHT11的使用

DHTDAT和单片机引脚相连。
温湿度传感器DHT11的使用_第1张图片
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的使用_第2张图片
从上图可以看出上电开始时主机信号要保持高电平,可以看出,由上拉电阻拉高。然后主机发送一个低电平信号作为起始信号,根据数据手册,低电平时间为18-30ms,之后微处理器将电平拉高等待传感器发送低电平响应信号,响应信号结束后传感器输出一段时间的高电平准备输出数据,从图中可以看出,输出数据0或者数据1的区别在于输出高电平的时间不同,而在表示数据位的高电平之前均输出相同时间低电平,查询数据手册可以得出高电平时间为23-27us表示数据位0,68-74us表示数据位1,因此可以在输出数据位之前的低电平结束术后延时30us,通过读取此时数据总线的状态,来判断输出的是0还是1。
Proteus仿真图
温湿度传感器DHT11的使用_第3张图片
程序
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
#include 
#include 

#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

你可能感兴趣的:(DHT11,温湿度传感器)