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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

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

單片機+DHT11+1602顯示程序Proteus仿真 有詳細注釋 藍牙串口傳輸

[復制鏈接]
跳轉到指定樓層
樓主
基于51單片機的溫濕度檢測設計,有藍牙向手機傳輸功能
仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)


電路原理圖如下:


注釋很詳細的單片機源程序如下:
  1. #include<reg52.h> //包含頭文件,一般情況不需要改動,頭文件包含特殊功能寄存器的定義
  2. #include<intrins.h>

  3. #define uchar unsigned char
  4. #define uint unsigned int
  5. #define lcddata  P0    //數據端口;

  6. sbit io=P1^0;           //dht11data端接單片機的P1^0口//

  7. sbit SPK =P1^1;         //蜂鳴器;
  8. sbit LED =P1^2;         //報警燈 ;
  9. sbit JDQ_WenDu =P1^3;   // 控制風扇的繼電器;
  10. sbit JDQ_ShiDu =P1^4;   // 控制風扇的繼電器;

  11. sbit K1=P3^2;       //手動/自動復位功能;
  12. sbit K2=P3^3;       //頁面選擇;
  13. sbit K3=P3^4;       //修改min,按鍵加1;
  14. sbit K4=P3^5;       //修改max,按鍵加1;

  15. sbit RS = P2^0;     //Pin4     數據命令選擇;  高電平時為數據寄存器,低電平是為選擇指令寄存器;
  16. sbit RW = P2^1;     //Pin5     讀寫模式選擇;
  17. sbit E  = P2^2;     //Pin6     使能信號;

  18. bit di=1;
  19. bit flag_300ms ;

  20. unsigned char s[3]={0,0,'\0'};              //只讀取兩個字節,讀到第三個結束;
  21. unsigned char table[]={0,1,2,3,4,5,6,7,8,9};                                                                                                                        

  22. unsigned int j=40,i=0,sum=0;
  23. int tempeature;         //整型變量  tempeature:溫度
  24. uchar yemian=0;         //(定義變量)
  25. uchar flat=1;
  26. unsigned char WenDu=20,ShiDu=40;//報警的溫度和濕度

  27. typedef bit BOOL;  //此聲明一個布爾型變量即真或假//
  28. uchar data_byte;
  29. uchar RH,RL,TH,TL;

  30. void receive();                   //接收數據//
  31. /******************************************************************/
  32. void DelayUs(unsigned char us)//delay us
  33. {
  34.                  unsigned char uscnt;
  35.                  uscnt=us>>1;        /*12MHz頻率*/
  36.                  while(--uscnt);
  37. }
  38. /******************************************************************/
  39. /*                    毫秒函數聲明                                */
  40. /******************************************************************/
  41. void DelayMs(unsigned int ms)
  42. {
  43. while(--ms)
  44.          {
  45.                  DelayUs(250);
  46.                  DelayUs(250);
  47.                  DelayUs(250);
  48.                  DelayUs(250);
  49.          }
  50. }

  51. //***************延時函數*************************************
  52. void delay(uchar ms) //延時模塊//
  53. {
  54.                 uchar i;
  55.                 while(ms--)               
  56.                 for(i=0;i<100;i++);
  57. }
  58. void delay1()  //一個for循環大概需要8個多機器周期 一個機器周期為1us 晶振為12MHz  也就是說本函數延時8us多 此延時函數必須德稍微精確一點
  59. {
  60.                 uchar i;
  61.                 for(i=0;i<1;i++);
  62. }
  63. //  對液晶經行寫指令;
  64. void wr_i_lcd(uchar content)
  65. {
  66.                  DelayMs(5);//操作前短暫延時,保證信號穩定
  67.                  E=0;          //E端的由高電平跳變成低電平時,液晶模塊執行命令;  此處位E端清零操作
  68.                  RS=0;     
  69.                  RW=0;         
  70.                  E=1;
  71.                  lcddata=content;
  72.                  E=0;
  73. }

  74. //    液晶初始化,清除顯示,歸為地址;
  75. void  lcd_csh()
  76. {
  77. //        wr_i_lcd(0x01);     //清除顯示;
  78. //        wr_i_lcd(0x30);     //地址歸位;    30H:設定8位控制界面;
  79. //                            //             00H:基本指令集;
  80. //                            //             34H:設定擴展指令集;
  81. //        wr_i_lcd(0x0c);     //開顯示,無光標,光標不閃爍;   0x0e:開顯示,有光標,光標不閃爍;  0x0f:開顯示,有光標,光標閃爍;
  82. //        wr_i_lcd(0x10);     //光標向左移;
  83. //  wr_i_lcd(0x06);    /*光標的移動方向   */
  84.         
  85.                 DelayMs(15);
  86.                 wr_i_lcd(0x38);
  87.                 DelayMs(5);
  88.                 wr_i_lcd(0x38);
  89.                 DelayMs(5);
  90.                 wr_i_lcd(0x38);
  91.                 DelayMs(5);
  92.                 wr_i_lcd(0x0c);
  93.                 DelayMs(5);
  94.                 wr_i_lcd(0x06);
  95.                 DelayMs(5);
  96.                 wr_i_lcd(0x01);
  97.                 DelayMs(5);        
  98. }

  99. //  對液晶進行寫數據;
  100. void wr_d_lcd(uchar content)
  101. {        
  102.          DelayMs(5);  //操作前短暫延時,保證信號穩定
  103.          E=0;
  104.          RS=1;
  105.          RW=0;
  106.          E=1;
  107.          lcddata=content;
  108.          E=0;
  109.          RS=0;
  110. }

  111. //   顯示坐標位置的函數;
  112. void  gotoxy(uchar y,uchar x)
  113. {
  114.          if(y==1)             //第一行第一列;
  115.                 wr_i_lcd(0x80|x);   //對液晶經行寫指令;
  116.          
  117.          if(y==2)             //第二行第一列;
  118.                 wr_i_lcd(0xc0|x);   //對液晶經行寫指令;
  119. }

  120. //   printf輸入字符串操作;
  121. void printf(uchar *str)
  122. {
  123.         while(*str!='\0')
  124.         {
  125.                 wr_d_lcd(*str);
  126.                 str++;
  127.         }
  128. }

  129. // 液晶顯示主程序操作;  初始顯示welcome
  130. void  show()
  131. {
  132.                 gotoxy(1,4);
  133.                 printf("welcome");        
  134. }


  135. void shezhi()  //對里面的數值進行修改
  136. {
  137.     if(!K3)    //溫濕度數據大小加++;
  138.                 {  
  139.                             DelayMs(50);
  140.                             if(!K3)
  141.                       {   
  142.               while(K3==0);        
  143.                                                         if(yemian==1)
  144.                                                         {               
  145.                                                                  WenDu+=1;
  146.                                                                   if(WenDu>99) { WenDu=99; }  //溫度上限加
  147.                                                         
  148.                                                          }
  149.                                                          if(yemian==2)
  150.                                                          {
  151.                                                       ShiDu+=1;
  152.                                                                   if(ShiDu>99) { ShiDu=99; }  //濕度下限加
  153.                                                                 }         
  154.                                    }
  155.                  }                 
  156.                 if(!K4)
  157.                 {  
  158.                          DelayMs(50);
  159.                          if(!K4)
  160.                                  {   
  161.                                            while(K4==0);     //按一次,防止按下不松,加多次
  162.                                                  if(yemian==1)
  163.                                                          {
  164.                                                         if(WenDu<1) {WenDu=1; }        
  165.                                                                      WenDu-=1;          //濕度下限減                                                   
  166.                                                          }                                 
  167.                                                  if(yemian==2)
  168.                                                          {
  169.                                                                     if(ShiDu<1) { ShiDu=1; }
  170.                                                                     ShiDu-=1;         //濕度下限減               
  171.                                                          }        
  172.                                  }
  173.                  }
  174. }                        

  175. // 中斷初始化
  176. void Int()
  177. {
  178.                         EA=1;
  179.                         EX0=1;
  180.                         IT0=1;
  181.         
  182.                         PX0=1;     //(中斷0為最高優先級)
  183.         
  184.                         EX1=1;
  185.                         IT1=1;
  186. }

  187. //   報警部分
  188. void warn()
  189. {
  190.          
  191. //         if((ShiDu>RH)||(WenDu<TH))
  192. //                {
  193. //                           SPK=1;
  194. //                     LED=1;
  195. //                }
  196. //                else
  197. //                {
  198. //                           SPK=0;        
  199. //                           LED=0;
  200. //                }        
  201.                
  202.           if(ShiDu<RH)
  203.                 {
  204.                         JDQ_ShiDu =1;     // 控制加濕器的繼電器;
  205.                         SPK=1;
  206.             LED=1;
  207.                 }
  208.                 else
  209.                 {
  210.                         JDQ_ShiDu =0;     // 控制加濕器的繼電器;
  211.                         SPK=0;
  212.                         LED=0;
  213.                 }
  214.                
  215.           DelayMs(200);
  216.           if(WenDu>TH)        //WenDu為設定值,TH測量值;
  217.                 {
  218.                         SPK=1;
  219.                         LED=1;
  220.                         JDQ_WenDu =1;     // 控制風扇的繼電器;
  221.                 }
  222.                 else
  223.                 {
  224.                         SPK=0;
  225.                         LED=0;
  226.                         JDQ_WenDu =0;     // 控制風扇的繼電器;
  227.                 }
  228.                
  229. }
  230. /***************************選擇界面工作狀態*********************************/
  231. void  Xuanze()
  232. {
  233. //                  key();
  234. //====================yemian==0時 進入工作狀態=================================
  235.                          if(yemian==0)  
  236.                         {
  237.                                 if(flat==1)
  238.                                  {
  239.            flat=0;
  240.                                          lcd_csh(); //初始化
  241.                                          
  242.                                           gotoxy(1,0);
  243.                                                 printf("Temp:00");
  244.                                          
  245.                                           gotoxy(1,8);
  246.                                                 s[0]=0xdf;   //由一個字符串轉化為一個字符;
  247.                         s[1]=0x43;        
  248.                               printf(s);               
  249.                                          
  250.                                           gotoxy(2,0);
  251.                                                 printf("Humi:00");
  252.                                                                   
  253.                                           gotoxy(2,7);
  254.                                                 printf("%RH");
  255.                                                                  
  256.                                           gotoxy(1,12);
  257.                                           printf("T:");
  258.                                                 
  259.                   s[0]=WenDu/10+0x30;   //由一個字符串轉化為一個字符;
  260.                                     s[1]=WenDu%10+0x30;        
  261.                                                 printf(s);
  262. //          display(0x0e,WenDu/10+0x30);  //報警溫度
  263. //                      display(0x0f,WenDu%10+0x30);
  264.                                    
  265.                                           gotoxy(2,12);
  266.                                           printf("H:");

  267.             s[0]=ShiDu/10+0x30;   //由一個字符串轉化為一個字符;
  268.                                     s[1]=ShiDu%10+0x30;        
  269.                                                 printf(s);
  270. //                                  display(0x4e,ShiDu/10+0x30);  //報警濕度
  271. //                      display(0x4f,ShiDu%10+0x30);
  272.                                          
  273.           }
  274. // ***********DHT11讀取顯示部分************                                 
  275.                                   receive();
  276.                                         gotoxy(1,5);
  277.                                         s[0]=TH/10+0x30;   //由一個字符串轉化為一個字符;
  278.                                         s[1]=TH%10+0x30;        
  279.                                         printf(s);
  280.                                                 
  281.                                         gotoxy(2,5);
  282.                                         s[0]=RH/10+0x30;   //由一個字符串轉化為一個字符;
  283.                                         s[1]=RH%10+0x30;        
  284.                       printf(s);                        
  285.              }

  286. //====================yemian==1 溫度設置===========================
  287.                    if(yemian==1)  //溫度
  288.                             {
  289.                          if(flat==1)
  290.                                      {
  291.                flat=0;  
  292.                                                          lcd_csh(); //初始化
  293. //                                                          bee=1;
  294.                                                          gotoxy(1,0);
  295.                                                    printf("Temp max:");
  296.              }                                                
  297.                                                 shezhi();
  298.                                                 gotoxy(2,7);
  299.                                                 s[0]=WenDu/10+0x30;   //由一個字符串轉化為一個字符;
  300.                                     s[1]=WenDu%10+0x30;        
  301.                                                 printf(s);
  302.                                                 
  303.                                                  SPK=1;
  304.                    LED=1;
  305.                       }               
  306. //====================yemian==1濕度設置==========================        
  307.                                 if(yemian==2)   //濕度設置
  308.                             {
  309.                          if(flat==1)
  310.                                      {
  311.                flat=0;  
  312. //                                                          bee=1;
  313.                lcd_csh(); //初始化
  314.                                                          gotoxy(1,0);
  315.                                                    printf("Humi min:");
  316.                                                  }
  317.                                                 shezhi();
  318.                                                 gotoxy(2,7);
  319.                                                 s[0]=ShiDu/10+0x30;   //由一個字符串轉化為一個字符;
  320.                                     s[1]=ShiDu%10+0x30;        
  321.                                                 printf(s);
  322.                                                 
  323.                                                  SPK=1;
  324.                    LED=1;
  325.                       }
  326. }

  327. //**************************dht11測試某塊*************************************//
  328. void start()           //開始信號
  329. {
  330.                 io=1;
  331.                 delay1();
  332.                 io=0;
  333.                 delay(30);          // 主機把總線拉低必須大于18ms 保證DHT11能檢測到起始信號
  334.                 io=1;               //發送開始信號結束后 拉高電平延時20-40us
  335.         
  336.                 delay1();           //以下三個延時函數差不多為24us 符合要求
  337.                 delay1();
  338.                 delay1();
  339.         
  340.                 delay1();
  341.                 delay1();
  342. }
  343. uchar receive_byte()             //接收一個字節//
  344. {
  345.                 uchar i,temp;
  346.                 for(i=0;i<8;i++)    //接收8bit的數據
  347.                 {
  348.                                 while(!io);     //等待50us的低電平開始信號結束
  349.                                 delay1();       //開始信號結束之后 延時26us-28us 以下三個延時函數
  350.                                 delay1();
  351.                                 delay1();
  352.                                 temp=0;         //時間為26us-28us 表示接收的為數據'0'
  353.                                 if(io==1)
  354.                                 temp=1;         //如果26us-28us之后 還為高電平 則表示接收的數據為'1'
  355.                                 while(io);      //等待數據信號高電平 '0'為26us-28us '1'為70us
  356.                                 data_byte<<=1;  //接收的數據為高位在前 右移
  357.                                 data_byte|=temp;
  358.                 }
  359.                 return data_byte;
  360. }
  361. void receive()                   //接收數據//
  362. {
  363.                         uchar T_H,T_L,R_H,R_L,check,num_check,i;
  364.                         start();                   //開始信號//
  365.                         io=1;                      //主機設為輸入 判斷從機 DHT11 響應信號
  366.                         if(!io)                    //判斷從機是否有低電平響應信號//
  367.                         {
  368.                                         while(!io);                 //判斷從機發出 80us 的低電平響應信號是否結束//
  369.                                         while(io);                  //判斷從機發出 80us 的高電平是否結束 如結束則主機進入數據接收狀態
  370.                                         R_H=receive_byte();         //濕度高位
  371.                                         R_L=receive_byte();         //濕度低位
  372.                                         T_H=receive_byte();         //溫度高位
  373.                                         T_L=receive_byte();         //溫度低位
  374.                                         check=receive_byte();       //校驗位
  375.                                         io=0;                       //當最后一bit數據接完畢后 從機拉低電平50us//
  376.                                         for(i=0;i<7;i++)            //差不多50us的延時
  377.                                         delay1();
  378.                                         io=1;                        //總線由上拉電阻拉高 進入空閑狀態
  379.                                         num_check=R_H+R_L+T_H+T_L;
  380.                                         if(num_check==check)          //判斷讀到的四個數據之和是否與校驗位相同
  381.                                         {
  382.                                                         RH=R_H;
  383.                                                         RL=R_L;
  384.                                                         TH=T_H;
  385.                                                         TL=T_L;
  386.                                                         check=num_check;
  387.                                         }
  388.                 }
  389. }
  390. /*************************串口初始化*********************************/
  391. void UsartConfiguration()
  392. {
  393.                 SCON=0x50;        //設置位方式1; REN=1(接收允許)
  394.                 TMOD=0x20;        //計數器工作方式2;  計數器T1
  395.                 PCON=0x00;        //SMOD=0;
  396.                 TH1=0xfd;         //波特率位9600bit/s;
  397.                 TL1=0xfd;
  398.                 TR1=1;                  //打開計數器;
  399.                 ES=1;             //打開接收中斷;
  400.                 EA=1;             //打開總中斷;
  401. }
  402. /***************************主程序*********************************/
  403. void main()
  404. {
  405.           SPK=1;
  406.             LED=1;
  407.         Int();                    //中斷初始化;
  408.         lcd_csh();                //LCD1602初始化;
  409.         UsartConfiguration();     //串口初始化;
  410.         show();
  411.         DelayMs(1000);    //3s以后,進入主程序部分,初始化部分結束;
  412.         while(1)
  413.         {  
  414.                
  415.                         RI=1;
  416.                   Xuanze();
  417.                   DelayMs(200);
  418.                   if(yemian==0)  {  warn(); }
  419.         }
  420. }

  421. /*********************頁面選擇*****************************/
  422. void int0(void) interrupt 0  //
  423. {
  424.         
  425.          if(!K1)    //頁面選擇;
  426.           {  
  427.                    DelayMs(20);    //程序消抖;
  428.                         if(!K1)      
  429.                         {   
  430.                                 yemian++;
  431.                                 flat++;
  432.                                 while(!K1);
  433.                                 if(yemian>=3)                  {  yemian=0;  }
  434.                   }
  435.           }
  436. }
  437. //************手機APP發送端*************
  438. void uart() interrupt 4
  439. {
  440.         
  441. //************發送濕度部分***************************        
  442.                         RI=0;             //                                             //清除收到中斷標志位;
  443.                         SBUF=RH/10+0x30;                             //將接收到的數據放回發送緩存器;
  444.                         while(!TI);                                               //等待發送數據完成;
  445.                   TI=0;                                                                                                 //清除發送中斷標志位;  
  446.                         
  447.                         RI=0;                                                            //清除收到中斷標志位;
  448.                         SBUF=RH%10+0x30;                              //將接收到的數據放回發送緩存器;
  449.                         while(!TI);                                               //等待發送數據完成;
  450.                   TI=0;                                                                //清除發送中斷標志位;

  451.             RI=0;             //  %                                         //清除收到中斷標志位;
  452.                         SBUF=37;                             //將接收到的數據放回發送緩存器;
  453.                         while(!TI);                                               //等待發送數據完成;
  454.                   TI=0;                                                                                                 //清除發送中斷標志位;  
  455.                         
  456.                         RI=0;             //  R                                          //清除收到中斷標志位;
  457.                         SBUF=82;                              //將接收到的數據放回發送緩存器;
  458.                         while(!TI);                                               //等待發送數據完成;
  459.                   TI=0;                                          
  460.                  
  461.                         RI=0;             //  H                                           //清除收到中斷標志位;
  462.                         SBUF=72;                             //將接收到的數據放回發送緩存器;
  463.                         while(!TI);                                               //等待發送數據完成;
  464.                   TI=0;                                                                                                 //清除發送中斷標志位;  
  465.                         
  466.                 for(i=0;i<10;i++)
  467.                 {
  468.                         RI=0;             //空格                                              //清除收到中斷標志位;
  469.                         SBUF=32;                              //將接收到的數據放回發送緩存器;
  470.                         while(!TI);                                               //等待發送數據完成;
  471.                   TI=0;                  
  472.                 }        
  473. //************發送溫度部分***************************               
  474.             RI=0;             //                                             //清除收到中斷標志位;
  475.                         SBUF=TH/10+0x30;                             //將接收到的數據放回發送緩存器;
  476.                         while(!TI);                                               //等待發送數據完成;
  477.                   TI=0;                                                                       //清除發送中斷標志位;  
  478.                         
  479.                         RI=0;                                                            //清除收到中斷標志位;
  480.                         SBUF=TH%10+0x30;                              //將接收到的數據放回發送緩存器;
  481.                         while(!TI);                                               //等待發送數據完成;
  482.                   TI=0;                  
  483.                                                                                    //清除發送中斷標志位;         
  484.             RI=0;                                                            //清除收到中斷標志位;
  485.                         SBUF=96;                                     //將接收到的數據放回發送緩存器;
  486.                         while(!TI);                                               //等待發送數據完成;
  487.                   TI=0;                                                                                                 //清除發送中斷標志位;  
  488.         
  489.             RI=0;                                         //清除收到中斷標志位;
  490.                         SBUF=67;                               //將接收到的數據放回發送緩存器;
  491.                         while(!TI);                                         //等待發送數據完成;
  492.                   TI=0;                                              //清除發送中斷標志位;  

  493.             SBUF=10;  // (換行)     
  494.                   while(!TI);                                        //等待發送數據完成;
  495.                         TI=0;                                                          //清除發送中斷標志位;
  496.         
  497. }
