C51 calendar clock program

Publisher:AngelicWhisperLatest update time:2016-11-24 Source: eefocusKeywords:c51 Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere

//Program function: calendar, clock, temperature display (temperature measurement code is not included yet, the program will exceed 4k after adding it, pay attention to the chip model selection), temperature sensor uses 18B20
//Calendar and clock, temperature time-sharing switching display, using 8-bit common anode digital tube
//Data output P1, bit code drive P2
//12864LCD display can also be used, the program is not written yet.
#include  
#include  
#define unchar unsigned char
#define unint unsigned int
unchar code dispcode[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,
                        0Xbf,0x9c,0xc6,0x7f,0xff}; //Digital tube font table, 0-9,-,o,C,.,extinguish
unchar code rili1997code[]={0x2,0x5,0x5,0x1,0x3,0x6,0x1,0x4,0x0,0x2,0X5,0x0}; //Month and week correction codes for the 12 months of 1996
unchar timecnt=19; //Timer interrupt counter          
unchar timeadd1=0; //Time plus 1 judgment
unchar newday=0; //Date plus 1 judgment
unchar week; //Week
unchar data date[]={9,12,9};
unchar data time[]={11,59,55};
unchar data wendu[]={14,19,116}; //wendu[0]=10 is negative, display -; wendu[0] =14 is positive, the sign bit is not displayed, Principle reference digital tube font table
                                 //wendu[1] is the integer temperature value, wendu[2]/10 is "°" display, wendu[2]/10+1 displays C, wendu[2]%110 is the temperature value after the decimal point   
unchar t=150; //Delay constant
unchar cnt=0; //Display control counter
//#define SSL 0x7f //Second low-order segment code address
//#define SSH 0XBF //Second high-order segment code address
//#define _L 0XDF //8-bit digital tube display, - separator between minutes and seconds
//#define MML 0XEF //The same as below
//#define MMH 0XF7
//#define _H 0XFB //8-bit digital tube display, - separator between hours and minutes
//#define HHL 0XFD
//#define HHH 0XFE
sbit timeset=P3^2; //Time adjustment key
sbit dateset=P3^3; //calendar adjustment key
sbit add=P3^4; //addition adjustment
sbit dec=P3^5; //subtraction adjustment


//Date plus 1 function
//Called when the date has a carry, to determine the maximum value of year, month and day
void dateadd1(unchar i)

  { unchar j=0;
 switch(i)
 { case 0:if(date[0]==99) //Year is represented by the lower 2 bits
             date[0]=0;
   else 
            date[0]++;break;
   case 1:if(date[1]==12)
             date[1]=1;
    else 
       date[1]++;break;
   case 2:
         switch(date[1])
        {case 4: //The maximum number of days in April, June, September and November is 30
        case 6: 
         case 9:
         case 11:if(date[2]==30)
                         {date[2]=1; 
              j++; //j++ means month plus 1, the same below
             }   
              else  
              {date[2]++; }
               break;
        case 1: //The maximum number of days in January, March, May, July, August, October and December is 31
        case 3:
        case 5:
        case 7:
      case 8:
      case 10:
      case 12: if(date[2]==31)
                             {date[2]=1; j++; } 
                   else
                    date[2]++; break;

       case 2:if(date[0]%400==0) //February needs to be judged whether it is a leap year
                          {if(date[2]==29) //A century year that is divisible by 400 is a leap year
                       {date[2]=1; j++; } //A leap year with 29 days in February, add 1 to the month
                     else
                     date[2]++;break; 
                     }   
                          else
                       {if(date[0]%4==0) //A non-century year that is divisible by 4 is a leap year
                          {if(date[2]==29)
                         {date[2]=1;j++; }
                          else
                          date[2]++; break;
                       }
                     else
                         {if(date[2]==28) //A non-leap year with 28 days in February
                         {date[2]=1;j++;}
                       else  
                       date[2]++; break;
                      }
                    }   
        default:break;
       
    }
    if(j)
     { if(date[1]==12) //If the carried month is December, set the month date[1] to 1
          date[1]=1;
    else
       date[1]++;

     }
}  }

}

