[求助] 请教下会DHT11的大神一个问题

kubiaaa   2013-4-22 17:12 楼主
我按照DHT11的典型电路和时序图在PIC18的单片机上实验成功,但是移植到m430f2619上确不行,关键是在发送完启动信号好,dht11没有给一个低电平回应。卡在这里几天了,请做过的大神指点一下。关键地方加粗了,请帮下忙,谢谢。
#include
#define DQ                                P1IN & BIT0                                                        //数据
#define DQ_HIGH()                         P1DIR |= BIT0; P1OUT |= BIT0                        //设为输出,拉高电平
#define DQ_LOW()                         P1DIR |= BIT0; P1OUT &= ~BIT0                       //设为输出,拉低电平
#define DQ_IN()                           P1DIR &= ~BIT0                                               //设为输入,拉高电平


//外接晶振16MHz
#define CPU_F                                 ((double)16000000)                                        //频率
#define delay_ms(x)                 __delay_cycles((long)(CPU_F*(double)x/1000.0))
#define delay_us(x)                 __delay_cycles((long)(CPU_F*(double)x/1000000.0))


//******************************初始化函数************************
void Init_CLK( void ){        int i;    BCSCTL3 |= XT2S_2;                         // XT2频率范围设置    BCSCTL1 &= ~XT2OFF;                        // 打开XT2振荡器    BCSCTL1 |= DIVA_1;                         // ACLK/2    do    {        IFG1 &= ~OFIFG;                        // 清振荡器失效标志        BCSCTL3 &= ~XT2OF;                     // 清XT2失效标志        for(  i = 0x47FF; i > 0; i-- );    // 等待XT2频率稳定    }while (IFG1 & OFIFG);                     // 外部时钟源正常起动了吗?    BCSCTL2 |= SELM_2 + SELS + DIVS_2 ;        // 设置MCLK、SMCLK为XT2}void Init_Port( void ){    P4OUT &= ~( BIT4+BIT3 + BIT6);    P4SEL |= BIT6;    P4DIR |= BIT4 + BIT6;    P7DIR |= 0xFF;    P7OUT =  0xFF;    P8DIR |= BIT0 + BIT1 + BIT2 + BIT3 + BIT4 + BIT5;    P8OUT = 0xFF;    P5DIR |= BIT7;    P5OUT |= BIT7;    P2REN = 0xff;    P2IFG = 0;    P2IES |= BIT1 + BIT0;                   //开Key1、Key3    P2IE |= BIT0 + BIT1;}void Init_MCU( void ){    WDTCTL = WDTPW + WDTHOLD;                 // 关看门狗    Init_CLK();                               // 初始化时钟    Init_Port();                              // 初始化端口}//******************************初始化函数************************

//***************************dht11*****************************
char receive(void) //接受函数
{
        char tem=0,cnt=0,data=0; //临时变量用于存储接受数据
        int respond=2;
        for(cnt=0;cnt<8;cnt++)
        {
                respond=2;
                while(!DQ && respond++);                             //等待50us的低电平结束
                delay_us(30);
                tem=0;
                if(DQ)                                                             //长于30us定义为1
                {
                        tem=1;
                        respond=2;
                        while(DQ && respond++);                           //结束高电平
                }
                data<<=1;
                data|=tem;
        }
        return data;
}
int get_TRH()
{
        int temp,j;
        char respond=1;

        unsigned char TH_TEMP,TL_TEMP,RH_TEMP,RL_TEMP,CK_TEMP,TH,TL,RH,RL,CK;
        DQ_LOW();                //拉低   
        delay_ms(20);//18ms          延时一个没错吧,我用LED灯试过亮灭500ms的,目测差别不是很大
        DQ_IN();                  //拉高
        delay_us(40);//40us
       //关键在这里DHT11没有给一个低电平的回应,所以下面直接跳过了
        if(!DQ)
        {
                respond=2;
                while(!DQ&&respond++);
                if(respond==1)
                {
                        return 9911;           //超时返回
                }
                respond=2;
                while(DQ&&respond++);
                if(respond==1)
                {
                        return 9912;           //超时返回
                }
                RH_TEMP=receive();
                RL_TEMP=receive();
                TH_TEMP=receive();
                TL_TEMP=receive();
                CK_TEMP=receive();

                DQ_IN();                         //接收结束

                CK=(TH_TEMP+TL_TEMP+RH_TEMP+RL_TEMP);     //数据验证
                if(CK==CK_TEMP)
                {
                        TH=TH_TEMP;
                        TL=TL_TEMP;
                        RH=RH_TEMP;
                        RL=RL_TEMP;
                }
                else
                        return 9993;               //超时返回
       
                temp=(int)(TH);                  //返回温度值
                return temp;
        }
        return 9999;                                //没有回应返回
}
//***************************dht11*****************************
int main( void )
{
        Init_MCU();
        while(1)
        {
                delay_ms(500);
                get_TRH();
        }
        LPM0;
        return 0;
}

回复评论

暂无评论,赶紧抢沙发吧
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复