//***********************************************************************************************
// DHT21.c DHT21 bus module
// 2010,4,8
// Compiler WINAVR 20100110
// Copyright By zsmbj
//
//**********************************************************************************************
#define F_CPU 8000000UL
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
//----------------------------------------------------------------------------------------------
// DHT21 Hardware IO defination
//----------------------------------------------------------------------------------------------
//DDR PORT
//0 0 in,high
//0 1 in,r
//1 0 out=0
//1 1 out=1
#define DHT_DAT PINB0
#define DHT_DAT_HIGH() ( DDRB &= ~(1<<DHT_DAT) )
#define DHT_DAT_LOW() ( DDRB |= (1<<DHT_DAT) )
#define IS_DHT_DAT_High() ( PINB & (1<<DHT_DAT) )
//----------------------------------------------------------------------------------------------
// Name: void DHT_Delay(void)
// Parameters: CLK_WIDTH delay time
// Function: delay us time with nop
// return : none
// Notice: none
// Created: 2010,4,8 zsmbj
//----------------------------------------------------------------------------------------------
void DHT_Delay(unsigned char us)
{
_delay_us(us);
}
//----------------------------------------------------------------------------------------------
// Name: void Init_DHT21(void)
// Parameters: none
// Function: Init_DHT21 bus
// return : none
// Notice: none
// Created: 2010,4,8 zsmbj
//----------------------------------------------------------------------------------------------
void Init_DHT21(void)
{
DHT_DAT_HIGH();
}
//----------------------------------------------------------------------------------------------
// Name: unsigned char Wait_RISE_EDGE(unsigned char* temp)
// Parameters: none
// Function:
// return : none
// Notice: none
// Created: 2010,4,8 zsmbj
//----------------------------------------------------------------------------------------------
unsigned char Wait_RISE_EDGE(unsigned char* temp)
{
unsigned char flag=0,i=0,ack=0;
while(1)
{
if( !(IS_DHT_DAT_High()) )
{
flag = 1;
}
else
{
if(flag == 1)
{
temp[0] = i; //return time :us
break;
}
}
// DHT_Delay(1);
i++;
if(i >= 200) //if wait 200us for nothing then return
{
ack = 1;
break;
}
}
return ack;
}
//----------------------------------------------------------------------------------------------
// Name: unsigned char Wait_FALL_EDGE(unsigned char* temp)
// Parameters: none
// Function:
// return : none
// Notice: none
// Created: 2010,4,8 zsmbj
//----------------------------------------------------------------------------------------------
unsigned char Wait_FALL_EDGE(unsigned char* temp)
{
unsigned char flag=0,i=0,ack=0;
while(1)
{
if( (IS_DHT_DAT_High()) )
{
flag = 1;
}
else
{
if(flag == 1)
{
temp[0] = i; //return time :us
break;
}
}
// DHT_Delay(1);
i++;
if(i >= 200) //if wait 200us for nothing then return
{
ack = 1;
break;
}
}
return ack;
}
//----------------------------------------------------------------------------------------------
// Name: unsigned char Get_DHT_Temp_Humi(unsigned char* temp)
// Parameters: none
// Function:
// return : none
// Notice: none
// Created: 2010,4,8 zsmbj
//
// ----| start | 20- |salve ack(2*80us)| data0 26- | data1 |stop-------
// ____ _40us_ __80us__ _28us_ __70us__ ____
// DAT : |____500us____| |__80us__| |_50us_| |_50us_| |_50us_|
//----------------------------------------------------------------------------------------------
unsigned char Get_Temp_Humi(unsigned char* temp)
{
unsigned char sum,i,j,ack,data[5],dat;
//Send start
DHT_DAT_LOW(); //set data low
DHT_Delay(250); //
DHT_Delay(250); //delay 500us
DHT_DAT_HIGH(); //set data high
DHT_Delay(20); //delay 20us
//get ack
ack = Wait_RISE_EDGE(&dat); //senond riseedge,80us,low level
if(ack != 0)
{
return ack;
}
ack += Wait_FALL_EDGE(&dat); //third falledge,80us high level
if(ack != 0)
{
return ack;
}
cli(); //we close interrupt
//get temp and humi 5 byte
for(i = 0;i<5;i++) //we got 40 bit data that is 5 byte
{
data = 0;
for(j = 0;j<8;j++)
{
ack = Wait_FALL_EDGE(&dat);
if(ack != 0)
{
ack = 1;
break;
// return ack;
}
else
{
if( (dat >= 110) && (dat <= 130) ) //bit 1,total 120us; we test is 122us
{
data <<= 1;
data += 1;
}
else if( (dat >= 67) && (dat <= 87) ) //bit 0,total 77us ;we test is 72us
{
data <<= 1;
data += 0;
}
else //an know bit
{
ack = 1;
break;
// return ack;
}
}
}
}
sei(); //we open interrupt
if(ack == 1)
{
return ack;
}
else
{
//calculate sum
sum = data[0] + data[1] + data[2] + data[3];
if( sum == data[4] )
{
temp[0] = data[2]; //temp msb
temp[1] = data[3]; //temp lsb
temp[2] = data[0]; //humi msb
temp[3] = data[1]; //humi lsb
ack = 0;
}
else
{
temp[0] = 0; //temp msb
temp[1] = 0; //temp lsb
temp[2] = 0; //humi msb
temp[3] = 0; //humi lsb
ack = 1;
}
//Stop
DHT_Delay(50); //delay 50us
DHT_DAT_HIGH(); //set data high
return ack;
}
}
//END OF DHT21.C
|