void datedec1(unchar i)
{   unchar j=0;
    switch(i)
 { case 0: if(date[0]==0)
              date[0]=99;
     else
           date[0]--;break;
   case 1:if(date[1]==0)
             date[1]=12;
    else 
       date[1]--;break;
   case 2:
          switch(date[1])
    { case 4:      //4,6,9,11月的最大天数是30
    case 6: 
     case 9:
      case 11:if(date[2]==0)
                          date[2]=30; 
           else  
              date[2]--;
               break;
      case 1:     //1,3,5,7,8,10,12月的最大天数是31
      case 3:
       case 5:
        case 7:
      case 8:
      case 10:
      case 12: if(date[2]==0)
                             date[2]=31;   
                   else
                    date[2]--;  break;

       case 2:if(date[0]%400==0) //February needs to be judged whether it is a leap year
                          {if(date[2]==0) //A century year that is divisible by 400 is a leap yeardate
                       [2]=29; //A leap year has 29 days in February, and the month is carried
                     else
                     date[2]--;break; 
                     }   
                          else
                       {if(date[0]%4==0) //A non-century year that is divisible by 4 is a leap year
                          {if(date[2]==0)
                         date[2]=29;
                          else
                          date[2]--; break;
                       }
                     else
                         {if(date[2]==0) //A non-leap year has 28 days in February
                         date[2]=28;
                       else  
                       date[2]--; break;
                      }
                    }   
        default:break;
       
    }
    
   }
}

void add1(unchar i) //time plus 1 function

if(i) 
  { 
     timeadd1--;
     if(time[2]==59) //seconds plus 1
       {time[2]=0;
        time[1]++;
      if(time[1]==60) //minutes plus 1
        {time[1]=0;
         time[0]++;  
       if(time[0]==24) //hours plus 1
         { time[0]=0;
     newday++;
    }
   }
  }
   else
    time[2]++; 
 }
//if(newday)
// {
// dateadd1(newday);
// }  
 }

