51单片机 温湿度光照模拟控制 protues仿真

2025-11-05 00:41:22

原理图如下:

51单片机 温湿度光照模拟控制 protues仿真

程序如下:

#include <reg52.h> //52头文件 

#include<absacc.h>

#include<intrins.h>

#include<math.h>

#define uchar unsigned char

#define uint unsigned int

uchar tempset1,hunset1,inteset1;  //设置的变量

uchar s1num,s4num;//模式切换的变量

uchar flag;

uchar temp;//实际显示的温度

uchar inte;//实际显示的光照度

uchar hun;//实际显示的湿度度

uchar num;

uchar getinte;

uchar gethun;

sbit key1=P1^0;  //设置模式 4种 默认 随意数字模式 1 设置温度 2 设置湿度 3设置光照度

sbit key2=P1^1;//当前参数加一 

sbit key3=P1^2;   //当前参数减一

sbit relay1=P1^4;// 加热电路接口

sbit relay2=P1^5; //通风电路接口

sbit relay3=P1^6; //滴灌电路接口

sbit relay4=P1^7; //电机电路接口

sbit ST=P3^0;//ADC0808 START

sbit OE=P3^1;

sbit EOC=P3^2;

sbit CLK=P3^3;

sbit ADDA=P1^3; //ADDA 

sbit A138=P3^4;  //A138

sbit B138=P3^5;  //

sbit C138=P3^6;  //

sbit DQ=P3^7;  //18B20输入

unsigned char code led[]={

0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f, //0--9

0x79,0x3E,0x76,  // EU  H

0x00,  //灭

}; 

unsigned char code smg_we[]={0x8F,0x9F,0xAF,0xBF,0xCF,0xDF,0xEF,0xFF};

uchar a[8];//数码管显示 

void init_ds18b20(void);

void write_byte(uchar dat);

uchar read_byte(void);

uchar readtemperature(void);

void display(void);

void delay(uint t);

void init(); 

void delay_ms(uint);

void keyscan();

void inteadc0804();

void hunadc0804(); 

void main()

{

    init();

while(1)

{

 keyscan();

 switch(flag)

 {

case 0:  

{

display(); 

}

break;

case 1:  

{

temp=readtemperature();  

display();

if (temp>=tempset1)  //实际温度大于设定值 开启通风电路

  {

  relay1=0;

  relay2=1;

}

if (temp<=tempset1) //实际温度低于设定值 开启加热电路 闭关通风电路

  {

relay1=1;

    relay2=0;

}

}

break;

case 2:  

{

    OE=0;

             ST=1;

             ST=0;

             ADDA=0;

             while(EOC==0);

             OE=1;

             getinte=P2;

             OE=0;   

inte=getinte/2.55;

             display();

if (inte>=inteset1)  //实际光线大于设定值 开启电机拉遮阳幕幕 

{

relay4=0;

}

if(inte<=inteset1)

   {

relay4=1;

}

}

break;

case 3:  

{

    ST=1;

             ST=0;

             ADDA=1;

             while(EOC==0);

             OE=1;

             gethun=P2;

             OE=0;

hun=gethun/2.55;

display();

if (hun>=hunset1)  //实际湿度大于设定值 开启通风电路  关滴灌

{

relay2=1;

relay3=0;

}

if(hun<=hunset1) //实际湿度于设定值 关通风电路 开滴灌

{

relay2=0;

relay3=1;

}

}

break;

 }

}

}

void keyscan()//键盘扫描函数

{

if(key1==0)//模式切换键按下

{

delay_ms(10);

if(key1==0)

{

  flag++;

  if(flag==4)

  {

flag=0;

  }

}

while(!key1) ; //等待按键释放

}

if(flag!=0)

{

switch(flag)

{

case 1:   //温度调整

{

if(key2==0)  //温度加1

{

delay_ms(10);

if(key2==0)

{

      tempset1++;

if(tempset1==40)

tempset1=15;

}

while(!key2);

}

if(key3==0)  //温度减1

{

delay_ms(10);

if(key3==0)

{

   tempset1--;

if(tempset1==15)

tempset1=40;   

}

while(!key3) ;

}

}  

break;

case 2:   //光照调整

{

if(key2==0)  //光照加1

{

delay_ms(10);

if(key2==0)

{

inteset1++;

if(inteset1==60)

inteset1=40;

}

while(!key2);

}

if(key3==0)  //光照减1

{

delay_ms(10);

if(key3==0)

{

 inteset1--;

if(inteset1==40)

inteset1=60;      

}

while(!key3);

}

}  

break;

case 3:   //湿度调整

{

if(key2==0)

{

delay_ms(10);

if(key2==0)

{

  hunset1++;

if(hunset1==90)

hunset1=10;

}

while(!key2);

}

if(key3==0)

{

delay_ms(10);

if(key3==0)

{

 hunset1--;

if(hunset1==10)

hunset1=90;     

}

while(!key3);

}

}  

break;

}

}

}

