51單片機(STC89C52RC)讀取DHT11模塊溫度濕度信號采集顯示數碼管


51單片機(STC89C52RC)讀取DHT11模塊溫度濕度信號采集顯示數碼管

上上周末媳婦問我,家里溫度多少,。。。我TM哪知道,租這么個鬼地方,啥也沒有,我能猜的出來嗎,當然“TM的”的是我現在現在加的。。。^_^,然后就想之前也買了一個樹莓派4B也買了一個面包板,再回憶一下大學時曾經所學的知識,算求了,想做個這么個玩意兒,然后,就。。。。。網上一搜,20多塊錢就能買一個。。。。但是作為一個程序員,就是這么喜歡折騰。。。也想多贊點兒私房錢。。然后就多要了點兒經費。。O(∩_∩)O哈哈~

我只是一個單純的軟件開發工程師。。對於硬件僅僅局限於大學那點兒知識而且畢業四五年了,早忘的差不多了,都是靠百度和各位大神的分享來去驅動。。。

1.成品展示

左側溫度,右側濕度   成品和仿真電路有區別,做着過程中發生了變化,就沒有再去仿真了,就增加了倆個報警指示燈

下圖:左側27℃   右側42%RH

2.問老婆申請經費(O(∩_∩)O)

3.下單,購買器件

(這里真是沒想到,買個成品可能20塊錢,但是你要做一個,各東西都得買。。前前后后下單了3次,這里只貼一張圖吧。。,還買倆個萬用表、電烙鐵。。。。各種器件。。。線材啥的。。。。。反正很多,反正是要干賠了,還倒貼了不少私房錢。。)

 

4.繪制電路圖仿真Proteus8.6版本

(基本百度就完了,各種各樣的都有,這個比較簡單)左側溫度,右側濕度

