久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 4766|回復: 7
打印 上一主題 下一主題
收起左側

DHT11的STM32歷程移植到51單片機,數據和校驗都出了問題!能否看下怎么解決,謝謝!

[復制鏈接]
回帖獎勵 2 黑幣 回復本帖可獲得 2 黑幣獎勵! 每人限 1 次
跳轉到指定樓層
樓主
ID:116263 發表于 2018-5-10 03:59 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
將正點原子的歷程移植到51中,時序圖對照了感覺沒錯,DHT11能響應,但是讀數據時卻不對,只能讀數據“1”,讀不到數據“0”,校驗也不對,在stm32中卻可以顯示,對照了下DHT11整個時序圖,覺得沒問題,想問下怎么解決,謝謝!

line level    source
   1          #include "REG51.h"
   2          #include <intrins.h>
   3          #include "DHT11.h"
   4          #include "oled.h"
   5          uchar i,humidity,temperature;

   6          void DHT11_delay_ms(uchar c)   //誤差 0us
   7          {
   8   1          unsigned char a,b;
   9   1          for(;c>0;c--)
  10   1              for(b=142;b>0;b--)
  11   1                  for(a=2;a>0;a--);
  12   1      }
  13         
  14            void DHT11_delay_us(uchar n)
  15          {
  16   1          while(--n);
  17   1      }
  18         
  19          void DHT11_Rst(void)// 主機發出起始信號
  20          {
  21   1         Data=1;
  22   1          DHT11_delay_us(2);
  23   1          Data=0;       //拉低DQ
  24   1          DHT11_delay_ms(20);     //拉低至少18ms
  25   1          Data=1;       //DQ=1
  26   1          DHT11_delay_us(30);       //主機拉高20~40us
  27   1      }
  28         
  29          /*  返回0: retry為0,則存在
  30              返回1:未檢測到DHT11的存在
  31          */
  32         
  33          uchar DHT11_Check(void)//等待DHT11響應
  34          {
  35   1         uchar retry=0;
  36   1         while (Data&&(retry<100))//DHT11會拉低40~80us
  37   1        {
  38   2          retry++;  
  39   2          DHT11_delay_us(1);
  40   2        }  
  41   1        if(retry>=100)
  42   1          return 1;
  43   1          else retry=0;
  44   1         while ((!Data)&&(retry<100))//DHT11拉低后會再次拉高40~80us
  45   1        {
  46   2            retry++;
  47   2            DHT11_delay_us(1);
  48   2        }
  49   1        if(retry>=100)
  50   1           return 1;   
  51   1          else   return 0;
  52   1      }
  53         
  54          uchar DHT11_Read_Bit(void)//讀取一位  
  55          {
  56   1            uchar retry=0;
  57   1            while(Data&&(retry<60))//等待變為低電平
  58   1            {
  59   2                   retry++;   
  60   2                   DHT11_delay_us(1);
  61   2             }
  62   1             retry=0;
  63   1            while((!Data)&&(retry<100))//等待變高電平
  64   1             {
  65   2                    retry++;  
  66   2                    DHT11_delay_us(1);
  67   2             }  
  68   1               DHT11_delay_us(50);//等待40us
  69   1               if(Data)
  70   1                 return 1;
  71   1               else            
  72   1                  return 0;
  73   1      
  74   1        
  75   1      
  76   1      }
  77         
  78         
  79          uchar DHT11_Read_Byte(void)//讀取一個字節  用前面讀取的每8位,組成一個字節
  80          {
  81   1            uchar i,dat;
  82   1          dat=0;
  83   1         for (i=0;i<8;i++)
  84   1          {
  85   2            dat<<=1;
  86   2           dat|=DHT11_Read_Bit();
  87   2          }           
  88   1          return dat;
  89   1      
  90   1      }
  91         
  92          uchar DHT11_Read_Data(void)  //解析所讀取的溫度和濕度
  93          {
  94   1         uchar buff[5];
  95   1          DHT11_Rst();//主機發出起始信號
  96   1         if(DHT11_Check()==0)//等待DHT11響應,如果返回0,則主機檢測到DHT11的響應信號
  97   1         {
  98   2                for(i=0;i<5;i++)//讀取40位數據
  99   2          {      
100   3                buff[ i]=DHT11_Read_Byte();//讀取數據(8位)
101   3          }
102   2         
103   2          if((buff[0]+buff[1]+buff[2]+buff[3])==buff[4])//檢驗
104   2         {
105   3              humidity=buff[0];//8bit濕度整數數據
106   3              temperature =buff[2];//8bit溫度整數數據
107   3         }
108   2       }
109   1         else return 1;
110   1         return 0;      
111   1      }


