原理图如下:
程序如下:
#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;
}