功能介绍:
0.本系统采用STC89C52作为单片机
1.系统实时监测当前温湿度/土壤湿度/环境光强并显示
2.温湿度超过设定阈值范围,蜂鸣器响,同时开启对应控制继电器
3.土壤湿度低于设定下限,开启喷洒,直至达到上限,关闭喷洒
4.环境光强超过设定上限,启动遮阳伞,环境光强低于设定下限,停用遮阳伞
5.按键可修改阈值范围
6.采用DC002作为电源接口可直接输入5V给整个系统供电
原理图:
PCB :
主程序:
#include "main.h"
#define MAXCNT (64*64-1)
#define MINCNT (1)
/*******************变量定义*********************/
enum _MODE_DF_ dispMode;
uchar setIndex = 0;
uint humidity; //湿度
uint temperature; //温度
uint light; //光强
float SH_Value = 0;//土壤湿度
uint hmMin= 50;//湿度下限
uint hmMax= 70;//湿度上限
uint tempMin = 25;//温度下限
uint tempMax = 40;//温度上限
uint lightMin = 30;//光照下限
uint lightMax = 60;//光照上限
int SH_Value_Min = 30;//土壤湿度下限
int SH_Value_Max = 60;//土壤湿度上限
uint motorCnt = 0; //记录遮光棚位置
uchar motorFlag = 2; //标记当前控制状态,=0遮阳棚已关闭,=1过程中,=2遮阳棚已打开
bit motorDir = 0; //方向
bit dispFlag = 0;
bit buzzerFlag1 = 0; //蜂鸣器标志1
bit buzzerFlag2 = 0; //蜂鸣器标志2
char dis[16];
/********************************************************
函数名称:void mian()
函数作用:主函数
参数说明:
********************************************************/
void main()
{
Timer0_Init(); //初始化定时器0
LCD_Init(); //初始化液晶
DelayMs(200); //延时有助于稳定
LCD_DispStr(4, 0, "Welcome!");
DelayS(1);
LCD_Clear(); //清屏
BYJ48 = ((BYJ48 & 0xF0) | REV[0]); //取数据
ULN_DQ3 = BIT3; ULN_DQ2 = BIT2; ULN_DQ1 = BIT1; ULN_DQ0 = BIT0;
while (1) //死循环
{
if (dispFlag == 1)
{
dispFlag = 0;
if (dispMode == NORMAL)
{
DispNormal();
}
}
if (humidity < hmMin) //湿度低于下限
{
buzzerFlag1 = 1;
RELAY_JS = ON; //加湿开
RELAY_CS = OFF; //除湿关
}
else if (humidity > hmMax) //湿度高于上限
{
buzzerFlag1 = 1;
RELAY_JS = OFF; //加湿关
RELAY_CS = ON; //除湿开
}
else
{
buzzerFlag1 = 0;
RELAY_JS = OFF; //加湿关
RELAY_CS = OFF; //除湿关
}
if (temperature < tempMin) //温度低于下限
{
buzzerFlag2 = 1;
RELAY_HEAT = ON; //升温开
RELAY_COOL = OFF; //降温关
}
else if (temperature > tempMax) //温度高于上限
{
buzzerFlag2 = 1;
RELAY_HEAT = OFF; //升温关
RELAY_COOL = ON; //降温开
}
else
{
buzzerFlag2 = 0;
RELAY_HEAT = OFF; //升温关
RELAY_COOL = OFF; //降温关
}
if (SH_Value < SH_Value_Min) //土壤湿度低于下限
{
RELAY_NY = ON; //喷洒
}
else if (SH_Value >= SH_Value_Max)
{
RELAY_NY = OFF; //停止喷洒
}
if (motorFlag == 2) //遮阳伞已打开
{
if (light > lightMax) //光照太强
{
//关闭遮阳伞
motorFlag = 1;
motorDir = 1;
motorCnt = 0;
}
}
else if (motorFlag == 0) //遮阳伞已关闭
{
if (light < lightMin) //光照低于下限
{
//打开遮阳伞
motorFlag = 1;
motorDir = 0;
motorCnt = MAXCNT;
}
}
if (buzzerFlag1 || buzzerFlag2) //蜂鸣器报警
{
BUZZER = ON;
}
else
{
BUZZER = OFF;
}
KeyProcess();
}
}
/*------------------------------------------------
定时器初始化子程序
------------------------------------------------*/
void Timer0_Init(void)
{
TMOD |= 0x01; //使用模式1,16位定时器,使用"|"符号可以在使用多个定时器时不受影响
TH0 = (65536 - 9216) / 256; //重新赋值 10ms
TL0 = (65536 - 9216) % 256;
EA = 1; //总中断打开
ET0 = 1; //定时器中断打开
TR0 = 1; //定时器开关打开
}
/*------------------------------------------------
定时器中断子程序
------------------------------------------------*/
void Timer0_Interrupt(void) interrupt 1
{
static unsigned int time1ms = 0;
TL0 = 0x66; //设置定时初始值
TH0 = 0xFC; //设置定时初始值 1ms
time1ms++;
if (time1ms > 500)
{
dispFlag = 1; //显示标志
time1ms = 0;
}
if (motorFlag == 1)
{
if (motorDir == 1)
{
motorCnt++;
BYJ48 = ((BYJ48 & 0xF0) | REV[motorCnt % 8]); //取数据
ULN_DQ3 = BIT3; ULN_DQ2 = BIT2; ULN_DQ1 = BIT1; ULN_DQ0 = BIT0;
if (motorCnt >= MAXCNT)
{
motorFlag = 0;
}
}
else
{
motorCnt--;
BYJ48 = ((BYJ48 & 0xF0) | REV[motorCnt % 8]); //取数据
ULN_DQ3 = BIT3; ULN_DQ2 = BIT2; ULN_DQ1 = BIT1; ULN_DQ0 = BIT0;
if (motorCnt <= 0)
{
motorFlag = 2;
}
}
}
}
void DispNormal(void)
{
ET0 = 0;
DHT11_0_ReadData();
ET0 = 1;
temperature = U8T_data_H; //读取温度
humidity = U8RH_data_H; //读取湿度
sprintf(dis, "Hm:%2d%% T:%3d", humidity, temperature);
LCD_DispStr(0, 0, dis);
LCD_DispOneChar(12, 0, 0xdf);
LCD_DispOneChar(13, 0, 'C');
LCD_DispOneChar(14, 0, ' ');
LCD_DispOneChar(15, 0, ' ');
SH_Value = 99 * (255-ReadADC(AIN0_GND)) / 210; //读取土壤湿度
if (SH_Value > 99)
{
SH_Value = 99;
}
light = 100 - 100 * ReadADC(AIN1_GND) / 255; //读取光强
sprintf(dis, "L:%2d%% SH:%2d", light, (int)SH_Value);
LCD_DispStr(0, 1, dis);
if (motorFlag == 2) //遮阳伞已打开
{
LCD_DispStr(11, 1, " St:O");
}
else if (motorFlag == 1)
{
LCD_DispStr(11, 1, " St:D");
}
else if (motorFlag == 0) //遮阳伞已关闭
{
LCD_DispStr(11, 1, " St:C");
}
}
/************************* 设置湿度阈值 *************************/
void DispSetHm(unsigned char setIndex)
{
LCD_DispStr(0, 0, " Set Humidity ");
sprintf(dis, " H:%2d%% L:%2d%% ", hmMax, hmMin);
LCD_DispStr(0, 1, dis);
switch (setIndex)
{
case 1: LCD_SetCursor(6, 1, 1); break;
case 2: LCD_SetCursor(12, 1, 1); break;
default:;
}
}
/************************* 设置温度阈值 *************************/
void DispSetTemp(unsigned char setIndex)
{
LCD_DispStr(0, 0, "Set Temperature ");
sprintf(dis, " H:%3d L:%3d ", tempMax, tempMin);
LCD_DispStr(0, 1, dis);
switch (setIndex)
{
case 1: LCD_SetCursor(7, 1, 1); break;
case 2: LCD_SetCursor(13, 1, 1); break;
default:;
}
}
/************************* 设置光照阈值 *************************/
void DispSetLight(unsigned char setIndex)
{
LCD_DispStr(0, 0, " Set LightLimit ");
sprintf(dis, " H:%2d%% L:%2d%% ", lightMax, lightMin);
LCD_DispStr(0, 1, dis);
switch (setIndex)
{
case 1: LCD_SetCursor(6, 1, 1); break;
case 2: LCD_SetCursor(12, 1, 1); break;
default:;
}
}
/************************* 设置土壤湿度阈值 *************************/
void DispSetSH(unsigned char setIndex)
{
LCD_DispStr(0, 0, " Set SH Limit ");
sprintf(dis, " H:%3d L:%3d ", SH_Value_Max, SH_Value_Min);
LCD_DispStr(0, 1, dis);
switch (setIndex)
{
case 1: LCD_SetCursor(6, 1, 1); break;
case 2: LCD_SetCursor(13, 1, 1); break;
default:;
}
}