#include<intrins.h>
#include<reg52.h>
#define uchar unsigned char
#define uint unsigned int
//这三个引脚参考资料
sbit E=P2^7; //1602使能引脚
sbit RW=P2^6; //1602读写引脚
sbit RS=P2^5; //1602数据/命令选择引脚
sbit DHTIO=P2^4; //温湿度传感器DHT11数据IO口
sbit SWIO=P2^0; //水位开关IO
sbit MOTOR=P2^1;//水泵电机IO
sbit BEEP=P1^1; //蜂鸣IO
sbit CSQ=P1^0; //除湿器IO
sbit key1=P3^5; //切换键
sbit key2=P3^6; //+键
sbit key3=P3^7; //-键
sbit led1=P1^2;
sbit led2=P1^3;
uchar Tem_Z,Tem_X,Hum_Z,Hum_X,Check;
uchar U8comdata;
uchar U8FLAG;
uchar U8temp;
uchar RUN_MODE=0; //运行模式 0=自动 1=手动 默认自动、
uchar RUN_STATE=0; //0=正常状态 1=水满状态 2=抽水状态
uchar SET_HUMI=50; //手动模式下设定的湿度值 默认50
uchar display1[17]={"Temp:00 Humi:00"};
uchar display3[17]={"Manual:< 50 > "};
uchar display2[17]={"Auto: "};
uchar cnt=0;
uchar sec=0;
/********************************************************************
* 名称 : lcd_delay()
* 功能 : 延时,延时时间大概为140US。
* 输入 : 无
* 输出 : 无
***********************************************************************/
void lcd_delay()
{
int i,j;
for(i=0; i<=10; i++)
for(j=0; j<=2; j++);
}
/********************************************************************
* 名称 : Delay20ms()
* 功能 : 延时,延时时间大概为20MS。
* 输入 : 无
* 输出 : 无
***********************************************************************/
void Delay20ms() //@11.0592MHz
{
unsigned char i, j;
i = 36;
j = 217;
do
{
while (--j);
} while (--i);
}
/********************************************************************
* 名称 : Delay10us()
* 功能 : 延时,延时时间大概为10us。
* 输入 : 无
* 输出 : 无
***********************************************************************/
void Delay10us() //@11.0592MHz
{
unsigned char i;
i = 2;
while (--i);
}
/********************************************************************
* 名称 : Delay200ms()
* 功能 : 延时,延时时间大概为200MS。
* 输入 : 无
* 输出 : 无
***********************************************************************/
void Delay200ms() //@11.0592MHz
{
unsigned char i, j, k;
_nop_();
i = 2;
j = 103;
k = 147;
do
{
do
{
while (--k);
} while (--j);
} while (--i);
}
/********************************************************************
* 名称 : Delay30000ms()
* 功能 : 延时,延时时间大概为3S。
* 输入 : 无
* 输出 : 无
***********************************************************************/
void Delay30000ms() //@12.000MHz
{
unsigned char i, j, k;
_nop_();
i = 228;
j = 253;
k = 219;
do
{
do
{
while (--k);
} while (--j);
} while (--i);
}
/********************************************************************
* 名称 : enable(uchar del)
* 功能 : 1602命令函数
* 输入 : 输入的命令值
* 输出 : 无
***********************************************************************/
void enable(uchar del)
{
P0 = del;
RS = 0;
RW = 0;
E = 0;
lcd_delay();
E = 1;
lcd_delay();
}
/********************************************************************
* 名称 : write(uchar del)
* 功能 : 1602写数据函数
* 输入 : 需要写入1602的数据
* 输出 : 无
***********************************************************************/
void write(uchar del)
{
P0 = del;
RS = 1;
RW = 0;
E = 0;
lcd_delay();
E = 1;
lcd_delay();
}
/********************************************************************
* 名称 : L1602_init()
* 功能 : 1602初始化,请参考1602的资料
* 输入 : 无
* 输出 : 无
***********************************************************************/
void L1602_init(void)
{
enable(0x01);
enable(0x38);
enable(0x0c);
enable(0x06);
enable(0xd0);
}
/********************************************************************
* 名称 : L1602_char(uchar hang,uchar lie,char sign)
* 功能 : 改变液晶中某位的值,如果要让第一行,第五个字符显示"b" ,调用该函数如下
L1602_char(1,5,'b')
* 输入 : 行,列,需要输入1602的数据
* 输出 : 无
***********************************************************************/
void L1602_char(uchar hang,uchar lie,char sign)
{
uchar a;
if(hang == 1) a = 0x80;
if(hang == 2) a = 0xc0;
a = a + lie - 1;
enable(a);
write(sign);
}
/********************************************************************
* 名称 : L1602_string(uchar hang,uchar lie,uchar *p)
* 功能 : 改变液晶中某位的值,如果要让第一行,第五个字符开始显示"ab cd ef" ,调用该函数如下
L1602_string(1,5,"ab cd ef;")
* 输入 : 行,列,需要输入1602的数据
* 输出 : 无
***********************************************************************/
void L1602_string(uchar hang,uchar lie,uchar *p)
{
uchar a;
if(hang == 1) a = 0x80;
if(hang == 2) a = 0xc0;
a = a + lie - 1;
enable(a);
while(1)
{
if(*p == '\0') break;
write(*p);
p++;
}
}
void COM(void)
{
uchar i;
for(i=0;i<8;i++)
{
U8FLAG=2;
while((!DHTIO)&&U8FLAG++);
Delay10us();
Delay10us();
Delay10us();
U8temp=0;
if(DHTIO)U8temp=1;
U8FLAG=2;
while((DHTIO)&&U8FLAG++);
//超时则跳出for循环
if(U8FLAG==1)break;
//判断数据位是0还是1
// 如果高电平高过预定0高电平值则数据位为 1
U8comdata<<=1;
U8comdata|=U8temp; //0
}//rof
}
/********************************************************************
* 名称 : Rec_DHT()
* 功能 : 接收来之DHT11的数据
* 输入 : 无
* 输出 : 无
***********************************************************************/
void Rec_DHT(void)
{
//主机拉低大于18ms
DHTIO=0;
Delay20ms();
DHTIO=1;
//总线由上拉电阻拉高 主机延时40us
Delay10us();
Delay10us();
Delay10us();
Delay10us();
//判断从机是否有低电平响应信号 如不响应则跳出,响应则向下运行
if(!DHTIO)
{
U8FLAG=2;
//判断从机是否发出 80us 的低电平响应信号是否结束
while((!DHTIO)&&U8FLAG++);
U8FLAG=2;
//判断从机是否发出 80us 的高电平,如发出则进入数据接收状态
while((DHTIO)&&U8FLAG++);
//数据接收状态
COM();
Hum_Z=U8comdata;
COM();
Hum_X=U8comdata;
COM();
Tem_Z=U8comdata;
COM();
Tem_X=U8comdata;
COM();
Check=U8comdata;
DHTIO=1;
}//fi
display1[5]=Tem_Z/10+48; //数据处理并装入显示缓存区
display1[6]=Tem_Z%10+48;
display1[14]=Hum_Z/10+48;
display1[15]=Hum_Z%10+48;
display3[9]=SET_HUMI/10+48;
display3[10]=SET_HUMI%10+48;
}
/********************************************************************
* 名称 : scan_key()
* 功能 : 扫描按键
* 输入 : 无
* 输出 : 无
***********************************************************************/
void scan_key(void)
{
key1=1;
key2=1;
key3=1;
if(key1==0) //切换键按下 则改变运行模式
RUN_MODE=!RUN_MODE;
if(RUN_MODE&&key2==0)
SET_HUMI++;
if(RUN_MODE&&key3==0)
SET_HUMI--;
}
/********************************************************************
* 名称 : Main()
* 功能 : 主函数
* 输入 : 无
* 输出 : 无
***********************************************************************/
void main()
{
L1602_init();
led1=1;
led2=0;
while(1)
{
Rec_DHT();
scan_key(); //扫描按键
L1602_string(1,1,&display1); //第一行显示温度和湿度
if(RUN_STATE==0)
{
if(RUN_MODE==0) //自动模式
{
if(Tem_Z>0&&Tem_Z<=18){display2[7]='4';display2[8]='0';}
else if(Tem_Z>18&&Tem_Z<=24){display2[7]='4';display2[8]='6';}
else if(Tem_Z>24&&Tem_Z<=31){display2[7]='5';display2[8]='2';}
else if(Tem_Z>31&&Tem_Z<=40){display2[7]='6';display2[8]='0';}
L1602_string(2,1,&display2); //显示自动模式内容
if((Tem_Z>0&&Tem_Z<=18&&Hum_Z>40)||(Tem_Z>18&&Tem_Z<=24&&Hum_Z>46)||
(Tem_Z>24&&Tem_Z<=31&&Hum_Z>52)||(Tem_Z>31&&Tem_Z<=40&&Hum_Z>60))
CSQ=0; //开启除湿机构
else
CSQ=1; //否则关闭除湿机构
}
else
{
L1602_string(2,1,&display3); //显示手动模式内容
if(Hum_Z>SET_HUMI) //湿度大于设定值
CSQ=0; //开启除