#include "drive_1602.h" #include "dht11.h" #include "string.h" #include "stdio.h" #define uint unsigned int #define uchar unsigned char typedef unsigned char uint8_t; typedef unsigned short int uint16_t; typedef unsigned int uint32_t; typedef uint32_t u32; typedef uint16_t u16; typedef uint8_t u8; /* 2、能够检测土壤的湿度,实时显示到LCD1602液晶屏上。 3、能够设置上下限值,低于下限启动浇水并报警。 4、利用太阳能供电节能环保。 5、利用继电器驱动潜水泵。 6、利用蓝牙模块实现远程控制。 7、自动和动手浇水切换。 8、根据不同的土壤和环境,能够合理的调整浇水要求。 利用湿度传感器来检测土壤的含水量并将检测到的信号传给控制器单片机, 通过DS18B20温度传感器检测到的环境温度反馈到单片机,单片机经过比较处理。 如果需要浇水则驱动水泵电机浇水。如果不需要单片机会进入掉电模式。 系统可以适应不同的土壤和环境进行设定。 设计预期成果:太阳能供电系统为系统供电。 通过对土壤湿度和环境温度的检测实现自动浇花。 用电阻丝实现对水位的检测,当水箱没水时, 把信号传递到单片机,单片机处理后使LED灯亮则需要加水。 该系统太阳能供电。通过对土壤湿度的检测实现自动浇花。 低于下限启动浇水灌溉并报警,大于下限停止报警继续浇水, 高于上限停止浇水。温度传感器可以感知周围的环境温度, 蓝牙部分可以实现远程操作, 实现自动和手动浇水的操作。 当然可以通过按键也可以实现自动和手动的操作。 液晶显示器也可以实时显示当前的温度和湿度信息。 */ char SET=0; char SdL=60; char SdH=80; char SET_Timer=5; sbit BG_LED=P2^4; sbit Jsq=P2^3; sbit buzz=P2^3; bit Open=0; char SETLBuff[5];//装载湿度数据 char SETHBuff[5];//装载温度数据数组 char blue_buff[16]={0}; char WdBuff[6];//装载湿度数据 char SdBuff[6];//装载温度数据数组 void sendString(char *p); unsigned char temp_val=0,humi_val=70; unsigned int set_gz=1000; void Get_DHTData(void) { if(dht11_value(&temp_val,&humi_val,DHT11_UINT8)==0) { SdBuff[0]=humi_val/10+'0'; //将湿度的整数部分的十位和个位分开 SdBuff[1]=humi_val%10+'0'; SdBuff[2]='%'; WdBuff[0]=temp_val/10+'0'; //将wen度的整数部分的十位和个位分开 WdBuff[1]=temp_val%10+'0'; WdBuff[2]=0xdf;WdBuff[3]='C'; sprintf(blue_buff,"X%dH%dD%dZ\r\n",temp_val,humi_val); sendString(blue_buff); } } void delay_xms(int xms) { char ix=0; for(;xms>0;xms--) for(ix=110;ix>0;ix--); } bit SET_Mode=0; bit CloseIfg=0; unsigned char BjCnt=0; bit TimeOpen=0; //开启后定时关闭变量 static unsigned int DsTimer=0; //倒计时计数器 void KeyRead(void) { static char keyIfg=0; unsigned char KeyVal=0; KeyVal = P3&0xF8; //读取按键值 if(KeyVal!=0xF8)//有按键按下了 { if(keyIfg==0) { keyIfg=1; switch(KeyVal) //判断键值 { case 0xF0: SET_Mode=~SET_Mode; CloseIfg=0; SET=0; break; case 0xE8: if(SET_Mode==0) { if(++SET>3)SET=0; } break; case 0xD8: if(SET_Mode==0) { if(SET==1) { if(++SdL>92)SdL=0; } if(SET==2) { if(++SdH>92)SdH=0; } if(SET==3) { if(set_gz<9990) { set_gz+=100; } } } break; case 0xB8: if(SET_Mode==0) { if(SET==1) { if(--SdL<0)SdL=92; } if(SET==2) { if(--SdH<0)SdH=92; } if(SET==3) { if(set_gz>100) { set_gz-=100; } } } break; case 0x78: //手动控制按键 if(SET_Mode) //手动模式下才能用 { Open^=1; } break; } } }else keyIfg=0; } void Time0Init(void) //40毫秒@11.0592MHz { TMOD &= 0xF0; //设置定时器模式 TMOD |= 0x01; //设置定时器模式 TL0 = 0x00; //设置定时初值 TH0 = 0x70; //设置定时初值 TF0 = 0; //清除TF1标志 TR0 = 1; //定时器1开始计时 ET0=1; EA=1; } uchar getTime=0; void ISR_T0()interrupt 1 { TL0 = 0x00; //设置定时初值 TH0 = 0x70; //设置定时初值 getTime++; KeyRead(); if(Open) { Jsq=0; }else { Jsq=1; } // if(SET_Mode==1&&Open)//定时模式 // { // if(SET_Timer>0) //定时模式递减 // { // if(++DsTimer>25)//1S时间到 // { // DsTimer=0; // SET_Timer--; // } // }else // { // Open=0; // } // } } void UartInit(void) //9600bps@11.0592MHz { PCON &= 0x7F; //波特率不倍速 SCON = 0x50; //8位数据,可变波特率 TMOD &= 0x0F; //清除定时器1模式位 TMOD |= 0x20; //设定定时器1为8位自动重装方式 TL1 = 0xFD; //设定定时初值 TH1 = 0xFD; //设定定时器重装值 ET1 = 0; //禁止定时器1中断 TR1 = 1; //启动定时器1 EA=1; ES=1; } void sendData(char *p,unsigned char n) { if( p == 0) return ; ES = 0; if(n > 0) { while(n --) { SBUF = *p++ ; while(!TI) ; TI = 0 ; } } ES = 1; } // 往串口发送字符串 void sendString(char *p) { if(p == 0) return ; sendData(p,strlen(p)); } bit SendIfg=0; unsigned char urx_dat=0; // 接收中断函数 void usart() interrupt 4 { if(RI == 1) { urx_dat = SBUF; switch(urx_dat) { case '@': SET_Mode=0; break; case '$': SET_Mode=1; break; case '&': if(SET_Mode)Open=1; break; case '*': if(SET_Mode)Open=0; break; } } RI = 0; TI = 0; } uint gz_val=0; void main(void) { Time0Init(); lcd1602_init(); WriteLcd1602_String(0,0," Welcome to use"); delay_xms(1000); Write_1602_com(0x01);//清显示 delay_xms(100); Get_DHTData(); delay_xms(50); BG_LED=1; UartInit(); while(1) { if(++getTime>20) { getTime=0; Get_DHTData(); // gz_val = BH1750_temp(); // if(gz_val>9999)gz_val=9999;//限制最大值 if(SET_Mode==0) //自动模式控制 { if(!CloseIfg) { CloseIfg=1; Write_1602_com(0x01);//清显示 delay_1ms(10); } if(SET==0)//工作模式 { WriteLcd1602_String(0,0,"Temp:"); WriteLcd1602_String(5,0,WdBuff); WriteLcd1602_String(0,1,"Humi:"); WriteLcd1602_String(5,1,SdBuff); WriteLcd1602_String(15,1,"A"); if(humi_valSdL&&humi_valSdH) { Open=0;//关闭 buzz=1; } }else //设置模式 { SETLBuff[0]=SdL/10+'0'; SETLBuff[1]=SdL%10+'0'; SETLBuff[2]='%'; SETLBuff[3]=' '; SETHBuff[0]=SdH/10+'0'; SETHBuff[1]=SdH%10+'0'; SETHBuff[2]='%'; SETHBuff[3]=' '; WriteLcd1602_String(9,0,"L:"); WriteLcd1602_String(11,0,SETLBuff); WriteLcd1602_String(9,1,"H:"); WriteLcd1602_String(11,1,SETHBuff); } } if(SET_Mode==1) //手动控制模式 { if(!CloseIfg) { CloseIfg=1; Write_1602_com(0x01);//清显示 delay_1ms(10); } if(SET==0) { // WriteLcd1602_String(0,0,"T:"); // WriteLcd1602_String(2,0,WdBuff); // // WriteLcd1602_String(9,0,"R:"); // WriteLcd1602_String(11,0,SdBuff); // WriteLcd1602_String(0,1,"light:"); // WriteLcd1602_String(6,1,GZ_Buff); // // WriteLcd1602_String(15,1,"B"); WriteLcd1602_String(0,0,"Temp:"); WriteLcd1602_String(5,0,WdBuff); WriteLcd1602_String(0,1,"Humi:"); WriteLcd1602_String(5,1,SdBuff); WriteLcd1602_String(15,1,"M"); } } } } }