分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復

使用道具 舉報

沙發
ID:164602 發表于 2018-5-10 07:24 | 只看該作者
為什么要從STM32移植,直接用51的不好嗎?
給你一個:
/****************************************************************
//           DHT21使用范例
//單片機 AT89S52 或 STC89C52RC
//功能   串口發送溫濕度數據 晶振 11.0592M 波特率 4800
//硬件   P2.0口為通訊口連接DHT11,DHT11的電源和地連接單片機的電源和地,單片機串口加MAX232連接電腦
//公司  雁凌電子   
****************************************************************/

#include <reg51.h>
#include <intrins.h>

sbit  P2_0  = P2^0 ;//溫濕度傳感器的數據接口

sbit SMG_q = P1^0;        //定義數碼管陽級控制腳(千位)
sbit SMG_b = P1^1;        //定義數碼管陽級控制腳(百位)
sbit SMG_s = P1^2;        //定義數碼管陽級控制腳(十位)
sbit SMG_g = P1^3;        //定義數碼管陽級控制腳(個位)

unsigned char ly_disdate[4]={0,0,0,0};
//----------------------------------------------//
//----------------定義區--------------------//
//----------------------------------------------//
unsigned char  U8FLAG;
unsigned char  U8temp;
unsigned char  U8T_data_H,U8T_data_L,U8RH_data_H,U8RH_data_L,U8checkdata;
unsigned char  U8T_data_H_temp,U8T_data_L_temp,U8RH_data_H_temp,U8RH_data_L_temp,U8checkdata_temp;
unsigned char  U8comdata;
unsigned char  outdata[5];  //定義發送的字節數          
unsigned char  indata[5];
unsigned char  count, count_r=0;
unsigned char str[5]={"RS232"};

code unsigned char table[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,
                                                        0x88,0x83,0xc6,0xa1,0x86,0x8e};        //共陽數碼管段值表 0-9 a-f

void delay(void)//延時35.5us
{               
        unsigned char i=10;
        while(i--);
}


void Delay(unsigned int j)//延時888.1725us
{
        unsigned char i;
        for(;j>0;j--)
        {        
                for(i=0;i<27;i++);
        }
}

void  Delay_10us(void)
{
        unsigned char i;
        i--;
        i--;
        i--;
        i--;
        i--;
        i--;
}
       
void COM (void)//讀數據
{
        unsigned char i;
        for(i=0;i<8;i++)          
        {
                U8FLAG=2;       
                while((!P2_0)&&U8FLAG++);
                Delay_10us();
                Delay_10us();                               
                Delay_10us();
                U8temp=0;
                if(P2_0)U8temp=1;
                U8FLAG=2;
                while((P2_0)&&U8FLAG++);
                   //超時則跳出for循環                  
                if(U8FLAG==1)break;
                   //判斷數據位是0還是1         
                // 如果高電平高過預定0高電平值則數據位為 1
                U8comdata<<=1;
                U8comdata|=U8temp;        //0
        }//rof
}

        //--------------------------------
        //-----濕度讀取子程序 ------------
        //--------------------------------
        //----以下變量均為全局變量--------
        //----溫度高8位== U8T_data_H------
        //----溫度低8位== U8T_data_L------
        //----濕度高8位== U8RH_data_H-----
        //----濕度低8位== U8RH_data_L-----
        //----校驗 8位 == U8checkdata-----
        //----調用相關子程序如下----------
        //---- Delay();, Delay_10us();,COM();
        //--------------------------------
