找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

帖子
查看: 2205|回復: 0
打印 上一主題 下一主題
收起左側(cè)

溫室大棚智能控制系統(tǒng)

[復制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:625382 發(fā)表于 2020-7-18 02:20 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
#include <reg52.h>
#include <intrins.h>
#define uint unsigned int
#define uchar unsigned char

/*======LCD位定義==========*/
sbit RS=P2^6;
sbit RW=P2^5;
sbit E=P2^7;  
sfr LCDData=0x80;
/*按鍵定位*/
sbit set   =   P1^4;//調(diào)時按鍵移位
sbit jia   =   P1^5;//加一按鍵
sbit jian  =   P1^6;//減一按鍵
sbit back  =   P1^7;//退出調(diào)時按鍵
/*蜂鳴器定位*/
sbit BEEP = P2^0;  
/*熱釋電紅外檢測定位*/
sbit HW_check = P2^1;  
/*指示燈定位*/
sbit LED_ZG  =   P3^2;  //遮光指示燈
sbit LED_BG  =   P3^3;  //補光指示燈
sbit LED_ZL  =   P3^4;  //制冷指示燈
sbit LED_JR  =   P3^5;  //加熱指示燈
sbit LED_ZS  =   P3^6;  //增濕指示燈
sbit LED_GZ  =   P3^7;  //干燥指示燈
/*光照強度檢測,AD轉(zhuǎn)換芯片引腳定位*/
unsigned char Read_ADC0832(unsigned char Ch);               
sbit ADC0832_CS =P1^0;       //將CS位定義為P2.5引腳
sbit ADC0832_CLK=P1^1;       //將CLK位定義為P2.6引腳
sbit ADC0832_DIO=P1^2;       //將DIO位定義為P2.7引腳
uchar AD_Value=0;
uchar result,result0;/*存放測試結(jié)果*/       
uchar count;
bit flash;                           //刷新頻率參數(shù)
sbit TRH = P2^2;        //溫濕度傳感器DHT11數(shù)據(jù)接入
uchar TH_data,TL_data,TH,TL,RH_data,RH_data0,RL_data,CK_data;
uchar TH_temp,TL_temp,RH_temp,RL_temp,CK_temp;
uchar com_data,untemp,temp;
uchar respond;
uchar T_SETDOWN,T_SETTOP,R_SETDOWN,R_SETTOP,L_SETDOWN, L_SETTOP;//溫濕度光照強度最大最小值
/***液晶驅(qū)動******/
void Delay(uint i)
{while(i--);}
// 毫秒級延時子程序
/*********************************************************************************/
void delay_ms(unsigned char ms)
{      
        unsigned char i;
        while(ms--)
        {
                for(i = 0; i< 150; i++)
                {
                        _nop_();
                        _nop_();
                        _nop_();
                        _nop_();
                }
        }
}

/****************************************************************************/
//收發(fā)信號檢測,數(shù)據(jù)讀取
/****************************************************************************/
//5us級延時程序
/*********************************************************************************/
void delay_5us()
{
        uchar i;
        i--;
        i--;
        i--;
        i--;
        i--;
        i--;
}
char receive()
{   
uchar i;
com_data=0;
for(i=0;i<=7;i++)   
{
        respond=2;
        while((!TRH)&&respond++);
        delay_5us();
        delay_5us();
        delay_5us();
        if(TRH)
        {
                temp=1;
                respond=2;
                while((TRH)&&respond++);
        }
        else
                temp=0;
        com_data<<=1;
        com_data|=temp;   
}
return(com_data);  
}
/**********溫濕度檢測程序*********/
//溫度高8位== TL_data,溫度低8位== TH_data,濕度高8位== RH_data,濕度低8位== RH_data,校驗 8位 == CK_data
void read_TRH()
{
        //主機拉低18ms
        TRH=0;
        delay_ms(18);
        TRH=1;
        //DATA總線由上拉電阻拉高 主機延時20us
        delay_5us();
        delay_5us();
        delay_5us();
        delay_5us();
        //delay_us();
        //delay_us();delay_us();delay_us();delay_us();
        //主機設(shè)為輸入 判斷從機響應信號
        TRH=1;
        //判斷DHT11是否有低電平響應信號 如不響應則跳出,響應則向下運行   
        if(!TRH)   
        {
        respond=2;                         //判斷DHT11發(fā)出 80us 的低電平響應信號是否結(jié)束
        while((!TRH)&& respond++);
        respond=2;                         //判斷從機是否發(fā)出 80us 的高電平,如發(fā)出則進入數(shù)據(jù)接收狀態(tài)
        while(TRH && respond++);           //數(shù)據(jù)接收狀態(tài)   
        RH_temp = receive();
        RL_temp = receive();
        TH_temp = receive();
        TL_temp = receive();
        CK_temp = receive();
        TRH=1;                             //數(shù)據(jù)校驗
        untemp=(RH_temp+RL_temp+TH_temp+TL_temp);
        if(untemp==CK_temp)
        {
                RH_data = RH_temp;                //濕度整數(shù)部分       
//                RL_data = RL_temp;                //濕度小數(shù)部分
                TH_data = TH_temp;                  //溫度整數(shù)部分
//                TL_data = TL_temp;                //溫度小數(shù)部分
                CK_data = CK_temp;
        }
        }
}
/*********************************************************************************/
void Write_Instruction(uchar x)
{
        Delay(1000);
        E=0;
        RW=0;
        RS=0;
        LCDData=x;
        E=1;
        Delay(20);
        E=0;
}
void Write_Data(uchar x)
{
        Delay(1000);
        E=0;
        RW=0;
        RS=1;
        E=1;
        LCDData=x;
        E=0;
}
void InitLCD(void)
{
        Write_Instruction(0x38);
        Delay(200);
        Write_Instruction(0x0e);
        Delay(200);
        Write_Instruction(0x06);
        Delay(200);
}
void Write_String(uchar x,uchar *p)
{ Write_Instruction(x);
        while(*p!=0x00)
        { Write_Data(*p);
           p++;
          if (x++==0x8f)
            { Write_Instruction(0xc0);}
        }
}
void Write_t(uchar i,uchar k)//數(shù)據(jù)寫入
{
  Write_Instruction(i);
  Write_Data(k|0x30);
}
void Write_d(uchar i,uchar k)//℃寫入
{
   Write_Instruction(i);
  Write_Data(k);

}
/****************************************************************************/
/****數(shù)據(jù)顯示*****/
void Display( uchar y,uchar x   )
{
        Write_t(y+0,(x/10)|0x30);
    Write_t(y+1,(x%10)|0x30);
}
/****按鍵檢測*****/
void key_test( )
{
         uchar place,num,number,x;
         place=0x8b;
         number = R_SETDOWN;
         num   = 1;
         x=1;
        while(num!=0)
        {         
                if(set==0)
                {
                 delay_ms(5);
                 if(set==0)
                 {
                   x++;
                   if(x>6)x=1;
                   while(!set);
                   switch(x)
                   {  
                   case 1:{
                                   Write_Instruction(0x01);//清屏
                                Write_String(0x80,"R:");
                                Write_String(0xc0,"T:");
                                Write_String(0x84,"%R");
                                Write_d(0xc4,0xdf);        //顯示℃
                                Write_String(0xc5,"C");
                                Write_String(0x87,"SET:");
                                Write_String(0xc7,"SET:");
                                Write_String(0x8d,"-");
                                Write_String(0xcd,"-");
                                Display(0x8b,R_SETDOWN);
                                Display(0x8e,R_SETTOP);
                                Display(0xcb,T_SETDOWN);
                                Display(0xce,T_SETTOP);
                                Display(0x82,RH_data);
                                Display(0xc2,TH_data);
                                   place=0x8b; number = R_SETDOWN;   
                  
                   break; }
                   case 2:{ place=0x8e; number = R_SETTOP;    break; }
                   case 3:{ place=0xcb; number = T_SETDOWN;   break; }
                   case 4:{ place=0xce; number = T_SETTOP;    break; }
                   case 5:{
                           Write_Instruction(0x01);//清屏
                        Write_String(0x80,"L:");
                        Write_String(0x84,"Lx");
                        Write_String(0x87,"SET:");
                        Display(0x8b,L_SETDOWN);
                        Write_String(0x8d,"-");
                        Display(0x8e,L_SETTOP);
                        Display(0x82,result);
                    place=0x8b; number = L_SETDOWN;   
                   break; }
                   case 6:{ place=0x8e; number = L_SETTOP;    break; }
                   default:{    break;          }
                   }
                 }
                 }               
                 Write_Instruction( place+1 );
                 if(jia==0||jian==0)
                        {
                                if(jia==0)
                                {
                                delay_ms(5);
                                if(jia==0)
                                {       
                                        while(!jia);
                                         number++;  
                                        if(number>99)number=0;
                                        Display(place,number);       
                                }
                                  }
                                if(jian==0)
                                {
                                delay_ms(5);
                                if(jian==0)
                                {               
                                        while(!jian);
                                        if(number==0)
                                        {
                                        number=99;
                                        goto ap;
                                        }
                                        number--;  
ap:                                        Display(place,number);                  
                                }
                                 }
                           switch(x)
                           {  
                           case 1:{ R_SETDOWN = number;    break; }
                           case 2:{ R_SETTOP  = number;   break; }
                           case 3:{ T_SETDOWN = number;   break; }
                           case 4:{ T_SETTOP  = number;   break; }
                           case 5:{ L_SETDOWN = number;   break; }
                           case 6:{ L_SETTOP  = number;   break; }
                           default:    break;
                          
                           }
                        }
       
        if(back==0)
                {
                        delay_ms(5);
                         if(back==0)
                         {
                           num=0;
                           while(!back);
                           TR1=1;
                          
                         }
                 }
        }
}
/**********************AD轉(zhuǎn)換**********************************************
* 名稱 : dRead_ADC0832()
* 功能 : 將模擬信號轉(zhuǎn)換成數(shù)字信號
* 輸入 : Ch-通道選擇
* 輸出 : dat-轉(zhuǎn)換值
*********************************************************************/
unsigned char Read_ADC0832(unsigned char Ch)
{
        unsigned char i,dat; //定義變量
        ADC0832_CS=1;   //一個轉(zhuǎn)換周期開始
        ADC0832_CLK=0;  //為第一個脈沖作準備
        ADC0832_CS=0;  //CS置0,片選有效
       
        ADC0832_DIO=1;    //DIO置1,規(guī)定的起始信號  
        ADC0832_CLK=1;   //第一個脈沖
        ADC0832_CLK=0;   //第一個脈沖的下降沿,此前DIO必須是高電平
        ADC0832_DIO=1;   //DIO置1, 通道選擇信號  
        ADC0832_CLK=1;   //第二個脈沖,第2、3個脈沖下沉之前,DI必須跟別輸入兩位數(shù)據(jù)用于選擇通道,這里選通道CH0
        ADC0832_CLK=0;   //第二個脈沖下降沿
        ADC0832_DIO=Ch;   //DI置0,選擇通道0
        ADC0832_CLK=1;    //第三個脈沖
        ADC0832_CLK=0;    //第三個脈沖下降沿
        ADC0832_DIO=1;    //第三個脈沖下沉之后,輸入端DIO失去作用,應置1
        ADC0832_CLK=1;    //第四個脈沖
        for(i=0;i<8;i++)  //高位在前
        {
                ADC0832_CLK=1;         //第四個脈沖
                ADC0832_CLK=0;
                dat<<=1;       //將下面儲存的低位數(shù)據(jù)向右移
                dat|=(unsigned char)ADC0832_DIO;          //將輸出數(shù)據(jù)DIO通過或運算儲存在dat最低位
        }                                  
        ADC0832_CS=1;          //片選無效
        return dat;         //將讀書的數(shù)據(jù)返回     
}
/****初始化子函數(shù)*****/
void init()                                        //通過定時器模擬PWM輸出程序,控制電機的轉(zhuǎn)速
{
        TMOD=0x10;                                //設(shè)置單片機定時器工作方式
        EA=1;                                    //打開單片機總中斷
        ET1=1;                    //定時器T1中斷允許
        count=0;
        TH1=(65536-43863)/256;    //定時器T1的高8位設(shè)置初值,每50ms產(chǎn)生一次中斷
        TL1=(65536-43863)%256;    //定時器T1的低8位設(shè)置初值,每50ms產(chǎn)生一次中斷
        TR1=0;                    //關(guān)閉定時器T1

//        。
}
/****************************************************************************/
//主函數(shù)
//TH,TL,RH,RL分別代表溫濕度的整數(shù)和小數(shù)部分

void main()
{               
        uchar n;
        BEEP=0;  
        R_SETDOWN = 40;   
        R_SETTOP  = 70;   
        T_SETDOWN = 20;
        T_SETTOP  = 40;
        L_SETDOWN=5;
        L_SETTOP=40;
        InitLCD();         //液晶初始化
        init();                 //定時器初始化
        Write_Instruction(0x0c);  //關(guān)光標
        TR1=1;

        while(1)
        {
                if(HW_check==0)        {        BEEP=1; }  //熱釋電紅外未檢測到人體信號
                else {        BEEP=0; }                                //熱釋電紅外檢測到人體信號


                if(count==0)
                {
                        if(flash==0)                                                  //第一屏顯示濕度、溫度
                        {
                                Write_Instruction(0x01);                  //清屏
                                Write_String(0x80,"R:");
                                Write_String(0xc0,"T:");
                                Write_String(0x84,"%R");
                                Write_d(0xc4,0xdf);                                  //顯示℃
                                Write_String(0xc5,"C");
               
                                Write_String(0x87,"SET:");
                                Write_String(0xc7,"SET:");
               
                                Write_String(0x8d,"-");
                                Write_String(0xcd,"-");
               
                                Display(0x8b,R_SETDOWN);                           //顯示濕度下限
                                Display(0x8e,R_SETTOP);                            //顯示濕度上限
                                Display(0xcb,T_SETDOWN);                           //顯示溫度下限
                                Display(0xce,T_SETTOP);                                   //顯示溫度上限
                                read_TRH();                                            //啟動溫濕度傳感器檢測
                         }
                        else                                                                         //第二屏顯示光照強度
                        {
                                Write_Instruction(0x01);                        //清屏
                                Write_String(0x80,"L:");
                                Write_String(0x84,"Lx");
                                Write_String(0x87,"SET:");
                                Display(0x8b,L_SETDOWN);                           //顯示光照強度下限
                                Write_String(0x8d,"-");
                                Display(0x8e,L_SETTOP);                                   //顯示光照強度上限
                        }
                        TR1=1;
                }

            RH_data=RH_data;                                                                                                //獲取濕度
                if( RH_data<=R_SETDOWN )         {          LED_ZS=0;        LED_GZ=1;}                          //濕度低,增濕啟動
                else if( RH_data>=R_SETTOP ){        LED_ZS=1;        LED_GZ=0;}                        //濕度高,干燥啟動
                else  { LED_ZS=1;        LED_GZ=1;         }                                                                //濕度合適,停止增濕,停止干燥

            TH_data=TH_data;                                                                                                //獲取溫度
                if( TH_data<=T_SETDOWN )         {          LED_JR=0;        LED_ZL=1;}                          //溫度低,加熱啟動
                else if( TH_data>=T_SETTOP ){        LED_JR=1;        LED_ZL=0;}                        //溫度高,制冷啟動
                else  { LED_JR=1;        LED_ZL=1;         }                                                                //溫度合適,停止加熱,停止制冷

                for(n=1;n<7;n++)
                {
                        AD_Value = Read_ADC0832(0);                                                                        //獲取光照強度
                        result0=(uchar)(((float)AD_Value+5)*50/251);
                        result=result+result0;
                }
                result=result/6;
                if(result<=38)result=38-result;
                else result=0;
                if( result<=L_SETDOWN)         {          LED_BG=0;LED_ZG=1;        }                                           //光照強度值低,啟動照明補光
                else if(result>=L_SETTOP)   {        LED_BG=1;LED_ZG=0;}
                else {LED_BG=1;LED_ZG=1;}
               
                if(flash==0)
                {
                        Display(0x82,RH_data);           //顯示濕度
                        Display(0xc2,TH_data);           //顯示溫度
                }
                else
                {
                        Display(0x82,result);          //顯示光照強度
                }
        if(jia==0)                                             //在輪流顯示模式,按【加】按鍵可以保持顯示模式,按多一次取消保持顯示模式
         {
                 delay_ms(5);
                 if(jia==0)
                 {
                    while(!jia);
                           TR1=~TR1;
                 }
         }
        if(set==0)
         {
         delay_ms(5);
         if(set==0)
         {
            while(!set);
            Write_Instruction(0x0f);  //開光標
            TR1=0;
            Write_Instruction(0x01);//清屏
                Write_String(0x80,"R:");
                Write_String(0xc0,"T:");
                Write_String(0x84,"%R");
                Write_d(0xc4,0xdf);        //顯示℃
                Write_String(0xc5,"C");
                Write_String(0x87,"SET:");
                Write_String(0xc7,"SET:");
                Write_String(0x8d,"-");
                Write_String(0xcd,"-");
                Display(0x8b,R_SETDOWN);
                Display(0x8e,R_SETTOP);
                Display(0xcb,T_SETDOWN);
                Display(0xce,T_SETTOP);
                Display(0x82,RH_data);
                Display(0xc2,TH_data);
            key_test();
            Write_Instruction(0x0c);  //關(guān)光標

         }
         }
        }      
}
/*******************************************************
函數(shù)功能:定時器T1的中斷服務函數(shù)
********************************************************/
void Time1() interrupt 3 using 2 //定時器T1的中斷編號為3,使用第2組工作寄存器
  {
            count++;          //T1每中斷1次,count加1
         if(count==50)     //若累計滿20次,即計滿1秒鐘
           {  
                   count=0;
                flash=~flash;
                TR1=0;
                 }
        TH1=(65536-43863)/256;           //定時器T1高8位賦初值
        TL1=(65536-43863)%256;           //定時器T1低8位賦初值
}


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

使用道具 舉報

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

本版積分規(guī)則

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

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

快速回復 返回頂部 返回列表