void init()

tempset1=25;//温度初值 E

inteset1=50;//光照初值 U

hunset1=46;//湿度初值H

TH1=(65536-200)/256;

TL1=(65536-200)%256;

TH0=(65536-50000)/256;

TL0=(65536-50000)%256;

EA=1;

ET1=1;

TR1=1;

ET0=1;

}

///////////////////////////////

void delay(uint t) 

while(t--); 

}

void delay_ms(uint z) //带参数延时函数

{

uint x,y;

for(x=z;x>0;x--)

for(y=110;y>0;y--);

}

/////////////////////////

void init_ds18b20(void) 

{  

uchar n;

DQ=1; 

delay(8); 

DQ=0; 

delay(80); 

DQ=1; 

delay(8);  

n=DQ; 

delay(14); 

///////////////////////////////

void write_byte(uchar dat) 

{  

uchar i; 

for(i=0;i<8;i++)

DQ=0;   

DQ=dat&0x01;  

delay(8);   

DQ=1;  

dat>>=1; 

}  

delay(8);

uchar read_byte(void) 

{  

uchar i,value;

for(i=0;i<8;i++) 

DQ=0;  

value>>=1;  

DQ=1; 

if(DQ)   

value|=0x80;   

delay(4); 

}  

return value; 

////////////////////////////

uchar readtemperature(void) 

uchar a,b;  

init_ds18b20(); 

write_byte(0xcc); //跳过ROM  

write_byte(0x44); // 启动温度测量 

delay(300); 

init_ds18b20();  

write_byte(0xcc);  

write_byte(0xbe); 

a=read_byte(); 

b=read_byte(); 

b<<=4;  

b+=(a&0xf0)>>4; //组成一个字节

return b; 

void display(void) 

{  

switch(flag)

{

case 0:  //初始模式

{

   a[7]=led[6];

a[6]=led[6];

a[5]=led[6];

a[4]=led[6];

a[3]=led[6];

a[2]=led[6];

a[1]=led[6];

a[0]=led[6];

}

break;

   case 1:  // 温度模式

{

   a[7]=led[temp%10];

a[6]=led[temp%100/10];

a[5]=led[temp/100];

a[4]=led[10];

a[3]=led[tempset1%10];

a[2]=led[tempset1%100/10];

a[1]=led[tempset1/100];

a[0]=led[10];

}

break;

case 2:    //光照度模式

{

a[7]=led[inte%10];

a[6]=led[inte%100/10];

a[5]=led[inte/100];

a[4]=led[11];

a[3]=led[inteset1%10];

a[2]=led[inteset1%100/10];

a[1]=led[inteset1/100];

a[0]=led[11];

 }

break;

   case 3:  //湿度模式

{

   a[7]=led[hun%10];

a[6]=led[hun%100/10];

a[5]=led[hun/100];

a[4]=led[12];

a[3]=led[hunset1%10];

a[2]=led[hunset1%100/10];

a[1]=led[hunset1/100];

a[0]=led[12];

}

break;

     }

   P3=smg_we[0]; //选择第一个数码管

   P0=a[0];//显示E 

   delay_ms(2);

   P3=smg_we[1]; //选择第2个数码管

   P0=a[1];//显示百位 

   delay_ms(2);

   P3=smg_we[2]; //选择第3个数码管

   P0=a[2];//显示十位 

   delay_ms(2);

   P3=smg_we[3]; //选择第4个数码管

   P0=a[3];//显示个位 

   delay_ms(2);

   P3=smg_we[4]; //选择第5个数码管

   P0=a[4];//显示E 

   delay_ms(2);

   P3=smg_we[5]; //选择第6个数码管

   P0=a[5];//显示百位 

   delay_ms(2);

   P3=smg_we[6]; //选择第7个数码管

   P0=a[6];//显示十位 

   delay_ms(2);

   P3=smg_we[7]; //选择第8个数码管

   P0=a[7];//显示个位 

   delay_ms(2);

void t1(void) interrupt 3  //ADC0808时钟频率

{

TH1=(65536-200)/256;

TL1=(65536-200)%256;

CLK=~CLK;

}

  

声明:本网站引用、摘录或转载内容仅供网站访问者交流或参考,不代表本站立场,如存在版权或非法内容,请联系站长删除,联系邮箱:site.kefu@qq.com。
猜你喜欢