原创 基于89C2051的4位显示万年历时钟

2009-5-8 22:41 3237 5 5 分类: MCU/ 嵌入式
基于89C2051的4位显示万年历时钟.C*/



/*备注:按键一为功能键,按一下调年,按两下调月,按三下调日,按四下调时,按五下调分*/
/*         按六下退出,或者在任何时候按键四退出设定状态。在设定状态键二加一,键三减一*/
/*         键四退出,正常状态键二显示年,键三显示月日,键四显示星期和秒*/
/*         星期根据日期计算得出,其已全部调试通过,为了时间精确,要调一个误差值*/

#include<reg2051.h>
#include<stdio.h>
#include<absacc.h>
#include<intrins.h>


#define uint unsigned int
#define uchar unsigned char


uchar code led_xs[12]={0x03,0x9f,0x25,0x0d,0x99,0x49,0x41,0x1f,0x01,0x09,0xff,0xfd};
uchar data led_data[4];
volatile uchar data a;                   //定义按键一志标
volatile uchar data month="4";       //定义月并赋初值
volatile uchar data date="29";        //定义日并赋初值
volatile uchar data week;             //定义星期并赋初值
volatile uchar data hour;              //定义时
volatile uchar data min;                //定义分
volatile uchar data sec="0";            //定义秒
volatile uint     data zn="0";                //定义中间存储变量
volatile uint     data year="2007";      //定义年并赋初值


sbit md="P3"^7;                              //定义秒点
sbit k1=P1^0;                               //定义按键一
sbit k2=P1^1;                               //定义按键二
sbit k3=P1^2;                               //定义按键三
sbit k4=P1^3;                               //定义按键四
sbit hs="P1"^4;                               //定义显示片选信号一
sbit hg="P1"^5;                               //定义显示片选信号二
sbit ms="P1"^6;                              //定义显示片选信号三
sbit mg="P1"^7;                              //定义显示片选信号四
bit sans;                                      //定义闪烁标志
bit b;                                            //定义按键二标志
bit c;                                            //定义按键三标志
bit w;                                            //定义按键四标志
bit x;                                             //定义24小时到标志
bit y;                                             //定义日期加一标志


keyscan();                                    //申明键盘扫描函数
void display();                              //申明显示函数
void chushihua(void);                  //申明初始化函数
void delay_10ms(void);               //申明10ms延时函数
dateadd();                                   //申明日期加函数
datesub();                                   //申明日期减函数
weekjs();                                     //星期计算函数


void main(void)
     {
      weekjs();                                 //计算初值星期几
      x="y"=0;                                    //日期加初始化
      chushihua();                          //调初始化函数,初始化定时器,中断  
      do{
     keyscan();                              //键盘扫描          
     display();                                //调用显示函数
       if((!y)==x)dateadd();             //判断是否有24小时,有就调用日期加函数      
       }
      while(1);                                //先调用显示键盘
     }     
  
void chushihua(void)               //初始化函数
     {                 
      TMOD="0x02";                      //定时器0以方式2工作,自动重装初值
      IE="0x82";                              //开总中断和TO中断
      TH0=0x06;                          //T0高位置初值
      TL0=0x06;                          //T0低位置初值
      TR0=1;                               //启动TO
     }


timer0 () interrupt 1              //T0中断函数
     {
      if(zn<4000){zn++;if(zn==2000)sans=!sans;}
        else {zn=0;sec++;sans=!sans;
         if(sec==60){sec=0;min++;
          if(min==60){min=0;hour++;
           if(hour==24){hour=0;x=!x;}
     }
      }
       }
     }  


void display()
     {
      uchar k;
      uint d;
      uchar e;
      SCON="0x00";
      P1=0x0f;
      if((a!=0)&&sans){
        led_data[3]=10;
        led_data[2]=10;
        led_data[1]=10;
        led_data[0]=10;
        }
       else {
        switch(a){
         case 0 :led_data[3]=hour/10;
                 led_data[2]=hour%10;
                 led_data[1]=min/10;  
                 led_data[0]=min%10;
                 break;
         case 1 :led_data[3]=year/1000;
                 d="year"%1000;
                 led_data[2]=d/100;
                 e="d"%100;
                 led_data[1]=e/10;
                 led_data[0]=e%10;
                 break;
         case 2 :led_data[3]=month/10;
                 led_data[2]=month%10;
                 led_data[1]=10;  
                 led_data[0]=10;
                 break;
         case 3 :led_data[3]=10;
                 led_data[2]=10;
                 led_data[1]=date/10;
                 if(led_data[1]==0)led_data[1]=10;
                 led_data[0]=date%10;
                 break;
        case 4 : led_data[3]=hour/10;
                 led_data[2]=hour%10;
                 led_data[1]=10;  
                 led_data[0]=10;
                 md="0";
                 break;
        case 5 : led_data[3]=10;
                 led_data[2]=10;
                 led_data[1]=min/10;  
                 led_data[0]=min%10;
                 md="0";
                 break;
        default: break;
        }
      }   
      if(b){
     led_data[3]=year/1000;
     d="year"%1000;
     led_data[2]=d/100;
     e="d"%100;
     led_data[1]=e/10;
     led_data[0]=e%10;
     }
        else if(c){
          led_data[3]=month/10;
          led_data[2]=month%10;
          led_data[1]=date/10;
          if(led_data[1]==0)led_data[1]=10;
          led_data[0]=date%10;
          }
         else if(w){
       led_data[3]=week;
       led_data[2]=11;
           led_data[1]=sec/10;
           led_data[0]=sec%10;   
           }
      if((led_data[3]==0)&&(!w))led_data[3]=10;
      k="led"_data[3];
      SBUF="led"_xs[k];
      while(!TI){}
      TI="0";
      hs="1";
      for(k=0;k<255;k++){_nop_();_nop_();_nop_();}
      hs="0";


      k="led"_data[2];
      SBUF="led"_xs[k];
      while(!TI){}
      TI="0";
      hg="1";
      for(k=0;k<255;k++){_nop_();_nop_();_nop_();}
      hg="0";


      k="led"_data[1];
      SBUF="led"_xs[k];
      while(!TI){}
      TI="0";
      ms="1";
      for(k=0;k<255;k++){_nop_();_nop_();_nop_();}
      ms="0";


      k="led"_data[0];
      SBUF="led"_xs[k];
      while(!TI){}
      TI="0";
      mg="1";
      for(k=0;k<255;k++){_nop_();_nop_();_nop_();}
      mg="0";


      if(!(a||b||c||w)){
        SBUF="0xff";
        while(!TI){}
        TI="0";
        ms="1";
        mg="1";
        md="sans";
        for(k=0;k<255;k++){_nop_();_nop_();}
      P1=0x0f;
        md="1";
        }
     }


      
