(共享资料)自己做的基于stc89c51单片机的自动浇花系统,有自动和手动两种模式,可以设置湿度的上下限,利用lcd1602显示,有一点遗憾的是设置湿度上下限时,没有光标闪动提示,希望大家给点建议,帮助改进,我把源程序附在这。
仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)
原理图:
单片机源代码:
- #include<reg51.h>
- #define uchar unsigned char
- #define uint unsigned int
- sbit ad_cs=P1^3; //ADC0832的控制位
- sbit ad_clk=P1^0;
- sbit ad_dat=P1^1;
- sbit lcd_rs=P2^7; //LCD1602的控制位
- sbit lcd_e=P2^6;
- sbit key1=P1^4; //独立按键
- sbit key2=P3^2;
- sbit key3=P3^3;
- sbit relay=P1^6; //继电器
- bit flag=1; //工作模式标志
- bit flag_motor=1; //手动模式下,抽水机开关标志
- bit flag_jia=0;
- bit flag_jian=0;
- uchar Hum_H=60; //自动模式下,湿度设定最大值
- uchar Hum_L=30; //自动模式下,湿度设定最小值
- uchar num=0;
- /********************延时函数1ms*****************
- void delay_ms(uint a)
- {
- uint i;
- while(a--)
- for(i=0;i<125;i++);
- }
- *************************************/
- /*******************延时函数50us******************/
- void delay_50us(uint a)
- {
- uint i;
- while(a--)
- for(i=0;i<19;i++);
- }
- /*************************************/
- /*******************ADC读取******************/
- uchar read_ad(uchar channel)
- {
- uchar i;
- uchar dat1,dat2;
- ad_clk=0;
- ad_cs=0;
- ad_dat=1;
- ad_clk=1;
- ad_clk=0; //起始信号
- ad_dat=1;
- ad_clk=1;
- ad_clk=0; //选择单通道模式
- ad_dat=channel;//0对应通道0,1对应通道1
- ad_clk=1;
- ad_clk=0;
- ad_dat=1;
- for(i=0;i<8;++i)
- {
- ad_clk=1;
- ad_clk=0;
- dat1=dat1<<1;
- if(ad_dat)
- dat1|=0x01;
-
- }
- for(i=0;i<8;i++)
- {
- dat2=dat2>>1;
- if(ad_dat)
- dat2|=0x80;
-
- ad_clk=1;
- ad_clk=0;
- }
- ad_cs=1;
- return (dat1==dat2)?dat1:0;
-
- }
- /*************************************/
- /*******************LCD1602初始化******************/
- void write_com(uchar com) //写指令
- {
- lcd_e=0;
- lcd_rs=0;
- P0=com;
- delay_50us(10);
- lcd_e=1;
- delay_50us(10);
- lcd_e=0;
- }
- void write_data(uchar dat) //写数据
- {
- lcd_e=0;
- lcd_rs=1;
- P0=dat;
- delay_50us(10);
- lcd_e=1;
- delay_50us(10);
- lcd_e=0;
- }
- void init_lcd1602() //lcd 初始化
- {
- delay_50us(300);
- write_com(0x38);
- delay_50us(100);
- write_com(0x38);
- delay_50us(100);
- write_com(0x38);
- write_com(0x38);
- write_com(0x08);
- write_com(0x01);
- write_com(0x06);
- write_com(0x0c);
- }
- void display_shu(uchar add,uchar dat) //显示数字
- {
- uchar l,m;
-
- // k=dat/100;
- l=dat%100/10;
- m=dat%10;
- write_com(0x80+add);
- // write_data(k+0x30);
- write_data(l+0x30);
- write_data(m+0x30);
- }
- void display_string(uchar add,uchar *dat) //显示字符串
- {
- uchar i;
- write_com(0x80+add);
- while(dat!=0&&(*dat!='\0')&&i<16)
- {
- write_data(*dat);
- dat++;
- i++;
- if(i==15) i=0;
- }
- }
- /*****************************************/
- /****************主函数*******************/
- void main()
- {
- EA=1; //开总中断
- EX0=1; //开外部中断0
- EX1=1; //开外部中断1
- IT0=0; //外部中断0触发方式为低电平
- IT1=0; //外部中断1触发方式为低电平
-
- init_lcd1602();
-
- display_string(0,"Hum: %"); //实时显示当前的湿度
- display_string(11,"H: %"); //显示设置的湿度最大值
- display_string(0x40,"Mode:"); //显示工作模式
- display_string(0x40+11,"L: %"); //显示设置的湿度最小值
- while(1)
- {
- uchar i;
-
- i=100-read_ad(0)*0.39;
- display_shu(4,i);
- display_shu(13,Hum_H);
- display_shu(0x40+13,Hum_L);
- if(key1==0)
- {
- delay_50us(100);
- if(key1==0)
- {
- while(!key1);
- num++;
- if(num>2) num=0;
- }
-
- switch (num) //选择工作模式和调整湿度设置最大、最小值
- {
- case 0:flag=~flag;
- flag_jia=0;
- flag_jian=0;
- //write_com(0x80+0x40);
- //write_com(0x0f);
- break;
- case 1://write_com(0x80+9);
- //write_com(0x0f);
- //delay_50us(1000);
- //write_com(0x0c);
- flag_jia=1;
- flag_jian=0;
- break;
- case 2://write_com(0x80+0x40+9);
- //write_com(0x0f);
- //delay_50us(1000);
- //write_com(0x0c);
- flag_jian=1;
- flag_jia=0;
- break;
- }
- if(flag==0&&num==1)
- {
- flag=~flag;
- num=0;
- flag_jia=0;
- flag_jian=0;
- }
- }
- if(flag==0) //手动模式
- {
-
- display_string(0x40+5,"MT");
- if(flag_motor) relay=1;
- else if(i<Hum_H) relay=0; //不能超过湿度最大值
- else relay=1;
- }
- else //自动模式
- {
- display_string(0x40+5,"AT");
- if(i<(Hum_L+Hum_H)/2) //最大和最小值的平均值作为抽水的判断条件
- {
- relay=0;
- }
- else relay=1;
- }
- }
- }
- /********************************************/
- /***********************外部中断*********************/
- void int0() interrupt 0
- {
- delay_50us(20);
- if(key2==0)
- while(!key2);
- flag_motor=~flag_motor;
- if(flag&&flag_jia)
- {
- //write_com(0x80+9);
- //write_com(0x0f);
- //delay_50us(1000);
- //write_com(0x0c);
- //delay_50us(1000);
- Hum_H++;
- if(Hum_H>=99) Hum_H=99;
- }
- if(flag&&flag_jian)
- {
- //write_com(0x80+0x40+9);
- //write_com(0x0f);
- //delay_50us(1000);
- //write_com(0x0c);
- //delay_50us(1000);
- Hum_L++;
- if(Hum_L>=Hum_H) Hum_L=Hum_H-1;
- }
- }
- void int1() interrupt 2
- {
- delay_50us(20);
- if(key3==0)
- while(!key3);
- if(flag&&flag_jian)
- {
- //write_com(0x80+0x40+9);
- //write_com(0x0f);
- //delay_50us(1000);
- //write_com(0x0c);
- //delay_50us(1000);
- Hum_L--;
- if(Hum_L<=1) Hum_L=1;
- }
- if(flag&&flag_jia)
- {
- //write_com(0x80+9);
- //write_com(0x0f);
- //delay_50us(1000);
- //write_com(0x0c);
- //delay_50us(1000);
- Hum_H--;
- if(Hum_H<=Hum_L) Hum_H=Hum_L+1;
- }
- }
- /********************************************/
复制代码 全部资料51hei下载地址:
基于51单片机的自动浇花系统.zip
(33.96 KB, 下载次数: 1461)
|