搜索
bottom↓
回复: 4

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

[复制链接]

出0入0汤圆

发表于 2013-4-20 15:51:36 | 显示全部楼层 |阅读模式
uchar RH_data_h, TM_data_h, RH_data_l, TM_data_l, cleck_data, temp;
uchar data[5];                                                                                                           //数据缓冲数组
uchar RH_data[3] = {0, 0, '\0'}, TM_data[3] = {0, 0, '\0'};
uchar RH_data_R[3] = {0,0,'\0'}, TM_data_T[3] = {0,0,'\0'};
uchar asc_D[3] = {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[i] = 0X00;
               
                for(j = 0; j < 8; j++)
                {
                         while(!MOSIN);                                    //等待低电平的到来,当低电平到来后便开始计时
                 
                        for(m = 0; m < 50; m++);                   //延时50us后看还是不是高电平,如果是高那么这位就为1,否则为0
                 
                        if(MOSIN)                                                //上面延时了50us,此时引脚数据寄存器还是高电平的话,表明接受到的是1
                          {                                                                  //否则为0  ,
                                  data[i] |= BIT(7 - j);                             //由此可知,先读取的高位,此命令只是写入1的位,data[i] = 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[0] + data[1] + data[2] + data[3]);  
                    if(data[4] == temp)               
                    {
            
                                 RH_data[0] = data[0];                                 //只要整数部分
                                RH_data[1] = data[1];                                       
                            TM_data[0] = data[2];
                                 TM_data[1] = data[3];
                                 cleck_data = data[4];
                            }
                       
            }
         
}

/*------将读到的数据进行拆分显示到液晶上,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();
  }

阿莫论坛20周年了!感谢大家的支持与爱护!!

知道什么是神吗?其实神本来也是人,只不过神做了人做不到的事情 所以才成了神。 (头文字D, 杜汶泽)

出0入0汤圆

发表于 2013-4-20 16:14:04 | 显示全部楼层
延时。  先用示波器调好两个延时再试。

出0入0汤圆

发表于 2013-4-20 17:20:43 | 显示全部楼层
奥松官网有STC的代码 不用调试直接可用

出0入0汤圆

 楼主| 发表于 2013-4-21 19:01:54 | 显示全部楼层
问题已经解决啦。。。还是延时的问题,给大家提供比较精确的延时void delay_30ms (unsigned int n)        //延时30ms  n=4992
{
    unsigned int i;
    i = n;
    while (i--);   
}  

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

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

出70入0汤圆

发表于 2013-4-22 09:29:00 | 显示全部楼层
较长时间延时还是用定时器好,不但精确,在多个任务需要运行的时候会有效提高单片机效率,在不同单片机之间移植程序也方便些。
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-7-24 03:26

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

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