1.DHT11模塊的電路使用 (詳細文檔到這里一下載

 DHT11模塊的時序圖

 

 

 

 

 

 

 

 

 2.電路設計

Proteus電路仿真和C語言程序源代碼下載

 程序

#include<reg51.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
sbit Data=P3^6;       //定義數據線
uchar rec_dat[9];   //用於顯示的接收數據數組
//數碼管數字 0--9
uint led[10]={0xc0,0xf9,0xa4, 0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};  



void delay(uint n)
{  
    uint x,y; 
   for(x=n;x>0;x--) 
       for(y=110;y>0;y--); 
} 



void write_com(uchar com)
{
                           //rs=0時輸入指令
        P2=com;
        delay(5);

}



void DHT11_delay_us(uchar n)
{
    while(--n);
}

void DHT11_delay_ms(uint z)
{
   uint i,j;
   for(i=z;i>0;i--)
      for(j=110;j>0;j--);
}

void DHT11_start()
{
   Data=1;
   DHT11_delay_us(2);
   Data=0;
   DHT11_delay_ms(30);   //延時18ms以上
   Data=1;
   DHT11_delay_us(30);
}

uchar DHT11_rec_byte()      //接收一個字節
{
   uchar i,dat=0;
  for(i=0;i<8;i++)    //從高到低依次接收8位數據
   {          
      while(!Data);   ////等待50us低電平過去
      DHT11_delay_us(8);     //延時60us,如果還為高則數據為1,否則為0 
      dat<<=1;           //移位使正確接收8位數據,數據為0時直接移位
      if(Data==1)    //數據為1時,使dat加1來接收數據1
         dat+=1;
      while(Data);  //等待數據線拉低    
    }  
    return dat;
}


//延時程序 單位ms
void delay222(unsigned int x)
{
    unsigned int i,j;

    for(i=x;i>0;i--)
        for(j=110;j>0;j--);
}


//設置溫度值
void SetTemperature(uchar value)
{

    //取出個位、十位數字
   int unitPlace = value/1%10;
   int tenPlace = value/10%10;
    
    
    P0 = led[tenPlace];
    P2 = 0x80;
    delay222(3);
    P2 = 0x00;
          
    P0 = led[unitPlace];
    P2 = 0x40;
    delay222(3);
    P2 = 0x00;
}

//設置濕度值
void SetHumidity(uchar value)
{

    //取出個位、十位數字
   int unitPlace = value/1%10;
   int tenPlace = value/10%10;
    
    
    P0 = led[tenPlace];
    P2 = 0x20;
    delay222(3);
    P2 = 0x00;
          
    P0 = led[unitPlace];
    P2 = 0x10;
    delay222(3);
    P2 = 0x00;
}
void DHT11_receive()      //接收40位的數據
{
    uchar R_H,R_L,T_H,T_L,RH,RL,TH,TL,revise; 
    int number; //閃爍頻率
    int count2;
    uchar tempValue;
    uchar  humidityValue;


    number = 20;
    count2 = 0;

    DHT11_start();



    count2 = 0;
    if(Data==0)
    {
        while(Data==0);   //等待拉高     
        DHT11_delay_us(40);  //拉高后延時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(); //接收校正位

        DHT11_delay_us(25);    //結束

        if((R_H+R_L+T_H+T_L)==revise)      //校正
        {
            RH=R_H;
            RL=R_L;
            TH=T_H;
            TL=T_L;
        }

        /*數據處理,方便顯示*/
//        rec_dat[0]='0'+(RH/10);
//        rec_dat[1]='0'+(RH%10);
//        rec_dat[2]='R';
//        rec_dat[3]='H';
//        rec_dat[4]=' ';
//        rec_dat[5]=' ';
//        rec_dat[6]='0'+(TH/10);
//        rec_dat[7]='0'+(TH%10);
//        rec_dat[8]='C';




        //讀取溫度濕度
             tempValue = RH;
             humidityValue = TH;
            
            while(count2 < number)
            {
                //設置溫度
                SetTemperature(tempValue);
                //設置濕度
                SetHumidity(humidityValue);

                count2++;
            }
    
            count2=0;

    }
}



/*這里使用lcd1602來顯示采集到的數據,lcd1602驅動程序在博主的51單片機系列博文中有詳細講解*/
void main()
{
   uchar i;   

   while(1)
   {   

       DHT11_receive();
           
   }
}

 

5.面包板調試電路和程序  

買了倆個紅色的2位共陽極數碼管10腳的,結果沒有接限流電阻,燒壞了一個,被迫又一次下單購買,結果購買錯了,買了倆個綠色的共陰極18腳的,太惡心了,焊接過得人估計能體會

6.器件部署和電路板焊接

焊接的過程中,發現還可以增加個報警指示燈。於是又焊接了倆個報警指示燈連接到了P1.0(溫度)和P1.1(濕度)

因為不會繪制pcb布線,就大概擺了一下,然后就開始焊接了。。。

 

實不相瞞,太惡心了,就因為買錯了,買了個共陰極18腳的2位數碼管。。就焊接成這樣了,水平有限大神直接飄過吧。。。。

7.成品展示

左側是溫度,右側是濕度顯示,然后因為數碼管換了,所以程序也改了,並且新增了個報警指示燈

 

因為仿真電路和我的實際成品有區別成品中的程序

  1 //****************************************************************//
  2 //大男孩溫濕度信號采集
  3 //單片機 STC89C52RC 
  4 //功能   數碼管顯示溫度和濕度   備注:晶振 11.0592M 波特率 9600 
  5 //硬件   P3.6口為通訊口連接DHT11,DHT11的電源和地連接單片機的電源和地   
  6 //****************************************************************//
  7 
  8 #include <reg51.h>
  9 #include <intrins.h> 
 10 
 11 
 12 //數據類型定義
 13 typedef unsigned char  U8;       /* defined for unsigned 8-bits integer variable       無符號8位整型變量  */
 14 typedef signed   char  S8;       /* defined for signed 8-bits integer variable          有符號8位整型變量  */
 15 typedef unsigned int   U16;      /* defined for unsigned 16-bits integer variable       無符號16位整型變量 */
 16 typedef signed   int   S16;      /* defined for signed 16-bits integer variable       有符號16位整型變量 */
 17 typedef unsigned long  U32;      /* defined for unsigned 32-bits integer variable       無符號32位整型變量 */
 18 typedef signed   long  S32;      /* defined for signed 32-bits integer variable       有符號32位整型變量 */
 19 typedef float          F32;      /* single precision floating point variable (32bits) 單精度浮點數(32位長度) */
 20 typedef double         F64;      /* double precision floating point variable (64bits) 雙精度浮點數(64位長度) */
 21 
 22 
 23 //----------------------------------------------//
 24 //----------------IO口定義區--------------------//
 25 //----------------------------------------------//
 26 sbit P3_6  = P3^6 ;     //DHT11數據針腳
 27 sbit P1_0 = P1^0;     //溫度報警針腳
 28 sbit P1_1 = P1^1;     //濕度報警針腳
 29 
 30 //----------------------------------------------//
 31 //----------------數碼管數字 0--9---------------//
 32 //----------------------------------------------//
 33 
 34 //uint led[10]={0xc0,0xf9,0xa4, 0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};  
 35 U8 led[10]={0x3F,0x06,0x5b, 0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};  
 36 
 37 //----------------------------------------------//
 38 //----------------數據存儲和數據緩存區----------//
 39 //----------------------------------------------//
 40 U8  U8FLAG;
 41 U8  U8temp;
 42 U8  U8T_data_H,U8T_data_L,U8RH_data_H,U8RH_data_L,U8checkdata;
 43 U8  U8T_data_H_temp,U8T_data_L_temp,U8RH_data_H_temp,U8RH_data_L_temp,U8checkdata_temp;
 44 U8  U8comdata;
 45   
 46 //----------------------------------------------//
 47 //----------------延時程序----------------------//
 48 //----------------------------------------------//
 49 
 50 //延時程序
 51 void Delay(U16 j)
 52 {      
 53     U8 i;
 54     for(;j>0;j--)
 55     {     
 56         for(i=0;i<27;i++);
 57 
 58     }
 59 }
 60 
 61 //延時程序10us
 62 void  Delay_10us(void)
 63 {
 64     U8 i;
 65     i--;
 66     i--;
 67     i--;
 68     i--;
 69     i--;
 70     i--;
 71 }
 72 
 73 //延時程序 單位ms
 74 void Delayms(unsigned int x1)
 75 {
 76     unsigned int i1,j1;
 77 
 78     for(i1=x1;i1>0;i1--)
 79         for(j1=110;j1>0;j1--);
 80 }
 81     
 82 
 83 
 84 //--------------------------------
 85 //-----濕度讀取子程序 ------------
 86 //--------------------------------
 87 //----以下變量均為全局變量--------
 88 //----溫度高8位== U8T_data_H------
 89 //----溫度低8位== U8T_data_L------
 90 //----濕度高8位== U8RH_data_H-----
 91 //----濕度低8位== U8RH_data_L-----
 92 //----校驗 8位 == U8checkdata-----
 93 //----調用相關子程序如下----------
 94 //---- Delay();, Delay_10us();,COM(); 
 95 //--------------------------------
 96 
 97 
 98 void COM(void)
 99 {
100      
101     U8 i;
102           
103     for(i=0;i<8;i++)       
104     {
105         
106            U8FLAG=2;    
107            while((!P3_6)&&U8FLAG++);
108         
109         Delay_10us();
110         Delay_10us();
111         Delay_10us();
112         
113         U8temp=0;
114          
115         if(P3_6)U8temp=1;
116             U8FLAG=2;
117             
118         while((P3_6)&&U8FLAG++);
119 
120            //超時則跳出for循環          
121             if(U8FLAG==1)
122              break;
123 
124            //判斷數據位是0還是1
125         // 如果高電平高過預定0高電平值則數據位為 1 
126             
127         U8comdata<<=1;
128            U8comdata|=U8temp;        //0
129     }//rof
130        
131 }
132 
133 
134 //總線數據讀取
135 void RH(void)
136 {
137        //主機拉低18ms 
138        P3_6=0;
139        Delay(180);
140 
141        //總線由上拉電阻拉高 主機延時20us
142        P3_6=1;
143        Delay_10us();
144        Delay_10us();
145        Delay_10us();
146        Delay_10us();
147 
148     //主機設為輸入 判斷從機響應信號 
149        P3_6=1;
150 
151       //判斷從機是否有低電平響應信號 如不響應則跳出,響應則向下運行     
152    if(!P3_6)         //T !      
153     {
154         U8FLAG=2;
155         //判斷從機是否發出 80us 的低電平響應信號是否結束     
156         while((!P3_6)&&U8FLAG++);
157 
158         U8FLAG=2;
159         //判斷從機是否發出 80us 的高電平,如發出則進入數據接收狀態
160         while((P3_6)&&U8FLAG++);
161 
162 
163         //數據接收狀態         
164         COM();
165         U8RH_data_H_temp=U8comdata;
166         COM();
167         U8RH_data_L_temp=U8comdata;
168         COM();
169         U8T_data_H_temp=U8comdata;
170         COM();
171         U8T_data_L_temp=U8comdata;
172         COM();
173         U8checkdata_temp=U8comdata;
174 
175         //數據讀取完后拉高總線電平
176         P3_6=1;
177 
178          //數據校驗
179         U8temp=(U8T_data_H_temp+U8T_data_L_temp+U8RH_data_H_temp+U8RH_data_L_temp);
180         if(U8temp==U8checkdata_temp)
181         {
182             U8RH_data_H=U8RH_data_H_temp;
183             U8RH_data_L=U8RH_data_L_temp;
184             U8T_data_H=U8T_data_H_temp;
185             U8T_data_L=U8T_data_L_temp;
186             U8checkdata=U8checkdata_temp;
187         }
188     }
189 
190 }
191 
192 
193 //----------------------------------------------//
194 //------------溫度濕度數碼管顯示區--------------//
195 //----------------------------------------------//
196 //設置溫度值
197 void SetTemperature(unsigned char value)
198 {
199 
200     unsigned char unitPlace, tenPlace;
201 
202     //取出個位、十位數字
203     unitPlace = value/1%10;
204     tenPlace = value/10;
205     
206     P0 = led[tenPlace];
207     P2 = 0x7f;
208     Delayms(4);
209     P2 = 0xff;
210           
211     P0 = led[unitPlace];
212     P2 = 0xbF;
213     Delayms(4);
214     P2 = 0xff;
215 }
216 
217 //設置濕度值
218 void SetHumidity(unsigned char value)
219 {
220     unsigned char unitPlace, tenPlace;
221 
222     //取出個位、十位數字
223     unitPlace = value/1%10;
224     tenPlace = value/10;
225     
226     
227     P0 = led[tenPlace];
228     P2 = 0xDF;
229     Delayms(4);
230     P2 = 0xFF;
231           
232     P0 = led[unitPlace];
233     P2 = 0xEF;
234     Delayms(4);
235     P2 = 0xFF;
236 }
237 
238 
239 //----------------------------------------------//
240 //-----系統初始化點亮報警燈和顯示數碼管---------//
241 //-----點亮報警燈,顯示數碼管88------------------//
242 //----------------------------------------------//
243 //系統初始化
244 void Init(void)
245 {
246     U8 number = 100; //閃爍頻率
247     U8 count = 0;      //計數
248 
249     P1_0 = 0;
250     P1_1 = 0;
251 
252     while(count < number)
253     {
254         //設置溫度
255         SetTemperature(88);
256         //設置濕度
257         SetHumidity(88);
258 
259         count++;
260     }
261 
262     Delayms(500);
263 
264     P1_0 = 1;
265     P1_1 = 1;
266 
267 }
268 
269     
270 //----------------------------------------------//
271 //----------溫度濕度讀取和顯示控制--------------//
272 //----------------------------------------------//
273 void main()
274 {
275 
276     //報警值區域
277     U8 tempAlarmMin = 20;
278     U8 tempALarmMax = 32;
279     U8 HumidityMin = 45;
280     U8 HumidityMax = 65;
281     
282     //顯示循環次數
283     U8 number = 250; 
284     U8 count = 0;      
285 
286     //系統初始化
287     Init();
288     
289     while(1)
290     { 
291            count =0;
292 
293            //調用溫濕度讀取子程序 
294            RH();
295 
296            
297            if(U8T_data_H > tempALarmMax || U8T_data_H < tempAlarmMin)
298            {
299                 P1_0 = 0;
300            }
301            else
302            {
303                P1_0 = 1;
304            }
305 
306         if(U8RH_data_H < HumidityMin || U8RH_data_H > HumidityMax)
307         {
308             P1_1 = 0;
309         }
310         else
311         {
312             P1_1 = 1;
313         }
314         
315        //讀取模塊數據周期不易小於 2S 所以這里循環顯示2s后讀取      
316        while(count < number)
317        {
318             //設置溫度
319             SetTemperature(U8T_data_H);
320             //設置濕度
321             SetHumidity(U8RH_data_H);
322 
323             count++;
324        }
325        
326 
327     }
328     
329 }
View Code

電路大概介紹

 硬件程序優化版

程序源代碼下載


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM