基于51单片机自动定时浇花程序

2019-04-15 18:58发布

        2018年的春节是一个很特别的一段时光,留在外地没有回老家过年。其实一开始也过得很是无聊,天天睡到自然醒——看看电视、玩玩游戏——随便无规律的吃点。呵呵……就这样任性的堕落。        俗话说得好啊!就是有龙肉,天天让你吃也会腻。看来贱命一条,没几天就实在过不了这种孤单寂寞冷的日子。出门走走逛逛花市打发打发无聊的时光。真是江湖之大各有各的特 {MOD},在老家亲朋好友相互走访热闹非凡;在花市五彩缤纷花香飘逸,熙熙攘攘、人流如潮。其实我很清楚我此行上目的,就是走走散散心别无他求。此情此景渲染,蠢蠢欲动实在按耐不住开心剁手的节奏购买几盘心仪的盘栽。        冲动是魔鬼啊!怎么剁手前没想到自个儿的工作性质呢!!时常浪荡周游不定的去处不定的归期,这些需要悉心料理的盘栽看来只能面对不久将来缺水遭殃的杯具。忽然灵光一动,怎么不想个办法制作一自动浇花的系统呢?阿三一言不合就开挂,对理工男来说像是忽然抓到了一根救命的稻草,心动不如行动,翻箱倒柜的找出尘封已久的单片机开发板及电子元件和工具。重新给电脑安装开发工具和各种硬件驱动。最苦的是没有水泵啊!!!此时此刻各位快递小哥都已欢度春节,奈何求助宝宝网、东东网、当当网……都不是明智之举吖!事实再次证明男人成功的背后一定有位强大女人,此时我背后有位美貌与智慧并存女朋友拉着说要去买金鱼,不说鱼好不好看,哈哈……反正没兴趣。开心的是我在此处却意外的发现了让我刚才还揪心物拾,真的没想到这里会有微型水泵哞!一切准备就绪了,只差后面东风吹又生了。准备买好鱼回去发力吧!        无聊堕落的时光不复存在,将来迎来激情满满的充实有意思的快乐时光。毕业后放手已久对单片机的操作已打得林丁破碎,还好就是激情尚在,通过数天的编写调试,最终将设想的目标达成。        通过8位数码管来显示时钟的时分秒信息,再通过8位独立按键来实现时分秒的校正,然后通过1位继电器的隔离输出去控制水泵抽水喷淋花花草草。        完整的程序代码如下,仅供参考学习,也欢迎各位大神指点完善。感谢、感谢、十分感谢!/*
1、在HC6800EM3实验板上实现数码管的动太扫描显示24小时时钟;采用独立键盘来修改校正时钟,K1为小时加,K5为小时减,
 K2为分钟加,K6为分钟减,K3为秒钟加,K7为秒钟减,K4为定时器中断停止,K8为定时器中断启动。
2、接线为P0口接到J12,P2口接到J16,P1口接到JP5,P3.0口接继电器输出,再通过触点控制水泵工作;
3、主要功能之一是时钟显示;第二功能是跟据花卉的浇水需求,将浇水时间设定为每隔五天的早上6:30:00开始浇水6:30:30停止浇水;
4、实验时间:2018年2月22日;
*/#include
sbit relay=P3^0;unsigned char code position[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f}; //数码管位选
unsigned char code paragraph[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}; //共阴极数码管段选
//                                                       0       1       2      3      4      5       6       7      8      9void display();       //显示函数申明
void initialize();      //初始化函数申明
void delay_ms(unsigned char time);  //延时函数申明
void delay_us(unsigned char time);  //延时函数申明
void key_scan();      //键盘扫描函数申明
void relay_out();      //继电器控制输出函数申明unsigned char day,hour,minute,second,temporary,hour_SW,hour_GW,   //定义全局变量
      minute_SW,minute_GW,second_SW,second_GW;void main()  //主程序
{
 initialize();
 while(1)
 {
  key_scan();
  relay_out();
  display();
 } 
}
 
