结痂沉香 发表于 2013-4-20 15:51:36

DHT11无法读出数据,请教各位

uchar RH_data_h, TM_data_h, RH_data_l, TM_data_l, cleck_data, temp;
uchar data;                                                                                                           //数据缓冲数组
uchar RH_data = {0, 0, '\0'}, TM_data = {0, 0, '\0'};
uchar RH_data_R = {0,0,'\0'}, TM_data_T = {0,0,'\0'};
uchar asc_D = {0,0, '\0'};       
uchar T0_NUM;

//   内部晶振是使用1M的
//   数据口是PA0
//   延时函数在最后说明

/*************************************************************
函数名称:receive_data
功能:接受数据
************************************************************/
void receive_data()
{
       uchar i,j,m;
       DDRA = 0x00 ;//DATA_IN;
   for(i = 0; i < 5; i++)                  //五字节的数据
       {
          data = 0X00;
               
                for(j = 0; j < 8; j++)
                {
                       while(!MOSIN);                                    //等待低电平的到来,当低电平到来后便开始计时
                 
                        for(m = 0; m < 50; m++);                   //延时50us后看还是不是高电平,如果是高那么这位就为1,否则为0
                 
                        if(MOSIN)                                            //上面延时了50us,此时引脚数据寄存器还是高电平的话,表明接受到的是1
                          {                                                                  //否则为0,
                                  data |= BIT(7 - j);                           //由此可知,先读取的高位,此命令只是写入1的位,data = 0X00,所以没写的还是0
                                while(MOSIN);                          //如果是低电平则表示下一位的开始
                   }   
                }
       }
}

/***********************************************
函数名称:ask_reply_do
功能:主机发出信号,DHT11回复信号,并且处理接收到的数据
**************************************************/
void ask_reply_do()
{
       //主机拉低18ms
           uchar i;
           DDRA =0xff;                                                             //DATA_OUT;
                   PORTA = 0x00;                                                      //PORT_CLR;
           delay_ms(20);
          
           PORTA = 0xff;                                    //PORT_SE                                           //总线由上拉电阻拉高 主机延时20us
          
           for(i = 0; i < 23; i++);                 //此操作为微秒级的延时       
               
           DDRA = 0x00 ;//DATA_IN;
                                        //主机设为输入 判断从机响应信号
           for(i = 0; i < 10;i++);

          if(!MOSIN )                          // 判断从机是否有低电平响应信号 如不响应则跳出,响应则向下运行                         
           {
                                          //判断从机是否发出 80us 的低电平响应信号是否结束       
                     while(!MOSIN);                        //等待从机把电平拉高
                 while(MOSIN);                                              //从机是否发出了高电平,是的话就跳出继续,下面就是接受数据了
                                                          //判断从机是否发出 80us 的高电平,如发出则进入数据接收状态
             //数据接收状态               
                receive_data();   
                     DDRA = 0xff;                                                   //DATA_OUT;               //保证DHT11没工作时数据脚为高电平
                     PORTA = 0xff;                                                //PORT_SET;
             //数据校验
                temp = (data + data + data + data);
                  if(data == temp)               
                  {
          
                               RH_data = data;                                 //只要整数部分
                              RH_data = data;                                       
                          TM_data = data;
                               TM_data = data;
                               cleck_data = data;
                          }
                       
          }
       
}

/*------将读到的数据进行拆分显示到液晶上,x为要显示的数据,y为在液晶上要显示的位置----------*/       
void show_TM_RH(uchar page, uchar line, uchar data)
{
       uchar i, j, m;
          j = data / 10;
          m = data % 10;
       LCD_set_addr(page, line);
       LCD12864_sendbyte(1, j + 0x30);
       LCD12864_sendbyte(1, m + 0x30);
}


//延时函数部分


void delay_1us(void)               //1us延时函数
{
   asm("nop");
}


void delay_us(unsigned int n)       //N us延时函数
{
   unsigned int i = 0;
   for (i = 0; i < n; i++)
   delay_1us();
}



void delay_1ms(void)               //1ms延时函数
{
   unsigned int i;
   for (i = 0;i < 141; i++);                       //晶振为1M时,为8M时为1140
}



void delay_ms(unsigned int n)       //N ms延时函数
{
   unsigned int i = 0;
   for (i = 0; i < n; i++)
   delay_1ms();
}

sco518 发表于 2013-4-20 16:14:04

延时。先用示波器调好两个延时再试。

2fen 发表于 2013-4-20 17:20:43

奥松官网有STC的代码 不用调试直接可用

结痂沉香 发表于 2013-4-21 19:01:54

问题已经解决啦。。。还是延时的问题,给大家提供比较精确的延时void delay_30ms (unsigned int n)      //延时30msn=4992
{
    unsigned int i;
    i = n;
    while (i--);   
}

void delay_50us (unsigned int n)    //延时50usn = 0
{
    unsigned int i;
    i = n;
    while (i--);      
            
}

void delay_30us (unsigned int n)       //延时30us n=2
{   
    while (n--);
}

绿茶山人 发表于 2013-4-22 09:29:00

较长时间延时还是用定时器好,不但精确,在多个任务需要运行的时候会有效提高单片机效率,在不同单片机之间移植程序也方便些。
页: [1]
查看完整版本: DHT11无法读出数据,请教各位