復制代碼

所有資料51hei提供下載:
無限溫濕度檢測f(仿真).zip (25.01 KB, 下載次數: 125)
溫濕度測量程序.zip (48.43 KB, 下載次數: 130)


評分

參與人數 1黑幣 +50 收起 理由
admin + 50 共享資料的黑幣獎勵!

查看全部評分

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

使用道具 舉報

沙發
ID:807430 發表于 2021-5-19 15:32 | 只看該作者
分享資料,功德無量!!!
回復

使用道具 舉報

板凳
ID:922803 發表于 2021-6-7 11:09 | 只看該作者
蜂鳴器一直會響是咋回事
回復

使用道具 舉報

地板
ID:922803 發表于 2021-6-9 11:01 | 只看該作者
老干爹 發表于 2021-6-7 11:09
蜂鳴器一直會響是咋回事

你可能是傳感器所處環境溫度高于設定值或者濕度低于設定值了程序給的溫度是20  濕度40這個你可以自己更換
回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 免费视频成人国产精品网站 | 日本人和亚洲人zjzjhd | 久久毛片| 久久精品一区二区视频 | 午夜影院黄 | 999精彩视频 | 久久精品视频免费观看 | 99热首页| 中文字幕亚洲国产 | 久久99精品久久久水蜜桃 | 在线成人免费视频 | 色婷婷综合久久久中字幕精品久久 | 日韩精品一区二区三区视频播放 | 午夜精品在线观看 | 在线观看中文字幕av | 久久最新 | 狠狠av| 免费av在线 | 久久首页 | 国产亚洲一区二区三区在线 | 久久草在线视频 | 精品一区视频 | 亚洲欧美国产一区二区三区 | 日日日色 | 九九热精品视频 | 中文天堂在线一区 | 久久午夜国产精品www忘忧草 | 性高湖久久久久久久久3小时 | 一区二区三区视频免费观看 | 久久高清免费视频 | 男女羞羞免费网站 | 先锋资源吧 | 日韩精品一区二区三区中文在线 | 久久影音先锋 | 亚洲精品中文在线观看 | 日韩精品在线看 | 中文字幕 欧美 日韩 | 国产一区二区不卡 | 国产精品精品视频一区二区三区 | 激情五月婷婷丁香 | 国产成人精品久久二区二区91 |