找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1603|回复: 0
打印 上一主题 下一主题
收起左侧

温室大棚智能控制系统

[复制链接]
跳转到指定楼层
楼主
ID:625382 发表于 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;//调时按键移位
sbit jia   =   P1^5;//加一按键
sbit jian  =   P1^6;//减一按键
sbit back  =   P1^7;//退出调时按键
/*蜂鸣器定位*/
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转换芯片引脚定位*/
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;/*存放测试结果*/       
uchar count;
bit flash;                           //刷新频率参数
sbit TRH = P2^2;        //温湿度传感器DHT11数据接入
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;//温湿度光照强度最大最小值
/***液晶驱动******/
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_();
                }
        }
}

/****************************************************************************/
//收发信号检测,数据读取
/****************************************************************************/
//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();
        //主机设为输入 判断从机响应信号
        TRH=1;
        //判断DHT11是否有低电平响应信号 如不响应则跳出,响应则向下运行   
        if(!TRH)   
        {
        respond=2;                         //判断DHT11发出 80us 的低电平响应信号是否结束
        while((!TRH)&& respond++);
        respond=2;                         //判断从机是否发出 80us 的高电平,如发出则进入数据接收状态
        while(TRH && respond++);           //数据接收状态   
        RH_temp = receive();
        RL_temp = receive();
        TH_temp = receive();
        TL_temp = receive();
        CK_temp = receive();
        TRH=1;                             //数据校验
        untemp=(RH_temp+RL_temp+TH_temp+TL_temp);
        if(untemp==CK_temp)
        {
                RH_data = RH_temp;                //湿度整数部分       
//                RL_data = RL_temp;                //湿度小数部分
                TH_data = TH_temp;                  //温度整数部分
//                TL_data = TL_temp;                //温度小数部分
                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)//数据写入
{
  Write_Instruction(i);
  Write_Data(k|0x30);
}
void Write_d(uchar i,uchar k)//℃写入
{
   Write_Instruction(i);
  Write_Data(k);

}
/****************************************************************************/
/****数据显示*****/
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转换**********************************************
* 名称 : dRead_ADC0832()
* 功能 : 将模拟信号转换成数字信号
* 输入 : Ch-通道选择
* 输出 : dat-转换值
*********************************************************************/
unsigned char Read_ADC0832(unsigned char Ch)
{
        unsigned char i,dat; //定义变量
        ADC0832_CS=1;   //一个转换周期开始
        ADC0832_CLK=0;  //为第一个脉冲作准备
        ADC0832_CS=0;  //CS置0,片选有效
       
        ADC0832_DIO=1;    //DIO置1,规定的起始信号  
        ADC0832_CLK=1;   //第一个脉冲
        ADC0832_CLK=0;   //第一个脉冲的下降沿,此前DIO必须是高电平
        ADC0832_DIO=1;   //DIO置1, 通道选择信号  
        ADC0832_CLK=1;   //第二个脉冲,第2、3个脉冲下沉之前,DI必须跟别输入两位数据用于选择通道,这里选通道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;       //将下面储存的低位数据向右移
                dat|=(unsigned char)ADC0832_DIO;          //将输出数据DIO通过或运算储存在dat最低位
        }                                  
        ADC0832_CS=1;          //片选无效
        return dat;         //将读书的数据返回     
}
/****初始化子函数*****/
void init()                                        //通过定时器模拟PWM输出程序,控制电机的转速
{
        TMOD=0x10;                                //设置单片机定时器工作方式
        EA=1;                                    //打开单片机总中断
        ET1=1;                    //定时器T1中断允许
        count=0;
        TH1=(65536-43863)/256;    //定时器T1的高8位设置初值,每50ms产生一次中断
        TL1=(65536-43863)%256;    //定时器T1的低8位设置初值,每50ms产生一次中断
        TR1=0;                    //关闭定时器T1

//        。
}
/****************************************************************************/
//主函数
//TH,TL,RH,RL分别代表温湿度的整数和小数部分

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);  //关光标
        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);  //关光标

         }
         }
        }      
}
/*******************************************************
函数功能:定时器T1的中断服务函数
********************************************************/
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 分享淘帖 顶 踩
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表