標(biāo)題: 溫室大棚智能控制系統(tǒng) [打印本頁]

作者: 123木頭人。。。    時(shí)間: 2020-7-18 02:20
標(biāo)題: 溫室大棚智能控制系統(tǒng)
#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)時(shí)按鍵移位
sbit jia   =   P1^5;//加一按鍵
sbit jian  =   P1^6;//減一按鍵
sbit back  =   P1^7;//退出調(diào)時(shí)按鍵
/*蜂鳴器定位*/
sbit BEEP = P2^0;  
/*熱釋電紅外檢測(cè)定位*/
sbit HW_check = P2^1;  
/*指示燈定位*/
sbit LED_ZG  =   P3^2;  //遮光指示燈
sbit LED_BG  =   P3^3;  //補(bǔ)光指示燈
sbit LED_ZL  =   P3^4;  //制冷指示燈
sbit LED_JR  =   P3^5;  //加熱指示燈
sbit LED_ZS  =   P3^6;  //增濕指示燈
sbit LED_GZ  =   P3^7;  //干燥指示燈
/*光照強(qiáng)度檢測(cè),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;/*存放測(cè)試結(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;//溫濕度光照強(qiáng)度最大最小值
/***液晶驅(qū)動(dòng)******/
void Delay(uint i)
{while(i--);}
// 毫秒級(jí)延時(shí)子程序
/*********************************************************************************/
void delay_ms(unsigned char ms)
{      
        unsigned char i;
        while(ms--)
        {
                for(i = 0; i< 150; i++)
                {
                        _nop_();
                        _nop_();
                        _nop_();
                        _nop_();
                }
        }
}

/****************************************************************************/
//收發(fā)信號(hào)檢測(cè),數(shù)據(jù)讀取
/****************************************************************************/
//5us級(jí)延時(shí)程序
/*********************************************************************************/
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);  
}
/**********溫濕度檢測(cè)程序*********/
//溫度高8位== TL_data,溫度低8位== TH_data,濕度高8位== RH_data,濕度低8位== RH_data,校驗(yàn) 8位 == CK_data
void read_TRH()
{
        //主機(jī)拉低18ms
        TRH=0;
        delay_ms(18);
        TRH=1;
        //DATA總線由上拉電阻拉高 主機(jī)延時(shí)20us
        delay_5us();
        delay_5us();
        delay_5us();
        delay_5us();
        //delay_us();
        //delay_us();delay_us();delay_us();delay_us();
        //主機(jī)設(shè)為輸入 判斷從機(jī)響應(yīng)信號(hào)
        TRH=1;
        //判斷DHT11是否有低電平響應(yīng)信號(hào) 如不響應(yīng)則跳出,響應(yīng)則向下運(yùn)行   
        if(!TRH)   
        {
        respond=2;                         //判斷DHT11發(fā)出 80us 的低電平響應(yīng)信號(hào)是否結(jié)束
        while((!TRH)&& respond++);
        respond=2;                         //判斷從機(jī)是否發(fā)出 80us 的高電平,如發(fā)出則進(jìn)入數(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ù)校驗(yàn)
        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);
}
/****按鍵檢測(cè)*****/
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()
* 功能 : 將模擬信號(hào)轉(zhuǎn)換成數(shù)字信號(hào)
* 輸入 : Ch-通道選擇
* 輸出 : dat-轉(zhuǎn)換值
*********************************************************************/
unsigned char Read_ADC0832(unsigned char Ch)
{
        unsigned char i,dat; //定義變量
        ADC0832_CS=1;   //一個(gè)轉(zhuǎn)換周期開始
        ADC0832_CLK=0;  //為第一個(gè)脈沖作準(zhǔn)備
        ADC0832_CS=0;  //CS置0,片選有效
       
        ADC0832_DIO=1;    //DIO置1,規(guī)定的起始信號(hào)  
        ADC0832_CLK=1;   //第一個(gè)脈沖
        ADC0832_CLK=0;   //第一個(gè)脈沖的下降沿,此前DIO必須是高電平
        ADC0832_DIO=1;   //DIO置1, 通道選擇信號(hào)  
        ADC0832_CLK=1;   //第二個(gè)脈沖,第2、3個(gè)脈沖下沉之前,DI必須跟別輸入兩位數(shù)據(jù)用于選擇通道,這里選通道CH0
        ADC0832_CLK=0;   //第二個(gè)脈沖下降沿
        ADC0832_DIO=Ch;   //DI置0,選擇通道0
        ADC0832_CLK=1;    //第三個(gè)脈沖
        ADC0832_CLK=0;    //第三個(gè)脈沖下降沿
        ADC0832_DIO=1;    //第三個(gè)脈沖下沉之后,輸入端DIO失去作用,應(yīng)置1
        ADC0832_CLK=1;    //第四個(gè)脈沖
        for(i=0;i<8;i++)  //高位在前
        {
                ADC0832_CLK=1;         //第四個(gè)脈沖
                ADC0832_CLK=0;
                dat<<=1;       //將下面儲(chǔ)存的低位數(shù)據(jù)向右移
                dat|=(unsigned char)ADC0832_DIO;          //將輸出數(shù)據(jù)DIO通過或運(yùn)算儲(chǔ)存在dat最低位
        }                                  
        ADC0832_CS=1;          //片選無效
        return dat;         //將讀書的數(shù)據(jù)返回     
}
/****初始化子函數(shù)*****/
void init()                                        //通過定時(shí)器模擬PWM輸出程序,控制電機(jī)的轉(zhuǎn)速
{
        TMOD=0x10;                                //設(shè)置單片機(jī)定時(shí)器工作方式
        EA=1;                                    //打開單片機(jī)總中斷
        ET1=1;                    //定時(shí)器T1中斷允許
        count=0;
        TH1=(65536-43863)/256;    //定時(shí)器T1的高8位設(shè)置初值,每50ms產(chǎn)生一次中斷
        TL1=(65536-43863)%256;    //定時(shí)器T1的低8位設(shè)置初值,每50ms產(chǎn)生一次中斷
        TR1=0;                    //關(guān)閉定時(shí)器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();                 //定時(shí)器初始化
        Write_Instruction(0x0c);  //關(guān)光標(biāo)
        TR1=1;

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


                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();                                            //啟動(dòng)溫濕度傳感器檢測(cè)
                         }
                        else                                                                         //第二屏顯示光照強(qiáng)度
                        {
                                Write_Instruction(0x01);                        //清屏
                                Write_String(0x80,"L:");
                                Write_String(0x84,"Lx");
                                Write_String(0x87,"SET:");
                                Display(0x8b,L_SETDOWN);                           //顯示光照強(qiáng)度下限
                                Write_String(0x8d,"-");
                                Display(0x8e,L_SETTOP);                                   //顯示光照強(qiáng)度上限
                        }
                        TR1=1;
                }

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

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

                for(n=1;n<7;n++)
                {
                        AD_Value = Read_ADC0832(0);                                                                        //獲取光照強(qiáng)度
                        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;        }                                           //光照強(qiáng)度值低,啟動(dòng)照明補(bǔ)光
                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);          //顯示光照強(qiáng)度
                }
        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);  //開光標(biāo)
            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)光標(biāo)

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







歡迎光臨 (http://www.torrancerestoration.com/bbs/) Powered by Discuz! X3.1