找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

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

4個繼電器的DTH11溫濕度控制器 單片機程序與Proteus仿真

  [復(fù)制鏈接]
ID:835138 發(fā)表于 2021-3-8 15:39 | 顯示全部樓層 |閱讀模式
根據(jù)DTH11傳感器來記錄溫濕度數(shù)據(jù),并以此來控制4個不同的繼電器,達到控制不同負載來調(diào)節(jié)溫濕度的目的

仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)
截圖_20213708033704.png

制作出來的實物圖如下:
負載全加.jpg DSC_3745.JPG DSC_3747.JPG

單片機源程序如下:
  1. #include <reg52.h>
  2. #include <intrins.h>
  3. #include <absacc.h>
  4. #include <math.h>                           //包含頭文件
  5.   
  6. #define uchar unsigned char
  7. #define uint unsigned int           //宏定義

  8. //定義四個輸出端口
  9. sbit Led_jiashi=P3^6;                //加濕
  10. sbit Led_qushi=P3^4;                //去濕
  11. sbit Led_jiangwen=P3^2;                //降溫
  12. sbit Led_shengwen=P3^3;                //升溫
  13. //定義三個設(shè)置按鍵
  14. sbit Key_SET = P2^0;                //設(shè)置按鍵
  15. sbit Key_ADD = P2^1;                //加按鍵
  16. sbit Key_SUB = P2^2;                //減按鍵
  17. sbit Key_OK  = P2^3;                //確定按鍵
  18. //定義24C02數(shù)據(jù)口
  19. sbit SCL = P1^0;
  20. sbit SDA = P1^1;
  21. //定義DHT11數(shù)據(jù)口
  22. sbit DATA = P1^7;
  23. sbit buzz=P3^5;                                //蜂鳴器接口

  24. //定義LCD1602端口
  25. sbit E=P1^3;                //1602使能引腳
  26. //sbit RW=P2^6;                //1602讀寫引腳         我們只需要向液晶里寫數(shù)據(jù),不需要讀取數(shù)據(jù),所以就把讀寫引腳直接接地,程序里就不用單獨控制了
  27. sbit RS=P1^2;                //1602數(shù)據(jù)/命令選擇引腳
  28. //定義全局變量
  29. uchar U8FLAG,U8temp,U8comdata,U8RH_data_H_temp,U8RH_data_L_temp,U8T_data_H_temp,U8T_data_L_temp,U8checkdata_temp;        //定義讀取溫濕度變量
  30. uchar U8RH_data_H,U8RH_data_L,U8T_data_H,U8T_data_L,U8checkdata;
  31. uchar Mode,humidity,temperature;                                                                                                                                                                        //設(shè)置模式、讀取到的濕度溫度數(shù)據(jù)存儲變量
  32. char TH,TL,HH,HL;                                                                                                                                                                                                        //溫濕度的上下限變量
  33. bit bdata FlagStartRH,hot,cold,humid,dry,BJ;                                                                                                                                                //開啟轉(zhuǎn)換溫濕度標志位、熱冷濕干和報警變量

  34. //定時器0初始化
  35. void Timer0_Init()
  36. {
  37.         ET0 = 1;        //允許定時器0中斷
  38.         TMOD = 0x11;       //定時器工作方式選擇
  39.         TL0 = 0xb0;     
  40.         TH0 = 0x3c;     //定時器賦予初值50ms
  41.         TR0 = 1;        //啟動定時器T0
  42. }

  43. //定時器0中斷
  44. void Timer0_ISR (void) interrupt 1 using 0
  45. {
  46.         uchar RHCounter;                                 //定義計數(shù)變量
  47.         TL0 = 0xb0;
  48.         TH0 = 0x3c;     //定時器賦予初值
  49.         RHCounter++;                                         //每進一次中斷就是50ms,此變量加一
  50.         if(RHCounter%10==0&&BJ==1)                 //加到10的整數(shù)倍,并且報警標志位為1
  51.         buzz=!buzz;                                                 //開啟報警,每500ms蜂鳴器引腳取反一次,就是蜂鳴器一秒響一次
  52.         else if(BJ==0)                                         //報警標志位為0時
  53.         buzz=1;                                                         //關(guān)閉報警
  54.         //每2秒鐘啟動一次溫濕度轉(zhuǎn)換
  55.     if (RHCounter >= 40)                         //計數(shù)到40次,就是2s,啟動一次溫濕度轉(zhuǎn)換
  56.     {
  57.        FlagStartRH = 1;                                 //啟動轉(zhuǎn)換變量置1
  58.            RHCounter = 0;                                 //計數(shù)變量清零
  59.     }
  60. }

  61. /*以下程序為24c02的程序,都是官方的實例程序,可以參考時序圖理解,都是固定的*/

  62. /*********************************
  63.       BASE  DRIVE
  64. **********************************/
  65. void DELAY(unsigned int t)                          //延時函數(shù)
  66. {
  67.         while(t!=0)
  68.         t--;
  69. }

  70. /******************************
  71.       IIC  DRIVE
  72. ******************************/
  73. void IICStart(void)                                         //24c02的開始函數(shù),關(guān)于24c02的函數(shù)多看下24c02的手冊
  74. {
  75.      SCL=0;                                                   //SCL引腳拉低
  76.           DELAY(1);                                                 //短延時
  77.      SDA=1; SCL=1; DELAY(1);                 //SDA拉高,SCL拉高,短延時
  78.      SDA=0; DELAY(1);                                 //SDA拉低,短延時
  79.      SCL=0;                                                  //SCL拉低
  80. }

  81. void IICStop(void)                                         //停止
  82. {
  83.          SDA=0;SCL=1; DELAY(1);                         //注釋略
  84.      SDA=1; DELAY(1);
  85.      SCL=0;         
  86. }
  87. void SEND0(void)                                         //發(fā)送
  88. {
  89.         SDA=0;
  90.         SCL=1;
  91.         DELAY(1);
  92.         SCL=0;
  93. }

  94. void SEND1(void)
  95. {
  96.         SDA=1;
  97.         DELAY(1);
  98.         SCL=1;
  99.         DELAY(1);
  100.         SCL=0;
  101. }

  102. bit Check_Ack(void)                                                //應(yīng)答
  103. {
  104.         unsigned char errtime=250;                        //定義變量
  105.         DELAY(1);                                                
  106.         SCL=1;
  107.         DELAY(1);
  108.         CY=SDA;                                                                //SDA引腳高電平就是1,低電平就是0,賦值給CY
  109.         while(CY)                                                        //如果CY為1,就執(zhí)行此while
  110.         {
  111.                 errtime--;                                                 //變量減
  112.                 CY=SDA;                                                        //賦值
  113.                 if (!errtime)                                        //判斷有沒有減到0
  114.                 {
  115.                         IICStop();                                        //停止24C02
  116.                         return 1;                                        //返回1
  117.                 }
  118.         }
  119.         DELAY(1);
  120.         SCL=0;
  121.         return 0;
  122. }

  123. void Write_byte(unsigned char dat)
  124. {
  125.     unsigned char i;
  126.         for(i=0;i<8;i++)
  127.         {        
  128.                 if((dat<<i)&0x80)
  129.                 SEND1();
  130.                 else
  131.                 SEND0();
  132.         }
  133. }

  134. unsigned char Read_byte(void)
  135. {
  136.         unsigned char i,temp=0;     
  137.         for(i=0;i<8;i++)
  138.         {
  139.         SDA=1;
  140.             SCL=1;
  141.             DELAY(1);  
  142.                 if(SDA==1)
  143.                 {
  144.                         temp=temp<<1;
  145.                         temp=temp|0x01;
  146.                 }
  147.                 else
  148.                 temp=temp<<1;
  149.                  SCL=0;        
  150.           }
  151.           return temp;
  152. }

  153. /************************************
  154.       EEPROM  DRIVE
  155.           Addr:from 0x00-->
  156. *************************************/
  157. unsigned char rdeeprom(unsigned char addr)
  158. {
  159.         unsigned char temp=0;
  160.                 bit flag=0;
  161.                 IICStart();
  162.                 Write_byte(0xa0);
  163.         Check_Ack();
  164.                 Write_byte(addr);
  165.                 Check_Ack();
  166.                 IICStart();
  167.                 Write_byte(0xa1);
  168.                 Check_Ack();
  169.                 temp=Read_byte();
  170.                 SEND1();
  171.                 IICStop();
  172.              return temp;   
  173. }  
  174.    
  175.    
  176. void wrteeprom(unsigned char addr,unsigned char dat)
  177. {
  178.                IICStart();
  179.                 Write_byte(0xa0);
  180.                 Check_Ack();
  181.                 Write_byte(addr);
  182.                 Check_Ack();
  183.                 Write_byte(dat);
  184.                 Check_Ack();
  185.                 IICStop();
  186. }

  187. /*以下程序為DHT11溫濕度傳感器程序,官方的實例程序*/


  188. void Delay1(uint j)                        //延時程序
  189. {
  190.     uchar i;
  191.     for(;j>0;j--)
  192.     {         
  193.                 for(i=0;i<27;i++);
  194.     }
  195. }

  196. void  Delay_10us(void)                  //延時函數(shù),大約10us,不精確
  197. {
  198.     uchar i;
  199.     i--;
  200.     i--;
  201.     i--;
  202.     i--;
  203.     i--;
  204.     i--;
  205. }        

  206. void  COM(void)                                                                         //讀取溫濕度函數(shù)
  207. {
  208.     uchar i;
  209.     for(i=0;i<8;i++)           
  210.     {
  211.               U8FLAG=2;
  212.                    while((!DATA)&&U8FLAG++);
  213.                 Delay_10us();
  214.                 Delay_10us();
  215.                 Delay_10us();
  216.                   U8temp=0;
  217.         if(DATA)U8temp=1;
  218.                     U8FLAG=2;
  219.                 while((DATA)&&U8FLAG++);
  220.                    //超時則跳出for循環(huán)                  
  221.                    if(U8FLAG==1)break;
  222.                    //判斷數(shù)據(jù)位是0還是1         
  223.                      
  224.                 // 如果高電平高過預(yù)定0高電平值則數(shù)據(jù)位為 1
  225.                     
  226.                 U8comdata<<=1;
  227.                    U8comdata|=U8temp;        //0
  228.     }//rof
  229. }

  230. //--------------------------------
  231. //-----溫濕度讀取子程序 ------------
  232. //--------------------------------
  233. //----以下變量均為全局變量--------
  234. //----溫度高8位== U8T_data_H------
  235. //----溫度低8位== U8T_data_L------
  236. //----濕度高8位== U8RH_data_H-----
  237. //----濕度低8位== U8RH_data_L-----
  238. //----校驗 8位 == U8checkdata-----
  239. //----調(diào)用相關(guān)子程序如下----------
  240. //---- Delay();, Delay_10us();,COM();
  241. //--------------------------------
  242. uchar RH(void)
  243. {
  244.     //主機拉低18ms
  245.     DATA=0;
  246.         Delay1(180);  //原來為5
  247.         DATA=1;
  248.         //總線由上拉電阻拉高 主機延時20us
  249.         Delay_10us();
  250.         Delay_10us();
  251.         Delay_10us();
  252.         Delay_10us();
  253.         //主機設(shè)為輸入 判斷從機響應(yīng)信號
  254.         DATA=1;
  255.         //判斷從機是否有低電平響應(yīng)信號 如不響應(yīng)則跳出,響應(yīng)則向下運行         
  256.         if(!DATA)                 //T !         
  257.         {
  258.             U8FLAG=2;
  259.             //判斷從機是否發(fā)出 80us 的低電平響應(yīng)信號是否結(jié)束         
  260.             while((!DATA)&&U8FLAG++);
  261.             U8FLAG=2;
  262.             //判斷從機是否發(fā)出 80us 的高電平,如發(fā)出則進入數(shù)據(jù)接收狀態(tài)
  263.             while((DATA)&&U8FLAG++);
  264.             //數(shù)據(jù)接收狀態(tài)                 
  265.             COM();
  266.             U8RH_data_H_temp=U8comdata;
  267.             COM();
  268.             U8RH_data_L_temp=U8comdata;
  269.             COM();
  270.             U8T_data_H_temp=U8comdata;
  271.             COM();
  272.             U8T_data_L_temp=U8comdata;
  273.             COM();
  274.             U8checkdata_temp=U8comdata;
  275.             DATA=1;
  276.             //數(shù)據(jù)校驗
  277.             U8temp=(U8T_data_H_temp+U8T_data_L_temp+U8RH_data_H_temp+U8RH_data_L_temp);
  278.             if(U8temp==U8checkdata_temp)
  279.             {
  280.                       U8RH_data_H=U8RH_data_H_temp;
  281.                       U8RH_data_L=U8RH_data_L_temp;
  282.                       U8T_data_H=U8T_data_H_temp;
  283.                       U8T_data_L=U8T_data_L_temp;
  284.                       U8checkdata=U8checkdata_temp;
  285.             }
  286.                 return 1;
  287.         }
  288.         else   //傳感器不響應(yīng)
  289.         {
  290.            return 0;
  291.         }
  292. }

  293. /********************************************************************
  294. * 文件名  : 液晶1602顯示.c
  295. * 描述    :  該程序?qū)崿F(xiàn)了對液晶1602的控制。
  296. ***********************************************************************/


  297. /********************************************************************
  298. * 名稱 : delay()
  299. * 功能 : 延時,延時時間大概為140US。
  300. * 輸入 : 無
  301. * 輸出 : 無
  302. ***********************************************************************/

  303. void delay()                                                         
  304. {
  305.         int i,j;
  306.         for(i=0; i<=10; i++)
  307.         for(j=0; j<=2; j++);
  308. }         
  309.         
  310. /********************************************************************
  311. * 名稱 : enable(uchar del)
  312. * 功能 : 1602命令函數(shù)
  313. * 輸入 : 輸入的命令值
  314. * 輸出 : 無
  315. ***********************************************************************/

  316. void enable(uchar del)
  317. {
  318.         P0 = del;                                          //數(shù)據(jù)發(fā)送到P0口
  319.         RS = 0;                                                  //RS引腳拉低
  320.         E = 1;                                                  //E引腳高電平
  321.         delay();                                          //延時
  322.         E = 0;                                                  //E引腳低電平
  323.         delay();                                          //延時
  324. }

  325. /********************************************************************
  326. * 名稱 : write(uchar del)
  327. * 功能 : 1602寫數(shù)據(jù)函數(shù)
  328. * 輸入 : 需要寫入1602的數(shù)據(jù)
  329. * 輸出 : 無
  330. ***********************************************************************/

  331. void write(uchar del)
  332. {
  333.         P0 = del;                                           //同上
  334.         RS = 1;
  335.         E = 1;
  336.         delay();
  337.         E = 0;
  338.         delay();
  339. }

  340. /********************************************************************
  341. * 名稱 : L1602_init()
  342. * 功能 : 1602初始化,請參考1602的資料
  343. * 輸入 : 無
  344. * 輸出 : 無
  345. ***********************************************************************/
  346. void L1602_init(void)
  347. {
  348.         
  349.         enable(0x38);                  //設(shè)置液晶工作模式,意思:16*2行顯示,5*7點陣,8位數(shù)據(jù)
  350.         enable(0x0c);                  //開顯示不顯示光標
  351.         enable(0x06);                   //整屏不移動,光標自動右移
  352.         enable(0x01);         //清屏
  353. }

  354. /********************************************************************
  355. * 名稱 : L1602_char(uchar hang,uchar lie,char sign)
  356. * 功能 : 改變液晶中某位的值,如果要讓第一行,第五個字符顯示"b" ,調(diào)用該函數(shù)如下
  357.                  L1602_char(1,5,'b')
  358. * 輸入 : 行,列,需要輸入1602的數(shù)據(jù)
  359. * 輸出 : 無
  360. ***********************************************************************/
  361. void L1602_char(uchar hang,uchar lie,char sign)
  362. {
  363.         uchar a;                                                                         //定義變量
  364.         if(hang == 1) a = 0x80;                                                 //如果hang變量為1,讓地址數(shù)據(jù)為0x80就是第一行的
  365.         if(hang == 2) a = 0xc0;                                                 //如果hang變量為0,讓地址數(shù)據(jù)為0xc0就是第二行的
  366.         a = a + lie - 1;                                                         //列數(shù)據(jù)減一,因為液晶屏的列是從0開始的
  367.         enable(a);                                                                         //發(fā)送行和列數(shù)據(jù)
  368.         write(sign);                                                                 //寫顯示內(nèi)容
  369. }

  370. /********************************************************************
  371. * 名稱 : L1602_string(uchar hang,uchar lie,uchar *p)
  372. * 功能 : 改變液晶中某位的值,如果要讓第一行,第五個字符開始顯示"ab cd ef" ,調(diào)用該函數(shù)如下
  373.                   L1602_string(1,5,"ab cd ef;")
  374. * 輸入 : 行,列,需要輸入1602的數(shù)據(jù)
  375. * 輸出 : 無
  376. ***********************************************************************/
  377. void L1602_string(uchar hang,uchar lie,uchar *p)
  378. {
  379.         uchar a;
  380.         if(hang == 1) a = 0x80;                                 //第一行地址
  381.         if(hang == 2) a = 0xc0;                                 //第二行地址
  382.         a = a + lie - 1;                                         //行和列數(shù)據(jù)加一起
  383.         enable(a);                                                         //發(fā)送行列數(shù)據(jù)
  384.         while(1)                                                         //進入循環(huán)
  385.         {
  386.                 if(*p == '\0') break;                         //發(fā)送完字符串后跳出while循環(huán)
  387.                 write(*p);                                                 //沒發(fā)送完就繼續(xù)發(fā)
  388.                 p++;                                                         //字符串指針地址加1
  389.         }
  390. }

  391. //顯示整型的溫濕度數(shù)據(jù)用,共占用4位,其中一位符號位
  392. void L1602_int(uchar hang, uchar lie, int num)
  393. {
  394.    uint temp;
  395.    uint gewei,shiwei,baiwei,sign;
  396.    if (num >= 0)                                                         //如果溫度值大于等于0
  397.    sign = 0;                                                                 //符號為正
  398.    else                                                                                 //反之
  399.    sign = 1;                                                                 //符號為負
  400.    temp = abs(num);                                                         //溫度值取絕對值
  401.    baiwei = temp / 100;                                                 //除以100得到溫度值百位
  402.    temp = temp - baiwei*100;                                 //溫度值減去百位得到十位和個位的數(shù)
  403.    shiwei = temp / 10;                                                 //除以10得到十位的數(shù)據(jù)
  404.    gewei = temp - shiwei*10;                                 //減去十位的數(shù)據(jù)得到個位的數(shù)
  405.    num = abs(num);                                                         //溫度取絕對值
  406.    if (num>=100)                                                         //如果溫度大于100
  407.    {
  408.    //   L1602_char(hang, lie+1, baiwei+48);  
  409.           L1602_char(hang, lie+2, shiwei+48);           //顯示十位和個位
  410.           L1602_char(hang, lie+3, gewei+48);  
  411.    }
  412.    else if (num>=10)                                                 //溫度大于10
  413.    {
  414.       if (sign == 1)                                                    //負數(shù)時
  415.           L1602_char(hang, lie+1, '-');                         //顯示負號
  416.           L1602_char(hang, lie+2, shiwei+48);           //顯示十位和個位數(shù)
  417.       L1602_char(hang, lie+3, gewei+48);
  418.    }
  419.    else                                                                                 //溫度小于10
  420.    {
  421.       if (sign == 1)                                                    //負數(shù)時
  422.           L1602_char(hang, lie+2, '-');                         //顯示負號
  423.           else                                                                         //正數(shù)
  424.           L1602_char(hang, lie+2, ' ');                         //十位不顯示
  425.       L1602_char(hang, lie+3, gewei+48);           //顯示個位數(shù)
  426.    }
  427. }

  428. void display()                                                                                         //顯示函數(shù)
  429. {                                                                                                                 
  430.         if(Mode==0)                                                                                         //不是設(shè)置狀態(tài)
  431.         {
  432.                 L1602_int(1,3,temperature);                                                 //顯示溫度數(shù)據(jù)
  433.                 L1602_char(1,7,0xdf);                                                         //顯示攝氏度的°
  434.                 L1602_int(1,12,humidity);                                                  //顯示濕度數(shù)據(jù)

  435.                 if(hot==1&&cold==0&&humid==0&&dry==0)                         //溫度過高
  436.                 {L1602_string(2,1," It's very hot! ");BJ=1;}          //顯示熱 ,報警
  437.                 else if(hot==1&&cold==0&&humid==1&&dry==0)                 //溫度高,濕度高
  438.                 {L1602_string(2,1," Hot and humid! ");BJ=1;}         //顯示熱 ,濕, 報警
  439.                 else if(hot==1&&cold==0&&humid==0&&dry==1)                 //溫度高 ,濕度低
  440.                 {L1602_string(2,1,"  Hot and dry!  ");BJ=1;}         //顯示熱 ,干, 報警
  441.                 else if(hot==0&&cold==1&&humid==0&&dry==0)                 //溫度低
  442.                 {L1602_string(2,1," It's very cold!");BJ=1;}         //顯示冷 ,報警
  443.                 else if(hot==0&&cold==1&&humid==1&&dry==0)                 //溫度低 ,濕度高
  444.                 {L1602_string(2,1," Cold and humid!");BJ=1;}         //顯示冷 ,濕,報警
  445.                 else if(hot==0&&cold==1&&humid==0&&dry==1)                 //溫度低 ,濕度低
  446.                 {L1602_string(2,1,"  Cold and dry! ");BJ=1;}         //顯示冷 ,干,報警
  447.                 else if(hot==0&&cold==0&&humid==1&&dry==0)                 //濕度高
  448.                 {L1602_string(2,1,"It's very humid!");BJ=1;}         //顯示潮濕,報警
  449.                 else if(hot==0&&cold==0&&humid==0&&dry==1)                 //濕度低
  450.                 {L1602_string(2,1," It's very dry! ");BJ=1;}         //顯示干燥
  451.                 else if(hot==0&&cold==0&&humid==0&&dry==0)                 //都在范圍內(nèi)
  452.                 {L1602_string(2,1,"Good environment");BJ=0;}         //顯示環(huán)境好,關(guān)閉報警
  453.         }                                                                          
  454. }

  455. /***按鍵函數(shù)***/
  456. void KEY()                                                                                                 //按鍵函數(shù)
  457. {
  458.         if(Key_SET==0)                                                                                 //設(shè)置按鍵按下
  459.         {
  460.                 Delay1(200);                                                                         //延時去抖
  461.                 if(Key_SET==0)                                                                         //再次判斷按鍵按下
  462.                 {
  463.                         Mode++;                                                                                 //顯示位加
  464.                         TR0=0;                                                                                 //關(guān)閉定時器
  465.                         Led_shengwen=1;
  466.                         Led_jiangwen=1;
  467.                         Led_jiashi=1;
  468.                         Led_qushi=1;                                                                 //關(guān)閉四路繼電器輸出
  469.                         hot=0;
  470.                         cold=0;
  471.                         humid=0;
  472.                         dry=0;                                                                                 //變量清零
  473.                         if(Mode==1)                                                                         //設(shè)置第一個位置
  474.                         {
  475.                                 L1602_string(1,1," TH:    C HH:  %");         //初始化設(shè)置界面,第一行顯示溫度和濕度上限
  476.                                 L1602_char(1,8,0xdf);                                         //顯示攝氏度的°
  477.                                 L1602_string(2,1," TL:    C HL:  %");         //第二行顯示溫度和濕度的下限
  478.                                 L1602_char(2,8,0xdf);                                         //顯示攝氏度的°
  479.                                 L1602_int(1,4,TH);                                                 //顯示溫度上限
  480.                                 L1602_int(1,12,HH);                                                 //顯示濕度上限
  481.                                 L1602_int(2,4,TL);                                                 //顯示溫度下限
  482.                                 L1602_int(2,12,HL);                                                 //顯示濕度下限
  483.                                 enable(0x80+6);                                                         //選中第一個位置閃爍
  484.                                 enable(0x0f);                                                         //開啟閃爍
  485.                         }
  486.                         else if(Mode==2)                                                         //第二個位置
  487.                         {
  488.                                 enable(0x80+0x40+6);                                         //溫度上限位置閃爍
  489.                                 enable(0x0f);
  490.                         }
  491.                         else if(Mode==3)
  492.                         {
  493.                                 enable(0x80+14);                                                 //濕度上限位置閃爍
  494.                                 enable(0x0f);
  495.                         }
  496.                         else if(Mode==4)
  497.                         {
  498.                                 enable(0x80+0x40+14);                                         //濕度下限位置閃爍
  499.                                 enable(0x0f);
  500.                         }
  501.                         else if(Mode>=5)                                                         //設(shè)置完最后一位,回到第一位
  502.                         {
  503.                                 Mode=1;                                                                         //回到第一位置
  504.                                 enable(0x80+6);                                                         //第一個位置閃爍
  505.                                 enable(0x0f);
  506.                         }
  507.                         while(!Key_SET);                                                         //按鍵釋放
  508.                 }
  509.         }
  510.         else if(Key_ADD==0)                                                                         //加按鍵
  511.         {
  512.                 Delay1(200);
  513.                 if(Key_ADD==0)
  514.                 {
  515.                         if(Mode==1)                                                                         //設(shè)置溫度上限
  516.                         {
  517.                                 TH++;                                                                         //溫度上限加
  518.                                 if(TH>=100)                                                                 //加到100
  519.                                 TH=99;                                                                         //賦值99,也就是最大能加到99
  520.                                 L1602_int(1,4,TH);                                                 //顯示溫度上限
  521.                                 enable(0x80+6);                                                         //因為送顯示數(shù)據(jù)了,閃爍的位置會自動右移,所以這里要指定要閃爍的位置
  522.                                 wrteeprom(0,TH);                                                 //將上限值寫入AT24C02芯片
  523.                         }
  524.                         else if(Mode==2)                                                         //設(shè)置溫度下限
  525.                         {
  526.                                 TL++;                                                                         //加
  527.                                 if(TL>=TH)                                                                 //下限不能比上限高
  528.                                 TL=TH-1;                                                                 //下限只能加到比上限小一
  529.                                 L1602_int(2,4,TL);                                                 //下面注釋同上,略
  530.                                 enable(0x80+0x40+6);
  531.                                 wrteeprom(1,TL);
  532.                         }
  533.                         else if(Mode==3)
  534.                         {
  535.                                 HH++;
  536.                                 if(HH>=100)
  537.                                 HH=99;
  538.                                 L1602_int(1,12,HH);
  539.                                 enable(0x80+14);
  540.                                 wrteeprom(2,HH);
  541.                         }
  542.                         else if(Mode==4)
  543.                         {
  544.                                 HL++;
  545.                                 if(HL>=HH)
  546.                                 HL=HH-1;
  547.                                 L1602_int(2,12,HL);
  548.                                 enable(0x80+0x40+14);
  549.                                 wrteeprom(3,HL);
  550.                         }
  551.                         while(!Key_ADD);
  552.                 }
  553.         }
  554.         else if(Key_SUB==0)                                                        //減按鍵
  555.         {
  556.                 Delay1(200);
  557.                 if(Key_SUB==0)
  558.                 {
  559.                         if(Mode==1)
  560.                         {
  561.                                 TH--;
  562.                                 if(TH<=TL)
  563.                                 TH=TL+1;
  564.                                 L1602_int(1,4,TH);
  565.                                 enable(0x80+6);
  566.                                 wrteeprom(0,TH);
  567.                         }
  568.                         else if(Mode==2)
  569.                         {
  570.                                 TL--;
  571.                                 if(TL<=0)
  572.                                 TL=0;
  573.                                 L1602_int(2,4,TL);
  574.                                 enable(0x80+0x40+6);
  575.                                 wrteeprom(1,TL);
  576.                         }
  577.                         else if(Mode==3)
  578.                         {
  579.                                 HH--;
  580.                                 if(HH<=HL)
  581.                                 HH=HL+1;
  582.                                 L1602_int(1,12,HH);
  583.                                 enable(0x80+14);
  584.                                 wrteeprom(2,HH);
  585.                         }
  586.                         else if(Mode==4)
  587.                         {
  588.                                 HL--;
  589.                                 if(HL<=0)
  590.                                 HL=0;
  591.                                 L1602_int(2,12,HL);
  592.                                 enable(0x80+0x40+14);
  593.                                 wrteeprom(3,HL);
  594.                         }
  595.                         while(!Key_SUB);
  596.                 }
  597.         }
  598.         if(Key_OK==0&&Mode!=0)                                                        //確認按鍵
  599.         {
  600.                 Delay1(200);
  601.                 if(Key_OK==0)
  602.                 {
  603.                         L1602_string(1,1,"Tem:   C Hum:  %");         //退出設(shè)置狀態(tài),恢復(fù)待機顯示界面
  604.                         L1602_string(2,1,"Good environment");
  605.                         Mode=0;                                                                        //清零
  606.                         TR0=1;                                                                        //打開定時器
  607.                         enable(0x0c);                                                        //光標不閃爍
  608.                         while(Key_OK==0);                                                //按鍵釋放
  609.                 }
  610.         }
  611. }

  612. //數(shù)據(jù)初始化
  613. void Data_Init()
  614. {
  615.    Led_qushi = 1;
  616.    Led_jiashi=1;
  617.    Led_jiangwen = 1;
  618.    Led_shengwen = 1;                                //熄滅四個繼電器
  619. }

  620. /********************************************************************
  621. * 名稱 : Main()
  622. * 功能 : 主函數(shù)
  623. ***********************************************************************/
  624. void main()
  625. {
  626.     uint i, j, testnum;

  627.     EA = 0;                                                 //關(guān)閉定時器

  628.         Timer0_Init();  //定時器0初始化

  629.     Data_Init();                                        //數(shù)據(jù)初始化
  630.         EA = 1;                                                        //打開定時器

  631.         L1602_init();                                                         //液晶屏初始化
  632.         L1602_string(1,1," Welcome to T&H ");
  633.         L1602_string(2,1," Control System!");         //開機顯示界面
  634.         //延時
  635.         for (i=0;i<1000;i++)                                         //延時
  636.            for (j=0;j<100;j++)
  637.            {;}
  638.             /***載入溫度上限和濕度上限設(shè)定值***/
  639.         TH=rdeeprom(0);          //從AT24C02讀取溫度上限數(shù)據(jù)
  640.         Delay1(20);                 //加延時可以存取穩(wěn)定
  641.         TL=rdeeprom(1);         //溫度下限
  642.         Delay1(20);
  643.         HH=rdeeprom(2);         //濕度上限
  644.         Delay1(20);
  645.         HL=rdeeprom(3);         //濕度下限
  646.         Delay1(20);
  647.                  
  648.         if(TH<=0&&TL<=0&&HH<=0&&HL<=0) //如果是新單片機,溫濕度數(shù)據(jù)都是小于0
  649.         {
  650.                 wrteeprom(0,30);                                         //那么就給溫濕度的報警值賦初值,30  20  60  50
  651.                 Delay1(20);                 //加延時可以存取穩(wěn)定
  652.                 TH=rdeeprom(0);                                                  //寫進去再讀出來
  653.                 Delay1(20);                 //加延時可以存取穩(wěn)定

  654.                 wrteeprom(1,20);
  655.                 Delay1(20);                 //加延時可以存取穩(wěn)定
  656.                 TL=rdeeprom(1);
  657.                 Delay1(20);                 //加延時可以存取穩(wěn)定

  658.                 wrteeprom(2,60);
  659.                 Delay1(20);                 //加延時可以存取穩(wěn)定
  660.                 HH=rdeeprom(2);
  661.                 Delay1(20);                 //加延時可以存取穩(wěn)定

  662.                 wrteeprom(3,50);
  663.                 Delay1(20);                 //加延時可以存取穩(wěn)定
  664.                 HL=rdeeprom(3);
  665.         }
  666.     //清屏
  667.         L1602_string(1,1,"                ");
  668.         L1602_string(2,1,"                ");
  669.     L1602_string(1,1,"Tem:   C Hum:  %");
  670.         L1602_string(2,1,"Good environment");         //顯示待機界面
  671.    
  672.         while(1)                                                                 //進入while循環(huán)
  673.         {
  674.       
  675.                  if (FlagStartRH == 1)         //溫濕度轉(zhuǎn)換標志檢查
  676.                  {
  677.                      TR0 = 0;                                                 //關(guān)閉定時器
  678.              testnum = RH();                                 //讀取溫濕度
  679.                           FlagStartRH = 0;                                 //轉(zhuǎn)換標志清零
  680.                          TR0 = 1;                                                 //打開定時器
  681.                          humidity = U8RH_data_H;         //讀出濕度,只取整數(shù)部分
  682.                          temperature = U8T_data_H;          //讀出溫度

  683.                         
  684.                          if(Mode==0)                //溫濕度控制
  685.                          {
  686.                                  if (temperature > TH)                 //溫度大于上限
  687.                                 {
  688.                                         Led_jiangwen = 0;                 //控制降溫繼電器打開
  689.                                         hot=1;                                         //溫度高變量置1
  690.                                         Led_shengwen = 1;                 //升溫繼電器關(guān)閉
  691.                                         cold=0;                                         //溫度低變量置0
  692.                         //                BJ=1;
  693.                                 }
  694.                                 else if(temperature<TL)                  //注釋同上,略
  695.                                 {
  696.                                         Led_shengwen = 0;
  697.                                         cold=1;
  698.                                         Led_jiangwen = 1;
  699.                                         hot=0;
  700.                                         buzz=0;
  701.                         //                BJ=1;
  702.                                 }                              
  703.                                 else                                 //溫度上下都不超限
  704.                                 {
  705.                                         Led_jiangwen=1;
  706.                                         Led_shengwen=1;
  707.                                         hot=0;
  708.                                         cold=0;
  709.                                         buzz=1;
  710.                                 }
  711.                                 if (humidity > HH)
  712.                                 {
  713.                                         Led_qushi = 0;
  714.                                         humid=1;
  715.                                         Led_jiashi = 1;
  716.                                         dry=0;
  717.                         //                BJ=1;
  718.                                 }
  719.                                 else if(humidity<HL)
  720.                                 {
  721.                                         Led_jiashi = 0;
  722.                                         dry=1;
  723.                                         Led_qushi = 1;
  724.                                         humid=0;
  725.                         //                BJ=1;
  726.                                 }               
  727.                                 else                                          //濕度上限都不超限
  728.                                 {
  729.                                         Led_qushi=1;
  730.                                         Led_jiashi=1;
  731.                                         humid=0;
  732.                                         dry=0;
  733.                                 }        
  734.                          }
  735.                          else                                          //所有數(shù)據(jù)都不超限
  736.                          {
  737.                                  Led_shengwen=1;
  738.                                 Led_jiangwen=1;
  739.                                 Led_jiashi=1;
  740.                                 Led_qushi=1;                  //關(guān)閉所有繼電器
  741.                                 hot=0;
  742.                                 cold=0;
  743.                                 humid=0;
  744.                                 dry=0;                                   //變量清零
  745.                                 BJ=0;                                   //關(guān)閉報警
  746.                          }        
  747.                 }
  748.                 display();                                                //調(diào)用顯示函數(shù)
  749.                 KEY();                                                        //調(diào)用按鍵掃描函數(shù)
  750.         }        
  751. }