void RH (void)
{       
        //主機拉低18ms
        P2_0=0;
        Delay(180);
        P2_0=1;
        //總線由上拉電阻拉高 主機延時20us
        Delay_10us();
        Delay_10us();
        Delay_10us();
        Delay_10us();            
        //主機設為輸入 判斷從機響應信號
        P2_0=1;
        //判斷從機是否有低電平響應信號 如不響應則跳出,響應則向下運行          
        if(!P2_0)                 //T !          
        {
                U8FLAG=2;
                //判斷從機是否發出 80us 的低電平響應信號是否結束         
                while((!P2_0)&&U8FLAG++);
                U8FLAG=2;
                //判斷從機是否發出 80us 的高電平,如發出則進入數據接收狀態
                while((P2_0)&&U8FLAG++);
                //數據接收狀態                 
                COM();
                U8RH_data_H_temp=U8comdata;
                COM();
                U8RH_data_L_temp=U8comdata;
                COM();
                U8T_data_H_temp=U8comdata;
                COM();
                U8T_data_L_temp=U8comdata;
                COM();
                U8checkdata_temp=U8comdata;
                P2_0=1;
                //數據校驗
                U8temp=(U8T_data_H_temp+U8T_data_L_temp+U8RH_data_H_temp+U8RH_data_L_temp);
                if(U8temp==U8checkdata_temp)
                {
                        U8RH_data_H=U8RH_data_H_temp;
                        U8RH_data_L=U8RH_data_L_temp;
                        U8T_data_H=U8T_data_H_temp;
                        U8T_data_L=U8T_data_L_temp;
                        U8checkdata=U8checkdata_temp;
                }//fi
        }//fi
}
       

void display()//采用的掃描法使數碼管動態顯示,即,讓一位數碼管顯示、關閉,再讓下一位顯示、
                          //關閉,時間很短,人眼通過“視覺暫留”就可以看到全部數碼管都在亮了
{
        SMG_q=0;                        //選擇千位數碼管(亮)
        P0=table[ly_disdate[0]];        //
        delay();                        //
        P0=0XFF;                        //
        SMG_q=1;                        //(滅)

        SMG_b=0;                        //選擇百位數碼管
        P0=table[ly_disdate[1]]-0x80;        //加上小數點
        delay();                        //延時
        P0=0XFF;                        //
        SMG_b=1;                        //

        SMG_s=0;                        //選擇十位數碼管
        P0=table[ly_disdate[2]];        //
        delay();                        //
        P0=0XFF;                        //
        SMG_s=1;                        //

        SMG_g=0;                        //選擇個位數碼管
        P0=table[ly_disdate[3]];        //
        delay();                        //
        P0=0XFF;                        //
        SMG_g=1;                        //
}

//----------------------------------------------
//main()功能描述:  AT89C51  11.0592MHz         串口發
//送溫濕度數據,波特率 9600
//----------------------------------------------
void main()
{       
        unsigned int n=0,i=20000;

        /* 系統初始化 */
        TMOD = 0x20;          //定時器T1使用工作方式2
        TH1 = 243;        // 設置初值
        TL1 = 243;
        TR1 = 1;          // 開始計時
        SCON = 0x50;          //工作方式1,波特率4800bps,允許接收   
        PCON=0x80;
        ES = 1;
        EA = 1;           // 打開所以中斷   
        TI = 0;
        RI = 0;
//        SendData(str) ;   //發送到串口
        Delay(10);         //延時100US(12M晶振)
        while(1)
        {  
                //------------------------
                //調用溫濕度讀取子程序
                RH();
                //串口顯示程序
                //--------------------------
                str[0]=U8RH_data_H;
                str[1]=U8RH_data_L;
                str[2]=U8T_data_H;
                str[3]=U8T_data_L;
                str[4]=U8checkdata;
                        Delay(200);
                        SBUF=str[0];//濕度值,十六進制數
                        Delay(200);       
                        SBUF=str[2];//溫度值,十六進制數
                        Delay(200);
                       
                //讀取模塊數據周期不宜小于 2S
                i=10000;
                while (i)//3.69s掃描一次
                {
                        if (n<5000)//1.845s換一次顯示,先顯示濕度,后顯示溫度
                        {
                                ly_disdate[0]=str[0]/16;//前兩位是十六進制數
                                ly_disdate[1]=str[0]%16;
                                ly_disdate[2]=str[0]/10;//后兩位是十進制數
                                ly_disdate[3]=str[0]%10;
                        }
                        else
                        {
                                ly_disdate[0]=str[2]/16;
                                ly_disdate[1]=str[2]%16;
                                ly_disdate[2]=str[2]/10;
                                ly_disdate[3]=str[2]%10;
                        }
                        n++;
                        i--;
                        if (n==10000)
                        {
                                n=0;
                        }
                        display();
                }
//                        Delay(20000);
        }//elihw
}// main

