这是一个我做出来的51单片机的浇花系统,带有DHT11温湿度检测模块,以及土壤湿度检测模块,可以设置触发浇花的临界值,并且改进了浇水判断程序,避免在临界值抖动达不到浇水效果
这个1602显示、带DHT11的浇花系统的程序我们借鉴了51黑电子论坛上许多大佬的作品,在此对他们表示感谢٩(๑>◡<๑)۶,同时我们也对程序做了许多优化与更改,使得整个系统更具实用性,比如改进了浇水判断程序,避免在临界值抖动达不到浇水效果(〃'▽'〃)。但是时间紧,有一些地方并没有完善,比如没有加1602背光控制。还需要各位继续完善(*/ω\*),然后,成品我们已经测试过可以正常使用,如果出现异常请检查一下接线是否有误~
还有还有,水泵如果和单片机使用同一个电源,要滤波否则会影响1602的正常显示,最好使用独立的电源。原理图没画1602的对比度调节,大家可以自己加上!
制作出来的实物图如下:
电路原理图如下:
单片机源程序如下:
- /**************************
- 制作:华南农业大学 LSR
- ***************************/
- //程序头函数
- #include <reg52.h>
- #include <intrins.H>
- #include <math.H>
- //宏定义
- #define uint unsigned int
- #define uchar unsigned char
- #define Data_ADC0809 P1
-
- //管脚声明
- sbit Feng = P3^0;
- sbit DQ=P3^1; //DTH11
- //ADC0809
- sbit ST=P3^3;
- sbit EOC=P3^4;
- sbit OE=P3^2;
- //按键
- sbit Key1=P3^5;
- sbit Key2=P3^6;
- sbit Key3=P3^7;
- sbit rs=P2^2;
- sbit lcden=P2^0;
- sbit rw=P2^1;
- uchar code table_num[]="0123456789abcdefg"; //定义数组
- uchar tem;
- uchar hum;
- //函数声明
- extern uchar ADC0809();
- bit Init_DTH11() ;
- void delay_ms(uint z);
- void delay(uint t);
- void write_com(uchar com) ;
- void write_data(uchar dat) ;
- void write_sfm2(uchar hang,uchar add,uint date);
- void write_string(uchar hang,uchar add,uchar *p);
- void init() ;
- void Display(uchar X,uchar Data);
- void DTH11_DUSHU();
- void Display_DTH11();
-
- uchar DTH11_RD_CHAR();
- //湿度变量
- uchar temp=0;
- //蜂鸣器变量
- uchar FF=60;
- //显示模式
- uchar Mode=0;
- int F=0;
- void main()
- {
- tem=0;hum=0;
- init();
- write_string(2,0,"T:00'C RH:00%");
- while(1)
- {
- //正常模式
- if(Mode==0)
- {
- //读取AD值
- bit Init_DTH11() ;
- DTH11_DUSHU();
- Display_DTH11();
- delay(500);
- temp=ADC0809();
- delay(10);
- Display(0,temp);
- delay(100);
- //判断是否报警
- if(temp>FF)
- {
- F=1;
- Feng=0;
- }
- else if(temp<=FF&&temp>=(FF-20)&&F==1) {Feng=0;} //这里是当湿度下降20时停止浇水的程序,若想改变浇水多少,改20即可。
-
- else
- {
- Feng=1;F=0;
- }
- }
- //调整模式
- else
- {
- Display(1,FF);
- }
- //功能键
- if(Key3==0)
- {
- Feng=1;
- delay(10);
- while(Key3==0)
- {
- if(Mode==0)
- Display(0,temp);
- else
- Display(1,FF);
- }
- if(Mode==0)
- Mode=1;
- else
- Mode=0;
- Feng=1;
- }
- //增加
- if(Key2==0&&Mode==1)
- {
- Feng=1;
- delay(10);
- while(Key2==0)
- {
- Display(1,FF);
- delay(100);
- }
- FF++;
- if(FF==256)
- FF=255;
- Feng=1;
- }
- //减少
- if(Key1==0&&Mode==1)
- {
- Feng=1;
- delay(10);
- while(Key1==0)
- {
- Display(1,FF);
- }
- FF--;
- if(FF==-1)
- FF=0;
- Feng=1;
- }
-
- }
- }
- void delay_ms(uint z)
- {
- uint x,y;
- for(x=z;x>0;x--)
- for(y=114;y>0;y--);
- }
- void write_com(uchar com) //写命令函数
- {
- delay(5);
- lcden=0;
- rs=0;
- rw=0;
- delay(5);
- P0=com;
- delay(5);
- lcden=1;
- delay(25);
- lcden=0;
- }
- void write_data(uchar dat) //写数据函数
- {
- delay(5);
- lcden=0;
- rs=1;
- rw=0;
- delay(5);
- P0=dat;
- delay(5);
- lcden=1;
- delay(25);
- lcden=0;
- }
- /********************************************************************
- * 名称 : write_sfm2(uchar hang,uchar add,uchar date)
- * 功能 : 显示3位十进制数,如果要让第一行,第五个字符开始显示"23" ,调用该函数如下
- write_sfm1(1,5,23)
- * 输入 : 行,列,需要输入1602的数据
- * 输出 : 无 !!!还需测试的!!!!
- ***********************************************************************/
- void write_sfm2(uchar hang,uchar add,uint date)
- {
- if(hang==1)
- write_com(0x80+add);
- else
- write_com(0x80+0x40+add);
- delay(5);
- write_data(0x30+date/100%10);
- delay(5);
- write_data(0x30+date/10%10);
- delay(5);
- write_data(0x30+date%10);
- }
- /********************************************************************
- * 名称 : write_string(uchar hang,uchar add,uchar *p)
- * 功能 : 改变液晶中某位的值,如果要让第一行,第五个字符开始显示"ab cd ef" ,调用该函数如下
- write_string(1,5,"ab cd ef;")
- * 输入 : 行,列,需要输入1602的数据
- * 输出 : 无
- ***********************************************************************/
- void write_string(uchar hang,uchar add,uchar *p)
- {
- if(hang==1)
- write_com(0x80+add);
- else
- write_com(0x80+0x40+add);
- while(1)
- {
- if(*p == '\0') break;
- write_data(*p);
- p++;
- }
- }
- void init()
- {
- // uchar num;
- rw=0;
- lcden=0;
- write_com(0x38);
- write_com(0x0c);
- write_com(0x06);
- write_com(0x01);
- delay(1000);
- write_string(1,0,"shidu:") ;
- write_string(2,0,"T:00'C RH:00%");
-
- }
- //ADC0809读取信息
- uchar ADC0809()
- {
- uchar temp_=0x00;
- //初始化高阻太
- OE=0;
- //转化初始化
- ST=0;
- delay(5);
- //开始转换
- ST=1;
- ST=0;
- //外部中断等待AD转换结束
- while(EOC==0)
- //读取转换的AD值
- OE=1;
- temp_=Data_ADC0809;
- OE=0;
- return temp_;
- }
- bit Init_DTH11()
- {
- bit flag;
- uchar num;
- DQ=0;
- delay_ms(19); // >18ms
- DQ=1;
- for(num=0;num<10;num++); // 20-40us 34.7us
- for(num=0;num<12;num++);
- flag=DQ;
- for(num=0;num<11;num++); //DTH响应80us
- for(num=0;num<24;num++); //DTH拉高80us
- return flag;
- }
- //****************************读DTH11数据
- uchar DTH11_RD_CHAR()
- {
- uchar byte=0;
- uchar num;
- uchar num1;
- while(DQ==1);
- for(num1=0;num1<8;num1++)
- {
- while(DQ==0);
- byte<<=1; //高位在前
- for(num=0;DQ==1;num++);
- if(num<10)
- byte|=0x00;
- else
- byte|=0x01;
- }
- return byte;
- }
- //******************************读取DTH11温度和湿度
- void DTH11_DUSHU()
- {
- uchar num;
- if(Init_DTH11()==0)
- {
- hum=DTH11_RD_CHAR(); //比正常值高7度左右
- DTH11_RD_CHAR();
- tem=DTH11_RD_CHAR();
- DTH11_RD_CHAR();
- DTH11_RD_CHAR();
- for(num=0;num<17;num++); //最后BIT输出后拉低总线50us
- DQ=1;
- }
- }
- //**************显示函数
-
- ……………………
- …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码
所有资料51hei提供下载:
浇花系统.rar
(19.19 MB, 下载次数: 263)
|