找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 7328|回復(fù): 6
收起左側(cè)

51單片機,使用DHT11模塊,程序卡死的問題

[復(fù)制鏈接]
ID:332895 發(fā)表于 2019-11-13 23:02 | 顯示全部樓層 |閱讀模式
20黑幣

樓主大四,在做一個基于 51 的智能晾衣架,其中分別使用了 DS18B20、DHT11 檢測溫、濕度,溫度檢測正常,在 dht11 的程序里,通過調(diào)試發(fā)現(xiàn)程序卡死了,在主函數(shù)里讀不出數(shù)據(jù),也無法執(zhí)行后面的程序,單片機型號是 STC 90C52RC ,晶振 11.0592M Hz ,延時函數(shù)使用燒錄軟件生成,之前參考了這篇文章 http://www.torrancerestoration.com/bbs/dpj-162117-1.htmldht11和ds18b20溫濕度控制 單片機程序。 燒錄在大二購買的51學習模塊【巫妖王】12 MHz 可以正常運行,但是燒錄在自己焊接的板子上就出問題了,一度懷疑自己焊接有問題,調(diào)了幾天,累了,遂尋求幫助 。



1、原理圖及PCB

原理圖.png

PCB.png



2、DHT11代碼
"dht11.h"

  • #ifndef __DHT11_H_  
  • #define __DHT11_H_  

  • #include <reg52.h>
  • #include"wifi.h"
  • #include<delay.h>

  • #ifndef uchar
  • #define uchar unsigned char
  • #endif

  • #ifndef uint
  • #define uint unsigned int
  • #endif

  • sbit DATA=P3^6; //溫濕度傳感器DHT11數(shù)據(jù)接入端

  • extern uchar dht11_data[5];         //存儲濕度數(shù)組

  • void DHT11_receive();

  • #endif  



"dht11.c"
  • #include"dht11.h"

  • uchar dht11_data[5];         //存儲濕度數(shù)組

  • //1-檢測到響應(yīng)信號 0-未檢測到
  • uchar DHT11RstAndCheck()
  • {
  •         uchar timer = 0;
  •         
  •         EA = 0;
  •         DATA = 0;
  •         delay20ms();
  •         DATA = 1;
  •         delay30us();
  •         while(!DATA)
  •         {
  •                   timer++;
  •                         _nop_();
  •         }
  •         if(timer>100 || timer<20)
  •         {
  •                  EA = 1;
  •                  return 0;
  •         }
  •         timer = 0;
  •         while(DATA)
  •         {
  •                         timer++;
  •                         _nop_();
  •         }
  •         EA = 1;
  •         if(timer>100 || timer<20)
  •         {
  •                 return 0;
  •         }
  •         return 1;
  • }

  • /*********************************************************************************************
  • 函數(shù)名:DHT11讀數(shù)據(jù)函數(shù)
  • 調(diào)  用:? = DHT11_rec_byte();
  • 參  數(shù):無
  • 返回值:
  • 結(jié)  果:讀DHT11數(shù)據(jù)并保存到dat
  • 備  注:
  • **********************************************************************************************/
  • uchar DHT11_rec_byte()      //接收一個字節(jié)
  • {
  •    uchar i,dat=0;
  •          EA = 0;
  •          for(i=0;i<8;i++)    //從高到低依次接收8位數(shù)據(jù)
  •    {         
  •                   while(DATA);
  •       while(!DATA);   ////等待50us低電平過去
  •                                         delay40us();
  •       dat<<=1;           //左移位使正確接收8位數(shù)據(jù),數(shù)據(jù)為0時直接移位
  •       if(DATA)    //數(shù)據(jù)為1時,使dat加1來接收數(shù)據(jù)1
  •                         {
  •          dat |= 0x01;
  •                         }
  •       while(DATA);  //等待數(shù)據(jù)線拉低   
  •     }  
  •           EA = 1;
  •     return dat;
  • }

  • /*********************************************************************************************
  • 函數(shù)名:接收DHT11的40位的數(shù)據(jù)并校驗
  • 調(diào)  用:? = DHT11_receive();
  • 參  數(shù):無
  • 返回值:無
  • 結(jié)  果:結(jié)果保存到strx
  • 備  注:
  • **********************************************************************************************/
  • void DHT11_receive()                 
  • {
  •           uchar R_H,R_L,T_H,T_L,RH,RL,TH,TL,revise;
  •           EA=0;
  •     DATA=1;                                 // 主線空閑狀態(tài)
  •                         delay10us();
  •     DATA=0;                                 // 主機發(fā)送開始工作信號
  •                         delay20ms();   //延時18ms以上
  •     DATA=1;                                 // 拉高并延時等待DHT11響應(yīng)
  •                         delay30us();
  •           DATA = 1;
  •     if(DHT11RstAndCheck())
  •     {        
  •                                         delay80us();             //拉高后延時80us
  •                                 R_H = DHT11_rec_byte();  //接收濕度高八位
  •                                 R_L = DHT11_rec_byte();  //接收濕度低八位
  •                                 T_H = DHT11_rec_byte();  //接收溫度高八位
  •                                 T_L = DHT11_rec_byte();  //接收溫度低八位
  •                     revise = DHT11_rec_byte();     //接收校正位
  •                           
  •                           DATA = 0;
  •                     delay40us();    //結(jié)束
  •                     DATA = 1;
  •                                 if((R_H+R_L+T_H+T_L)==revise)           //數(shù)據(jù)校驗
  •                                 {
  •                                                 RH=R_H;
  •             RL=R_L;
  •             TH=T_H;
  •             TL=T_L;
  •                                 }
  •                  
  •         /*數(shù)據(jù)處理,方便顯示*/
  •         dht11_data[0]='0'+(RH/10);
  •         dht11_data[1]='0'+(RH%10);
  •         dht11_data[2]='0'+(TH/10);
  •         dht11_data[3]='0'+(TH%10);
  •                                 dht11_data[4]=RH;        
  •                                 send_table[20]=dht11_data[0];
  •                                 send_table[21]=dht11_data[1];
  •                 }
  • }   