void RSINTR() interrupt 4 using 2
{
        unsigned char InPut3;
        if(TI==1) //發送中斷          
        {
                TI=0;
                if(count!=5) //發送完5位數據         
                {
                        SBUF= outdata[count];
                        count++;
                }
        }
        if(RI==1)         //接收中斷                  
        {       
                InPut3=SBUF;
                indata[count_r]=InPut3;
                count_r++;
                RI=0;                                                                 
                if (count_r==5)//接收完4位數據
                {
                        //數據接收完畢處理。
                        count_r=0;
                        str[0]=indata[0];
                        str[1]=indata[1];
                        str[2]=indata[2];
                        str[3]=indata[3];
                        str[4]=indata[4];
                        P0=0;
                }
        }
}

評分

參與人數 1黑幣 +60 收起 理由
admin + 60 回帖助人的獎勵!

查看全部評分

回復

使用道具 舉報

板凳
ID:326504 發表于 2018-5-10 08:46 | 只看該作者
#include "dht11.h"   void delay(uchar ms) //延時模塊//   {     uchar i;     while(ms--)                              for(i=0;i<100;i++);   }    void delay1()//一個for循環大概需要8個多機器周期一個機器周期為1us晶振為12MHz也就是說本函數延時8us多此延時函數必須德稍微精確一點   {     uchar i;     for(i=0;i<1;i++);   }  void Delay5ms()                //@12.000MHz {         unsigned char i, j;          i = 10;         j = 183;         do         {                 while (--j);         } while (--i); } void Delay20ms()                //@11.0592MHz {         unsigned char i, j;          i = 36;         j = 217;         do         {                 while (--j);         } while (--i); }   void Delay30us()                //@11.0592MHz {         unsigned char i;          i = 11;         while (--i); }  void Delay27us()                //@11.0592MHz {         unsigned char i;          _nop_();         i = 9;         while (--i); }  void start()//開始信號   {     io=1;     delay1();     io=0;     Delay20ms();// 主機把總線拉低必須大于18ms保證DHT11能檢測到起始信號     io=1;    //發送開始信號結束后拉高電平延時20-40us    Delay30us();//以下三個延時函數差不多為24us符合要求      }      uchar receive_byte()//接收一個字節//   {     uchar i,temp;     for(i=0;i<8;i++)//接收8bit的數據     {            while(!io);//等待50us的低電平開始信號結束    Delay27us();//開始信號結束之后延時26us-28us以下三個延時函數              temp=0;//時間為26us-28us表示接收的為數據'0'            if(io==1)            temp=1; //如果26us-28us之后還為高電平則表示接收的數據為'1'       while(io);//等待數據信號高電平'0'為26us-28us'1'為70us            data_byte<<=1;//接收的數據為高位在前右移            data_byte|=temp;     }     return data_byte;   }         void receive()//接收數據//   {     uchar T_H,T_L,R_H,R_L,check,num_check;     start();//開始信號//     io=1;   //主機設為輸入判斷從機DHT11響應信號     if(!io)//判斷從機是否有低電平響應信號//     {           while(!io);//判斷從機發出 80us 的低電平響應信號是否結束//           while(io);//判斷從機發出 80us 的高電平是否結束如結束則主機進入數據接收狀態           R_H=receive_byte();//濕度高位            R_L=receive_byte();//濕度低位           T_H=receive_byte();//溫度高位           T_L=receive_byte();//溫度低位           check=receive_byte();//校驗位           io=0; //當最后一bit數據接完畢后從機拉低電平50us//   Delay27us();//差不多50us的延時   Delay27us();           io=1;//總線由上拉電阻拉高進入空閑狀態           num_check=R_H+R_L+T_H+T_L;           if(num_check==check)//判斷讀到的四個數據之和是否與校驗位相同            {      RH=R_H;      RL=R_L;      TH=T_H;      TL=T_L;      check=num_check;            }     }   }
回復