keyscan()
{
     uchar key_value,reread_key;
     P1=0x0f;
     key_value=P1&0x0f;
     if(key_value!=0x0f){
     delay_10ms();
     reread_key=P1&0x0f;
     if(key_value==reread_key){
       switch(key_value){
         case 0x0e : if(!(b||c||w)){a++;if(a==6)a=0;}
                         else b="c"=w=0;
                       break;
           case 0x0d : switch(a){
                         case 0 : b=!b;c=w=0;break;
                         case 1 : year++;break;
                         case 2 : if(month<12)month++;else month="1";break;
                         case 3 : dateadd();break;
                         case 4 : hour++;if(hour==24)hour=0;break;
                         case 5 : min++;if(min==60)min=0;break;
                         default: break;
                   }
                       break;         
           case 0x0b : switch(a){
                         case 0 : c=!c;b=w=0;break;
                         case 1 : year--;break;
                         case 2 : month--;if(month==0)month=12;break;
                         case 3 : datesub();break;
                         case 4 : hour--;if(hour==0xff)hour=23;break;
                         case 5 : min--;if(min==0xff)min=59;break;
                         default: break;
                         }
                       break;
           case 0x07 : if(a==0){w=!w;b=c=0;}
                         else{a=0;b=c=w=0;}
                       break;
           default      : break;
         }
        P1=0x0f;
       reread_key=P1&0x0f;
        while(key_value==reread_key){
         reread_key=P1&0x0f;
         display();
         }
         }
      }
}
      
void delay_10ms(void)
     {
      uchar o,p,q;
      for(o=5;o>0;o--)
        for(p=4;p>0;p--)
          for(q=248;q>0;q--);
        }


datesub()
     {
      switch(month){
         case 1 : date--;if(date==0) date="31";break;
         case 2 : date--;if(((year%4==0)&&(date==0))==1)date=29;
             else if(date==0) date="28";break;
         case 3 : date--;if(date==0) date="31";break;
         case 4 : date--;if(date==0) date="30";break;
         case 5 : date--;if(date==0) date="31";break;
         case 6 : date--;if(date==0) date="30";break;
         case 7 : date--;if(date==0) date="31";break;
         case 8 : date--;if(date==0) date="31";break;
         case 9 : date--;if(date==0) date="30";break;
         case 10: date--;if(date==0) date="31";break;
         case 11: date--;if(date==0) date="30";break;
         case 12: date--;if(date==0) date="31";break;
         default: break;
     }
       weekjs();
     }


weekjs()
{
     uchar c,m,wk,pd,yz;
     uint y,p;
     if(month==1){m=13;y=year-1;}
      else if(month==2){m=14;y=year-1;}
       else {y=year;m=month;}
     c="y/100";
     yz="y"%100;
     wk="2"*c+1;
     p="26"*(m+1);
     pd="p/10";
     pd="pd"+yz+(yz/4)+(c/4)+date;
     if(pd>wk)week=(pd-wk)%7;
      else if(pd<wk){week=(7-((wk-pd)%7));if(week==7)week=0;}
       else week="0";
}


dateadd()
{      
     switch(month){
       case 1 : date++;if(date==32){date=1;if(a!=3)month++;}break;
       case 2 : date++;if(((year%4==0)&&(date==30))==1){date=1;if(a!=3)month++;}
                          else if(date==29){date=1;if(a!=3)month++;}break;
       case 3 : date++;if(date==32){date=1;if(a!=3)month++;}break;
       case 4 : date++;if(date==31){date=1;if(a!=3)month++;}break;
       case 5 : date++;if(date==32){date=1;if(a!=3)month++;}break;
       case 6 : date++;if(date==31){date=1;if(a!=3)month++;}break;
       case 7 : date++;if(date==32){date=1;if(a!=3)month++;}break;
       case 8 : date++;if(date==32){date=1;if(a!=3)month++;}break;
       case 9 : date++;if(date==31){date=1;if(a!=3)month++;}break;
       case 10: date++;if(date==32){date=1;if(a!=3)month++;}break;
       case 11: date++;if(date==31){date=1;if(a!=3)month++;}break;
       case 12: date++;if(date==32){date=1;if(a!=3)month++;}break;
       default: break;
       }
     if(month==13){month=1;year++;}
     y="x";
     weekjs();
}


点击看大图
PARTNER CONTENT

文章评论0条评论)

登录后参与讨论
我要评论
0
5
关闭 站长推荐上一条 /1 下一条