復(fù)制代碼

所有資料51hei提供下載(Proteus7.5版本的仿真+程序):
4個繼電器的溫濕度控制器.7z (424.6 KB, 下載次數(shù): 171)

評分

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

查看全部評分

回復(fù)

使用道具 舉報

ID:89286 發(fā)表于 2021-3-9 04:42 | 顯示全部樓層
thanks for sharing
回復(fù)

使用道具 舉報

ID:582255 發(fā)表于 2021-3-15 14:58 | 顯示全部樓層
5v的繼電器驅(qū)動沒問題吧?
回復(fù)

使用道具 舉報

ID:922803 發(fā)表于 2021-6-6 10:11 | 顯示全部樓層
需要用Proteus7.5版本打開才能顯示
回復(fù)

使用道具 舉報

ID:961300 發(fā)表于 2021-9-25 19:57 | 顯示全部樓層
樓主,照著做了一個,為什么不顯示溫度和濕度,只顯示0%
回復(fù)

使用道具 舉報

ID:961300 發(fā)表于 2021-9-25 21:15 | 顯示全部樓層
樓主能幫忙看看什么問題嗎?
回復(fù)

使用道具 舉報

ID:990300 發(fā)表于 2021-12-12 21:49 | 顯示全部樓層
我想問一下那個蜂鳴器仿真時為什么不會響啊,還有那個蜂鳴器為什么要加一個開關(guān)啊?求解答
回復(fù)

使用道具 舉報

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

本版積分規(guī)則

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

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

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