3、焊接及顯示內(nèi)容
焊接.jpg



顯示.jpg
回復(fù)

使用道具 舉報

ID:639532 發(fā)表于 2019-11-15 17:55 | 顯示全部樓層
程序我就不看了,給你個思路,一般會你這現(xiàn)象的原因有:1,單片機的中斷標志沒清,導(dǎo)致程序一直跑中斷,不運行主函數(shù);2,中斷的等級沒處理好,有些函數(shù)被更高級別的中斷阻塞了;3,用了一些空指針,程序跑飛了;4,內(nèi)存占滿了;5,某些寄存器會在某些行為(比如觸發(fā)中斷)后自動清0,導(dǎo)致你的配置被清了;6,你所使用的單片機這一方面性能不穩(wěn)定(這個可能非常小這么多年就見過一次,原廠fae都解決不了)

評分

參與人數(shù) 1黑幣 +5 收起 理由
Eli_ + 5 贊一個!

查看全部評分

回復(fù)

使用道具 舉報

ID:245004 發(fā)表于 2019-11-15 22:47 | 顯示全部樓層
84行到88行的代碼不合適吧?對照數(shù)據(jù)手冊看看。單片機時鐘必須跟延時函數(shù)一致;延時函數(shù)盡量放在當前c文件里,不要放在其它文件里;以下代碼僅供參考:
io_DHT11 = 0;                 //主機拉低 >18ms
        Delay25ms();
        io_DHT11 = 1;                //20~40us后從機應(yīng)答拉低電平
        Delay60us();                 //延時大于(20~40us)
        if(io_DHT11 == 0)         //判斷從機是否響應(yīng)
        {
                if (DHT11_WaitLevelChange(0) == isNo) return isNo;        //規(guī)定時間內(nèi)電平0是否改變?如果未改變返回isNo
                if (DHT11_WaitLevelChange(1) == isNo) return isNo;        //規(guī)定時間內(nèi)電平1是否改變?如果未改變返回isNo

                i = 0;
                ucArrTemp[i++] = DHT11_ReadByte();
                ucArrTemp[i++] = DHT11_ReadByte();
                ucArrTemp[i++] = DHT11_ReadByte();
                ucArrTemp[i++] = DHT11_ReadByte();
                ucArrTemp[i]   = DHT11_ReadByte();


評分

參與人數(shù) 1黑幣 +5 收起 理由
Eli_ + 5 贊一個!

查看全部評分

回復(fù)

使用道具 舉報

ID:123289 發(fā)表于 2019-11-16 09:17 | 顯示全部樓層
關(guān)鍵點:
1、不要用DEALY做延時。
2、等待硬件信號時,要做限時動作,等不到就返回,并標記異常通知主程序。

評分

參與人數(shù) 1黑幣 +5 收起 理由
Eli_ + 5 贊一個!

查看全部評分

回復(fù)

使用道具 舉報

ID:647620 發(fā)表于 2019-11-23 02:16 | 顯示全部樓層
想知道樓主解決了嗎?
。。。表示碰到了一樣的問題 。。把dht11拔了 別的都正常,插上dht11就卡住了  感覺上好像是卡在某個while里面了。。。。。。。作為一個初學者毫無頭緒
回復(fù)

使用道具 舉報

ID:647620 發(fā)表于 2019-11-23 02:21 | 顯示全部樓層
對了還有個現(xiàn)象 卡住以后 濕度高位不知道為什么變成了255.。。
回復(fù)

使用道具 舉報

ID:647620 發(fā)表于 2019-11-23 18:57 | 顯示全部樓層
樓主數(shù)據(jù)線設(shè)的P3^6 可是 沒有把端口設(shè)置成開漏,可以設(shè)置一下試試 。我今天把sda換到P0口  程序不至于卡死了。。雖然取值還不對 。感覺之前卡死是因為從機沒法置低導(dǎo)致開在while判斷上了
回復(fù)

使用道具 舉報

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

本版積分規(guī)則

小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機教程網(wǎng)

快速回復(fù) 返回頂部 返回列表