void display()  //8位数码管显示函数
{
 second_SW=second/10;
 second_GW=second%10;
 minute_SW=minute/10;
 minute_GW=minute%10;
 hour_SW=hour/10;
 hour_GW=hour%10; P2=position[0];   //秒钟位选
 P0=paragraph[second_GW];
 delay_us(150);   //150时显示比较稳定
 P2=position[1];
 P0=paragraph[second_SW];
 delay_us(150);
 P2=position[2];
 P0=0x40;
 delay_us(150);
 P2=position[3];   //分钟位选
 P0=paragraph[minute_GW];
 delay_us(150);
 P2=position[4];
 P0=paragraph[minute_SW];
 delay_us(150);
 P2=position[5];
 P0=0x40;
 delay_us(150);
 P2=position[6];   //时钟位选
 P0=paragraph[hour_GW];
 delay_us(150);
 P2=position[7];
 P0=paragraph[hour_SW];
}void timer_1() interrupt 1  //定时器中断函数,定时器0、中断1
{
 TH0=(65536-50000)/256; //每次进入中断程序时重新装初值。计时50ms
 TL0=(65536-50000)%256;
 temporary++;
 if(temporary==20)
 {
  temporary=0;
  second++; 
  if(second==60)
  {
   second=0;
   minute++;
   if(minute==60)
   {
    minute=0;
    hour++;
    if(hour==24)
    {
     hour=0;
     day++;
    }
   }
  }
 }
}void initialize()  //初始化函数
{ TMOD=0x01; //设置定时器0为工作方式1
 TH0=(65536-50000)/256; //(16位的最大值-需要定时的长度)/256; 此计算将求得的整数部份放到
         //高8位,意思为求模。
 TL0=(65536-50000)%256;  //(16位的最大值-需要定时的长度)/256; 此计算将求得的余数部份放到
         //低8位,意思为求余。
 EA=1;  //开总中断。
 ET0=1; //开定时器0中断。
 TR0=1; //启动定时器0
 
 hour=0;   hour_SW=0; hour_GW=0;
 minute=0;  minute_SW=0; minute_GW=0;
 second=0;  second_SW=0; second_GW=0;
 temporary=0; 
}void delay_ms(unsigned char time) //当i=X时为Xms的延时程序。
{
    unsigned char a,b;
    for(time;time>0;time--)
     for(b=142;b>0;b--)
      for(a=2;a>0;a--);
}
void delay_us(unsigned char time) //数码管扫描延时程序。
{
   unsigned char a,b;
 for(time;time>0;time--)
    for(b=1;b>0;b--)
     for(a=2;a>0;a--);
}void key_scan() //独立键盘扫描函数
{
 unsigned char keyboard;
 keyboard=P1;
 if(keyboard!=0xff)
 {
   delay_ms(10);
  if(keyboard!=0xff)
  {
   switch(keyboard)
   {
    case 0xfe:hour++;  //K1按键,用于小时校正 加加
      if(hour==24)
      {
      hour=0;
      day++;
      }      
      break;
    case 0xef:hour--;   //K5按键,用于小时校正 减减
       if(hour==0)
      {
      hour=23;
      day--;
      if(day<=0) day=0;
      }
       break;
    case 0xfd:minute++;  //K2按键,用于分钟校正 加加
     if(minute==60)
     {
      minute=0;
      hour++;
      if(hour==24)
      {
       hour=0;
       day++;
      }
     }
     break;
    case 0xdf:minute--;   //K6按键,用于分钟校正 减减
     if(minute==0)
     {
      minute=59;
      hour--;
      if(hour==0)
      {
       hour=23;
       day--;
       if(day<=0) day=0;
      }
     }
     break;
    case 0xfb:second++;   //K3按键,用于秒钟校正 加加
     if(second==60)
     {
      second=0;
      minute++;
      if(minute==60)
      {
       minute=0;
       hour++;
       if(hour==24)
       {
        hour=0;
        day++;
       }
       
      }
     }
    break;
    case 0xbf:second--;   //K7按键,用于秒钟校正 减减
     if(second==0)
     {
      second=59;
      minute--;
      if(minute==0)
      {
       minute=59;
       hour--;
       if(hour==0)
       {
        hour=23;
        day--;
        if(day<=0) day=0;
       }
      }
     }
    break;
    case 0xf7: TR0=0; break; //K4按键,用于在校正时间时停止定时器中断
    case 0x7f: TR0=1; break; //K8按键,用于在校正时间后激活启动定时器中断
    default:P1=0xff;
   }
  }
 }
 keyboard=P1 ;
 while(!keyboard);
 delay_ms(10);
 while(!keyboard);
}void relay_out() //断电器输出控制水泵抽水浇花,当前设定为每隔5天浇水30秒。
{
 if(day==5)
 {  
  if(hour==6)
  {
   if(minute==30)
   {
    relay=0;
    if(second==30)
    {
     relay=1;
     day=0;
    }
   }
  }
 }
}