//Delay function
void delay(unchar x)   
{unsigned char i=0;
   while(i  i++;
}
//Display function:
//(1) Display time, format: HH(2 digits)-(1 digit)MM(2 digits)(1 digit empty)SS(2 digits)(8 digits in total), 
//(2) Display calendar, format: month(2 digits)-(1 digit)day(2 digits)(2 digits empty)week(1 digit), 
//(3) Display date (only appears when adjusting the date), format: year-month-day       
//(4) Display temperature  
//(5) Display process: the first 25 seconds of 30 seconds display time, the last 5 seconds display calendar
void display(unchar x,unchar y,unchar z,unchar r,unchar k)      
{ unchar a=150;                                    
   cnt++;                                       
  if(cnt==300)             
     cnt=0; //Function instructions:
      if(((r!=5)&&(r!=2))||(cnt>a)||(r==6)) //Display function parameters x, y, z, corresponding to the hour, minute, second of the time, or the year, month, day of the date
         {if(r==6)
       P1=dispcode[z/10+1];
    else
       P1 =dispcode[z%10]; //Or display the month, day, week of the calendar, or the positive or negative temperature, temperature, oC.   
          P2 =0x7f;//SSL; //k: week control parameter, when displaying the calendar, k=1, the week displays a single digit, when k is other values, it does not affect other display modes
          delay(t); //r: display control parameter, when r takes different values, the item to be adjusted flashes, and only the flashing item can be adjusted using the keyboard.
   if( k!=1) //When r is 0, 1, 2, the corresponding hh, mm, ss will flash and enter adjustment. When r is 3, 4, 5, the corresponding year, month, day will flash and adjust
        {P1=dispcode[z/10]; //When r=6, it is a special way to display temperature
            P2=0xbf;//SSH; //
            delay(t);
      }
   }
    if(((r!=4)&&(r!=1))||(cnt>a)||(r==6))
         { if(r==6)
        P1=dispcode[y%10]-0x80; //Used to display decimal point
    else 
        P1 =dispcode[y%10];
          P2=0xef;//MML; //
        delay(t);
    if(r==6) //When the high bit of temperature is 0, it is not displayed
    if(y/10==0)
       P1=dispcode[14];
    
    P1=dispcode[y/10];
          P2=0xf7;//MMH; //
          delay(t);
          }

   if((r==6)||((r!=3)&&(r!=0))||(cnt>a))
      {if(r==6)
      P1=0XFF;
    else
       P1 =dispcode[x%10];
     P2=0xfd;//HHL;
           delay(t);
    if(r==6)
       P1=0XFF;
    else
            P1=dispcode[x/10];
         P2=0xfe;//HHH;
         delay(t);
          }
       
    if((r==6)||(cnt>a)) //r=6 can be used for temperature measurement display control
        {if(r==6)
     P1=dispcode[wendu[0]];
   else
     P1 =dispcode[10];//dispcode[y%10];
         P2=0xfb;//_H;
         delay(t);
   }
   if(r==6)
   {P1=dispcode[wendu[2]%110];
    P2=0xdf;
    delay(t);
   }
  
 }

void keyscan()       //键盘扫描函数,用于扫描P3.2(timeset),P3.3(dateset),P3.4(add),P3.5(dec)键是否按下
{ unchar i=0,j=0;
if(dateset==0)
     {display(date[0],date[1],date[2],8,0);       //延时
      if(dateset==0)
      while(i<3)
    {   display(date[0],date[1],date[2],i,0);
      if(add==0)
        {display(date[0],date[1],date[2],i,0);
         if(add==0)
         dateadd1(i);
      display(date[0],date[1],date[2],i,0);
      display(date[0],date[1],date[2],i,0);
      display(date[0],date[1],date[2],i,0);
      display(date[0],date[1],date[2],i,0);
      }
      if(dec==0)
      {display(date[0],date[1],date[2],i,0);
       
       if(dec==0)
       datedec1(i);
       display(date[0],date[1],date[2],i,0);
       display(date[0],date[1],date[2],i,0);
       display(date[0],date[1],date[2],i,0);
       display(date[0],date[1],date[2],i,0);
      }
      if(dateset==0)
         {display(date[0],date[1],date[2],i,0);
          if(dateset==0)
        i++;
     display(date[0],date[1],date[2],i,0);
     display(date[0],date[1],date[2],i,0);
     display(date[0],date[1],date[2],i,0);
     display(date[0],date[1],date[2],i,0);
      }
     
     }
   } 
         
if(timeset==0)
     {delay(100);       //短暂延时
      if(timeset==0)
      delay(100);
    
        while(j<3)
      { display(time[0],time[1],time[2],j,0);
      if(add==0)
        {delay(200);
         if(add==0)
        { //delay(200);
     switch(j)
        {case 0:if(time[0]==24)
                  time[0]=0;
        else
         time[0]++;break;
         display(time[0],time[1],time[2],j,0);
      case 1:
      case 2:if(time[j]==60)
                time[j]=0;
        else
           time[j]++;
      default:break;
      } //delay(100);
     // display(time[0],time[1],time[2],j,0);
         }
        }     
      if(dec==0)
      {delay(200);
       if(dec==0)
       switch(j)
       {case 0:if(time[0]==0)
                  time[0]=23;
        else
         time[0]--;break;
         display(time[0],time[1],time[2],j,0);
           case 1:
      case 2:if(time[j]==0)
                time[j]=59;
        else
           time[j]--;
           display(time[0],time[1],time[2],j,0);
      default:break;
     } delay(100);
      }
      if(timeset==0)
         {
         display(time[0],time[1],time[2],j,0);
         //display(time[0],time[1],time[2],j,0);
          if(timeset==0)
        j++;
      }
     
     }
   
    }            
}

 

 

 


void datetoweek(unchar x,unchar y,unchar z,unchar p) //Calculate the day of the week for the specified date, x, y, z are year, month, day respectively;
{if(p) 
  { int year;
     year=1997+x+3;
     dateadd1(2);
  newday--;

 if((year%400)==0) //p is the condition for whether to execute the function, that is, the variable newday (generated by the carry of hh),
   {if(y<3) //When hh has no carry, newday=0, do not execute the function 
         {unchar i,j; //Date plus 1, calendar adjustment
      j=rili1997code[y-1];     
      i=(((year-1997)/4+(year-1997)+j)-1); 
      week=(z+i+1)%7; //
       }
       else
       {unchar i,j;
        j=rili1997code[y-1];
         i=(((year-1997)/4+(year-1997)+j));
         week=(z+i+1)%7;
          }
   }
  else
      { if(year%4==0)
     {if(y<3)
          {unchar i,j;
           j=rili1997code[y-1];
           i=(((year-1997)/4+(year-1997)+j)-1);
           week=(z+i+1)%7;
           }
            else
           {unchar i,j      ;
            1997code[y-1             ] ;
            i=(((year-1997)/4+(year-1997)+j))     ;             week     =             (z+i+1)%
            7 ;
              }
     }
  }       }







 void displaycontrol() //Display control function

  if(time[2]%30<=20) //The first 25 seconds of 30 seconds display time, and the last 5 seconds display calendardisplay
    (time[0],time[1],time[2],7,0);
  //if((time[2]%30<=25)&&(time[2]%30>20))
  else
    if(time[2]%30<=25)
    display(date[1],date[2],week,8,1);
 // if((time[2]%30<=30)&&(time[2]%30>25))
     else
       display(wendu[0],wendu[1],wendu[2],6,0);
}

void main(void) // Main function

   
  TMOD=0x01; 
  TH0=((65535-50000)/256); //Assign initial value to timer
  TL0=((65535-50000)%256);
  ET0=1; 
  EA=1;
  TR0=1;
  while(1) 
    {
    keyscan(); //Keyboard scan
 add1(timeadd1); //Add 1
    datetoweek(date[0],date[1],date[2],newday);
    displaycontrol(); //Time, calendar, temperature, etc. display control
    } 
 }

 void t0 (void)interrupt 1 using 0 //Timer interrupt function
{

  TH0+=((65536-50000)/256);
  TL0+=((65536-50000)%256);
  timecnt--;
if ( timecnt == 0 )
  { timecnt = 19 ;
     timeadd1++;
   }
} }


