查看: 836|回复: 0
打印 上一主题 下一主题

DHT21的驱动程序

[复制链接]
跳转到指定楼层
沙发
发表于 2016-6-4 01:08:49 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
//***********************************************************************************************
//  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

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 加入因仑

本版积分规则

快速回复 返回顶部 返回列表