使用道具 舉報

地板
ID:311407 發表于 2018-5-10 09:26 | 只看該作者
時序的時間很重要,延時函數看是否正確
回復

使用道具 舉報

5#
ID:116263 發表于 2018-5-10 10:30 | 只看該作者
HC6800-ES-V2.0 發表于 2018-5-10 07:24
為什么要從STM32移植,直接用51的不好嗎?
給你一個:
/********************************************** ...

因為以前需要用32檢測DHT11,根據時序圖來看,F在需要51,所以就移植過去,卻有問題,我只是想知道問題出在哪里,所以才沒用51的
回復

使用道具 舉報

6#
ID:232585 發表于 2018-5-10 15:59 | 只看該作者
延時函數不對吧
回復

使用道具 舉報

7#
ID:275894 發表于 2019-4-14 17:38 | 只看該作者
今天調試,也出現類似的問題,數據接收不對,校驗和出錯(很詭異,DTH11輸出校驗和與實際計算值偏差10以內),
回復

使用道具 舉報

8#
ID:275894 發表于 2019-4-14 17:41 | 只看該作者
調試中也出現類似問題,最后發現問題出在DTH11應答位延時時間不準。
DTH11應答位,輸出高/低電平為80us;如果不符合這個值,將會造成接收數據與時間值不符,校驗和不對;
我將應答位的判斷,全部換用while循環,才解決該問題;見備注處;

void DTH_rec_all()
{
     DTH_start();
     if(dat==0)
         {
         while(dat==0);
         while(dat==1);
/*
此處非常不建議使用延時函數delay80us來代替該while循環,
否則容易導致后面采集的數據不準,并且校驗和不對
*/
         R_H=Rec_DTH();
         R_L=Rec_DTH();
         T_H=Rec_DTH();
         T_L=Rec_DTH();
         sum=Rec_DTH();
         }  
}
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 中文字幕亚洲在线 | 日韩欧美一区二区三区 | 艹逼网 | 欧美日韩看片 | 日本久久福利 | 成人精品视频99在线观看免费 | 国产精品激情 | 天天操夜夜爽 | 国产精品黄色 | 综合二区| 国外成人在线视频 | 国产精品揄拍一区二区 | 精品久久久999 | 成人在线中文字幕 | 欧美日韩一区精品 | 午夜影院黄 | 日韩视频在线观看一区二区 | 美女久久| 久草在线| 国产成人精品免费视频 | 亚洲人va欧美va人人爽 | 欧美日韩在线免费 | 一区二区三区中文字幕 | 欧美一区二区大片 | 久久国内 | 精品视频99 | 精品久久久一区二区 | 久久久久国产一区二区三区 | 亚洲美女天堂网 | 玖玖在线免费视频 | v片网站| 久久国产精品72免费观看 | 中文字幕中文字幕 | 国产精品久久二区 | 欧美日韩精品一区二区三区视频 | 欧美日韩专区 | 九九在线视频 | 国产欧美日韩精品一区 | 狠狠ri| 国产免费一区二区三区免费视频 | 狠狠干五月天 |