Keywords:c51 Reference address:C51 calendar clock program

Previous article:Summary of Accurate Delay in Keil C51 Programming
Next article:Why should the P0~P3 ports of the 89C51 microcontroller be set to 1 when inputting?

Latest Microcontroller Articles
  • Download from the Internet--ARM Getting Started Notes
    A brief introduction: From today on, the ARM notebook of the rookie is open, and it can be regarded as a place to store these notes. Why publish it? Maybe you are interested in it. In fact, the reason for these notes is ...
  • Learn ARM development(22)
    Turning off and on interrupts Interrupts are an efficient dialogue mechanism, but sometimes you don't want to interrupt the program while it is running. For example, when you are printing something, the program suddenly interrupts and another ...
  • Learn ARM development(21)
    First, declare the task pointer, because it will be used later. Task pointer volatile TASK_TCB* volatile g_pCurrentTask = NULL;volatile TASK_TCB* vol ...
  • Learn ARM development(20)
    With the previous Tick interrupt, the basic task switching conditions are ready. However, this "easterly" is also difficult to understand. Only through continuous practice can we understand it. ...
  • Learn ARM development(19)
    After many days of hard work, I finally got the interrupt working. But in order to allow RTOS to use timer interrupts, what kind of interrupts can be implemented in S3C44B0? There are two methods in S3C44B0. ...
  • Learn ARM development(14)
  • Learn ARM development(15)
  • Learn ARM development(16)
  • Learn ARM development(17)
Change More Related Popular Components

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

About Us Customer Service Contact Information Datasheet Sitemap LatestNews


Room 1530, 15th Floor, Building B, No.18 Zhongguancun Street, Haidian District, Beijing, Postal Code: 100190 China Telephone: 008610 8235 0740

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号