www.pudn.com > ucosii_block.rar > CLK.C


/* 
********************************************************************************************************* 
*                                             Clock/Calendar 
* 
*                            (c) Copyright 1999, Jean J. Labrosse, Weston, FL 
*                                           All Rights Reserved 
* 
* Filename   : CLK.C 
* Programmer : Jean J. Labrosse 
********************************************************************************************************* 
*/ 
 
/* 
********************************************************************************************************* 
*                                              INCLUDE FILES 
********************************************************************************************************* 
*/ 
 
#define  CLK_GLOBALS                   /* CLK.H is informed to allocate storage for globals            */ 
#include "includes.h" 
 
/* 
********************************************************************************************************* 
*                                            LOCAL CONSTANTS 
********************************************************************************************************* 
*/ 
 
#define  CLK_TS_BASE_YEAR    2000      /* Time stamps start year                                       */ 
 
/* 
********************************************************************************************************* 
*                                            LOCAL VARIABLES 
********************************************************************************************************* 
*/ 
 
static  OS_EVENT   *ClkSem;            /* Semaphore used to access the time of day clock               */ 
static  OS_EVENT   *ClkSemSec;         /* Counting semaphore used to keep track of seconds             */ 
 
static  OS_STK      ClkTaskStk[CLK_TASK_STK_SIZE]; 
 
static  INT8U       ClkTickCtr;        /* Counter used to keep track of system clock ticks             */ 
 
 
/*$PAGE*/ 
/* 
********************************************************************************************************* 
*                                              LOCAL TABLES 
********************************************************************************************************* 
*/ 
 
#if CLK_DATE_EN 
static  char *ClkDOWTbl[] = {          /* NAME FOR EACH DAY OF THE WEEK                                */ 
    "Sunday ", 
    "Monday ", 
    "Tuesday ", 
    "Wednesday ", 
    "Thursday ", 
    "Friday ", 
    "Saturday " 
}; 
 
 
static  CLK_MONTH ClkMonthTbl[] = {    /* MONTHS TABLE                                                 */ 
    {0,  "",           0},             /* Invalid month                                                */ 
    {31, "January ",   6},             /* January                                                      */ 
    {28, "February ",  2},             /* February (note leap years are handled by code)               */ 
    {31, "March ",     2},             /* March                                                        */ 
    {30, "April ",     5},             /* April                                                        */ 
    {31, "May ",       0},             /* May                                                          */ 
    {30, "June ",      3},             /* June                                                         */ 
    {31, "July ",      5},             /* July                                                         */ 
    {31, "August ",    1},             /* August                                                       */ 
    {30, "September ", 4},             /* September                                                    */ 
    {31, "October ",   6},             /* October                                                      */ 
    {30, "November ",  2},             /* November                                                     */ 
    {31, "December ",  4}              /* December                                                     */ 
}; 
#endif 
 
/* 
********************************************************************************************************* 
*                                        LOCAL FUNCTION PROTOTYPES 
********************************************************************************************************* 
*/ 
 
        void          ClkTask(void *data); 
static  BOOLEAN       ClkUpdateTime(void); 
 
#if     CLK_DATE_EN 
static  BOOLEAN       ClkIsLeapYear(INT16U year); 
static  void          ClkUpdateDate(void); 
static  void          ClkUpdateDOW(void); 
#endif 
 
/*$PAGE*/ 
/* 
********************************************************************************************************* 
*                                    FORMAT CURRENT DATE INTO STRING 
* 
* Description : Formats the current date into an ASCII string. 
* Arguments   : n      is the format type: 
*                      1   will format the time as "MM-DD-YY"           (needs at least  9 characters) 
*                      2   will format the time as "Day Month DD, YYYY" (needs at least 30 characters) 
*                      3   will format the time as "YYYY-MM-DD"         (needs at least 11 characters) 
*               s      is a pointer to the destination string.  The destination string must be large 
*                      enough to hold the formatted date. 
*                      contain 
* Returns     : None. 
* Notes       : - A 'switch' statement has been used to allow you to add your own date formats.  For 
*                 example, you could display the date in French, Spanish, German etc. by assigning 
*                 numbers for those types of conversions. 
*               - This function assumes that strcpy(), strcat() and itoa() are reentrant. 
********************************************************************************************************* 
*/ 
 
#if  CLK_DATE_EN 
void  ClkFormatDate (INT8U n, char *s) 
{ 
    INT8U   err; 
    INT16U  year; 
    char    str[5]; 
 
 
    OSSemPend(ClkSem, 0, &err);                  /* Gain exclusive access to time-of-day clock         */ 
    switch (n) { 
        case  1: 
              strcpy(s, "MM-DD-YY");             /* Create the template for the selected format        */ 
              s[0] = ClkMonth / 10 + '0';        /* Convert DATE to ASCII                              */ 
              s[1] = ClkMonth % 10 + '0'; 
              s[3] = ClkDay   / 10 + '0'; 
              s[4] = ClkDay   % 10 + '0'; 
              year = ClkYear % 100; 
              s[6] = year / 10 + '0'; 
              s[7] = year % 10 + '0'; 
              break; 
 
        case  2: 
              strcpy(s, ClkDOWTbl[ClkDOW]);                  /* Get the day of the week                */ 
              strcat(s, ClkMonthTbl[ClkMonth].MonthName);    /* Get name of month                      */ 
              if (ClkDay < 10) { 
                 str[0] = ClkDay + '0'; 
                 str[1] = 0; 
              } else { 
                 str[0] = ClkDay / 10 + '0'; 
                 str[1] = ClkDay % 10 + '0'; 
                 str[2] = 0; 
              } 
              strcat(s, str); 
              strcat(s, ", "); 
              itoa(ClkYear, str, 10); 
              strcat(s, str); 
              break; 
 
        case  3: 
              strcpy(s, "YYYY-MM-DD");           /* Create the template for the selected format        */ 
              s[0] = year / 1000 + '0'; 
              year = year % 1000; 
              s[1] = year /  100 + '0'; 
              year = year %  100; 
              s[2] = year /   10 + '0'; 
              s[3] = year %   10 + '0'; 
              s[5] = ClkMonth / 10 + '0';        /* Convert DATE to ASCII                              */ 
              s[6] = ClkMonth % 10 + '0'; 
              s[8] = ClkDay   / 10 + '0'; 
              s[9] = ClkDay   % 10 + '0'; 
              break; 
 
        default: 
              strcpy(s, "?"); 
              break; 
    } 
    OSSemPost(ClkSem);                           /* Release access to clock                            */ 
} 
#endif 
 
/*$PAGE*/ 
/* 
********************************************************************************************************* 
*                                    FORMAT CURRENT TIME INTO STRING 
* 
* Description : Formats the current time into an ASCII string. 
* Arguments   : n      is the format type: 
*                      1   will format the time as "HH:MM:SS"     (24 Hour format) 
*                                                                 (needs at least  9 characters) 
*                      2   will format the time as "HH:MM:SS AM"  (With AM/PM indication) 
*                                                                 (needs at least 13 characters) 
*               s      is a pointer to the destination string.  The destination string must be large 
*                      enough to hold the formatted time. 
*                      contain 
* Returns     : None. 
* Notes       : - A 'switch' statement has been used to allow you to add your own time formats. 
*               - This function assumes that strcpy() is reentrant. 
********************************************************************************************************* 
*/ 
 
void  ClkFormatTime (INT8U n, char *s) 
{ 
    INT8U err; 
    INT8U hr; 
 
 
    OSSemPend(ClkSem, 0, &err);                       /* Gain exclusive access to time-of-day clock    */ 
    switch (n) { 
        case  1: 
              strcpy(s, "HH:MM:SS");                  /* Create the template for the selected format   */ 
              s[0] = ClkHr  / 10 + '0';               /* Convert TIME to ASCII                         */ 
              s[1] = ClkHr  % 10 + '0'; 
              s[3] = ClkMin / 10 + '0'; 
              s[4] = ClkMin % 10 + '0'; 
              s[6] = ClkSec / 10 + '0'; 
              s[7] = ClkSec % 10 + '0'; 
              break; 
 
        case  2: 
              strcpy(s, "HH:MM:SS AM");               /* Create the template for the selected format   */ 
              s[9] = (ClkHr >= 12) ? 'P' : 'A';       /* Set AM or PM indicator                        */ 
              if (ClkHr > 12) {                       /* Adjust time to be displayed                   */ 
                  hr   = ClkHr - 12; 
              } else { 
                  hr = ClkHr; 
              } 
              s[0] = hr     / 10 + '0';               /* Convert TIME to ASCII                         */ 
              s[1] = hr     % 10 + '0'; 
              s[3] = ClkMin / 10 + '0'; 
              s[4] = ClkMin % 10 + '0'; 
              s[6] = ClkSec / 10 + '0'; 
              s[7] = ClkSec % 10 + '0'; 
              break; 
 
        default: 
              strcpy(s, "?"); 
              break; 
    } 
    OSSemPost(ClkSem);                                /* Release access to time-of-day clock           */ 
} 
 
/*$PAGE*/ 
/* 
********************************************************************************************************* 
*                                         FORMAT TIME-STAMP 
* 
* Description : This function converts a time-stamp to an ASCII string. 
* Arguments   : n         is the desired format number: 
*                            1 : "MM-DD-YY HH:MM:SS"         (needs at least 18 characters) 
*                            2 : "YYYY-MM-DD HH:MM:SS"       (needs at least 20 characters) 
*               ts        is the time-stamp value to format 
*               s         is the destination ASCII string 
* Returns     : none 
* Notes       : - The time stamp is a 32 bit unsigned integer as follows: 
* 
*        Field: -------Year------ ---Month--- ------Day----- ----Hours----- ---Minutes--- --Seconds-- 
*        Bit# : 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 
* 
*               - The year is based from CLK_TS_BASE_YEAR.  That is, if bits 31..26 contain 0 it really  
*                 means that the year is really CLK_TS_BASE_YEAR.  If bits 31..26 contain 13, the year  
*                 is CLK_TS_BASE_YEAR + 13. 
********************************************************************************************************* 
*/ 
 
#if CLK_TS_EN && CLK_DATE_EN 
void  ClkFormatTS (INT8U n, TS ts, char *s) 
{ 
    INT16U yr; 
    INT8U month; 
    INT8U day; 
    INT8U hr; 
    INT8U min; 
    INT8U sec; 
 
 
    yr    = CLK_TS_BASE_YEAR + (ts >> 26);       /* Unpack time-stamp                                  */ 
    month = (ts >> 22) & 0x0F; 
    day   = (ts >> 17) & 0x1F; 
    hr    = (ts >> 12) & 0x1F; 
    min   = (ts >>  6) & 0x3F; 
    sec   = (ts & 0x3F); 
    switch (n) { 
        case  1: 
              strcpy(s, "MM-DD-YY HH:MM:SS");    /* Create the template for the selected format        */ 
              yr    = yr % 100; 
              s[ 0] = month / 10 + '0';          /* Convert DATE to ASCII                              */ 
              s[ 1] = month % 10 + '0'; 
              s[ 3] = day   / 10 + '0'; 
              s[ 4] = day   % 10 + '0'; 
              s[ 6] = yr    / 10 + '0'; 
              s[ 7] = yr    % 10 + '0'; 
              s[ 9] = hr    / 10 + '0';           /* Convert TIME to ASCII                             */ 
              s[10] = hr    % 10 + '0'; 
              s[12] = min   / 10 + '0'; 
              s[13] = min   % 10 + '0'; 
              s[15] = sec   / 10 + '0'; 
              s[16] = sec   % 10 + '0'; 
              break; 
 
        case  2: 
              strcpy(s, "YYYY-MM-DD HH:MM:SS");  /* Create the template for the selected format        */ 
              s[ 0] = yr    / 1000 + '0';        /* Convert DATE to ASCII                              */ 
              yr    = yr % 1000; 
              s[ 1] = yr    /  100 + '0'; 
              yr    = yr %  100; 
              s[ 2] = yr    /   10 + '0'; 
              s[ 3] = yr    %   10 + '0'; 
              s[ 5] = month / 10 + '0';           
              s[ 6] = month % 10 + '0'; 
              s[ 8] = day   / 10 + '0'; 
              s[ 9] = day   % 10 + '0'; 
              s[11] = hr    / 10 + '0';           /* Convert TIME to ASCII                             */ 
              s[12] = hr    % 10 + '0'; 
              s[14] = min   / 10 + '0'; 
              s[15] = min   % 10 + '0'; 
              s[17] = sec   / 10 + '0'; 
              s[18] = sec   % 10 + '0'; 
              break; 
 
        default: 
              strcpy(s, "?"); 
              break; 
    } 
} 
#endif 
 
/*$PAGE*/ 
/* 
********************************************************************************************************* 
*                                             GET TIME-STAMP 
* 
* Description : This function is used to return a time-stamp to your application.  The format of the 
*               time-stamp is shown below: 
* 
*        Field: -------Year------ ---Month--- ------Day----- ----Hours----- ---Minutes--- --Seconds-- 
*        Bit# : 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 
* 
* Arguments   : None. 
* Returns     : None. 
* Notes       : The year is based from CLK_TS_BASE_YEAR.  That is, if bits 31..26 contain 0 it really  
*               means that the year is CLK_TS_BASE_YEAR.  If bits 31..26 contain 13, the year is  
*               CLK_TS_BASE_YEAR + 13. 
********************************************************************************************************* 
*/ 
 
#if CLK_TS_EN && CLK_DATE_EN 
TS  ClkGetTS (void) 
{ 
    TS ts; 
 
 
    OS_ENTER_CRITICAL(); 
    ts = ClkTS; 
    OS_EXIT_CRITICAL(); 
    return (ts); 
} 
#endif 
 
/*$PAGE*/ 
/* 
********************************************************************************************************* 
*                                        TIME MODULE INITIALIZATION 
*                                     TIME-OF-DAY CLOCK INITIALIZATION 
* 
* Description : This function initializes the time module.  The time of day clock task will be created 
*               by this function. 
* Arguments   : None 
* Returns     : None. 
********************************************************************************************************* 
*/ 
 
void  ClkInit (void) 
{ 
    ClkSem     = OSSemCreate(1);       /* Create time of day clock semaphore                           */ 
    ClkSemSec  = OSSemCreate(0);       /* Create counting semaphore to signal the occurrence of 1 sec. */ 
    ClkTickCtr =    0; 
    ClkSec     =    0; 
    ClkMin     =    0; 
    ClkHr      =    0; 
#if CLK_DATE_EN 
    ClkDay     =    1; 
    ClkMonth   =    1; 
    ClkYear    = 1999; 
#endif 
#if CLK_TS_EN && CLK_DATE_EN 
    ClkTS      = ClkMakeTS(ClkMonth, ClkDay, ClkYear, ClkHr, ClkMin, ClkSec); 
#endif 
    OSTaskCreate(ClkTask, (void *)0, &ClkTaskStk[CLK_TASK_STK_SIZE], CLK_TASK_PRIO); 
} 
 
/*$PAGE*/ 
/* 
********************************************************************************************************* 
*                                     DETERMINE IF WE HAVE A LEAP YEAR 
* 
* Description : This function determines whether the 'year' passed as an argument is a leap year. 
* Arguments   : year    is the year to check for leap year. 
* Returns     : TRUE    if 'year' is a leap year. 
*               FALSE   if 'year' is NOT a leap year. 
********************************************************************************************************* 
*/ 
#if CLK_DATE_EN 
static  BOOLEAN  ClkIsLeapYear(INT16U year) 
{ 
    if (!(year % 4) && (year % 100) || !(year % 400)) { 
        return TRUE; 
    } else { 
        return (FALSE); 
    } 
} 
#endif 
 
/*$PAGE*/ 
/* 
********************************************************************************************************* 
*                                           MAKE TIME-STAMP 
* 
* Description : This function maps a user specified date and time into a 32 bit variable called a 
*               time-stamp. 
* Arguments   : month     is the desired month   (1..12) 
*               day       is the desired day     (1..31) 
*               year      is the desired year    (CLK_TS_BASE_YEAR .. CLK_TS_BASE_YEAR+63) 
*               hr        is the desired hour    (0..23) 
*               min       is the desired minutes (0..59) 
*               sec       is the desired seconds (0..59) 
* Returns     : A time-stamp based on the arguments passed to the function. 
* Notes       : - The time stamp is formatted as follows using a 32 bit unsigned integer: 
* 
*        Field: -------Year------ ---Month--- ------Day----- ----Hours----- ---Minutes--- --Seconds-- 
*        Bit# : 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 
* 
*               - The year is based from CLK_TS_BASE_YEAR.  That is, if bits 31..26 contain 0 it really  
*                 means that the year is really CLK_TS_BASE_YEAR.  If bits 31..26 contain 13, the year is  
*                 CLK_TS_BASE_YEAR + 13. 
********************************************************************************************************* 
*/ 
 
#if CLK_TS_EN && CLK_DATE_EN 
TS  ClkMakeTS (INT8U month, INT8U day, INT16U yr, INT8U hr, INT8U min, INT8U sec) 
{ 
    TS ts; 
 
 
    yr -= CLK_TS_BASE_YEAR; 
    ts  = ((INT32U)yr << 26) | ((INT32U)month << 22) | ((INT32U)day << 17); 
    ts |= ((INT32U)hr << 12) | ((INT32U)min   <<  6) |  (INT32U)sec; 
    return (ts); 
} 
#endif 
 
/*$PAGE*/ 
/* 
********************************************************************************************************* 
*                                            SET DATE ONLY 
* 
* Description : Set the date of the time-of-day clock 
* Arguments   : month     is the desired month (1..12) 
*               day       is the desired day   (1..31) 
*               year      is the desired year  (CLK_TS_BASE_YEAR .. CLK_TS_BASE_YEAR+63) 
* Returns     : None. 
* Notes       : It is assumed that you are specifying a correct date (i.e. there is no range checking 
*               done by this function). 
********************************************************************************************************* 
*/ 
 
#if  CLK_DATE_EN 
void  ClkSetDate (INT8U month, INT8U day, INT16U year) 
{ 
    INT8U err; 
 
 
    OSSemPend(ClkSem, 0, &err);                  /* Gain exclusive access to time-of-day clock         */ 
    ClkMonth = month; 
    ClkDay   = day; 
    ClkYear  = year; 
    ClkUpdateDOW();                              /* Compute the day of the week (i.e. Sunday ...)      */ 
    OSSemPost(ClkSem);                           /* Release access to time-of-day clock                */ 
} 
#endif 
 
/*$PAGE*/ 
/* 
********************************************************************************************************* 
*                                          SET DATE AND TIME 
* 
* Description : Set the date and time of the time-of-day clock 
* Arguments   : month     is the desired month   (1..12) 
*               day       is the desired day     (1..31) 
*               year      is the desired year    (2xxx) 
*               hr        is the desired hour    (0..23) 
*               min       is the desired minutes (0..59) 
*               sec       is the desired seconds (0..59) 
* Returns     : None. 
* Notes       : It is assumed that you are specifying a correct date and time (i.e. there is no range 
*               checking done by this function). 
********************************************************************************************************* 
*/ 
 
#if  CLK_DATE_EN 
void  ClkSetDateTime (INT8U month, INT8U day, INT16U year, INT8U hr, INT8U min, INT8U sec) 
{ 
    INT8U err; 
 
 
    OSSemPend(ClkSem, 0, &err);                  /* Gain exclusive access to time-of-day clock         */ 
    ClkMonth = month; 
    ClkDay   = day; 
    ClkYear  = year; 
    ClkHr    = hr; 
    ClkMin   = min; 
    ClkSec   = sec; 
    ClkUpdateDOW();                              /* Compute the day of the week (i.e. Sunday ...)      */ 
    OSSemPost(ClkSem);                           /* Release access to time-of-day clock                */ 
} 
#endif 
 
/*$PAGE*/ 
/* 
********************************************************************************************************* 
*                                          SET TIME ONLY 
* 
* Description : Set the time-of-day clock 
* Arguments   : hr        is the desired hour    (0..23) 
*               min       is the desired minutes (0..59) 
*               sec       is the desired seconds (0..59) 
* Returns     : None. 
* Notes       : It is assumed that you are specifying a correct time (i.e. there is no range checking 
*               done by this function). 
********************************************************************************************************* 
*/ 
 
void  ClkSetTime (INT8U hr, INT8U min, INT8U sec) 
{ 
    OS_ENTER_CRITICAL();                         /* Gain exclusive access to time-of-day clock         */ 
    ClkHr  = hr; 
    ClkMin = min; 
    ClkSec = sec; 
    OS_EXIT_CRITICAL();                          /* Release access to time-of-day clock                */ 
} 
 
/*$PAGE*/ 
/* 
********************************************************************************************************* 
*                          SIGNAL CLOCK MODULE THAT A 'CLOCK TICK' HAS OCCURRED 
* 
* Description : This function is called by the 'clock tick' ISR on every tick.  This function is thus 
*               responsible for counting the number of clock ticks per second.  When a second elapses, 
*               this function will signal the time-of-day clock task. 
* Arguments   : None. 
* Returns     : None. 
* Note(s)     : CLK_DLY_TICKS must be set to the number of ticks to produce 1 second.   
*               This would typically correspond to OS_TICKS_PER_SEC if you use uC/OS-II. 
********************************************************************************************************* 
*/ 
 
void  ClkSignalClk (void) 
{ 
    ClkTickCtr++;                           /* count the number of 'clock ticks' for one second        */ 
    if (ClkTickCtr >= CLK_DLY_TICKS) { 
        ClkTickCtr = 0; 
        OSSemPost(ClkSemSec);               /* Signal that one second elapsed                          */ 
    } 
} 
 
/* 
********************************************************************************************************* 
*                                        TIME-OF-DAY CLOCK TASK 
* 
* Description : This task is created by ClkInit() and is responsible for updating the time and date. 
*               ClkTask() executes every second. 
* Arguments   : None. 
* Returns     : None. 
* Notes       : CLK_DLY_TICKS must be set to produce 1 second delays. 
********************************************************************************************************* 
*/ 
 
void  ClkTask (void *data) 
{ 
    INT8U err; 
 
 
    data = data;                            /* Avoid compiler warning (uC/OS requirement)              */ 
    for (;;) { 
 
#if CLK_USE_DLY 
        OSTimeDlyHMSM(0, 0, 1, 0);          /* Delay for one second                                    */ 
#else 
        OSSemPend(ClkSemSec, 0, &err);      /* Wait for one second to elapse                           */ 
#endif 
 
        OSSemPend(ClkSem, 0, &err);         /* Gain exclusive access to time-of-day clock              */ 
        if (ClkUpdateTime() == TRUE) {      /* Update the TIME (i.e. HH:MM:SS)                         */ 
#if CLK_DATE_EN 
            ClkUpdateDate();                /* And date if a new day (i.e. MM-DD-YY)                   */ 
#endif 
        } 
#if CLK_TS_EN && CLK_DATE_EN 
        ClkTS = ClkMakeTS(ClkMonth, ClkDay, ClkYear, ClkHr, ClkMin, ClkSec); 
#endif 
        OSSemPost(ClkSem);                  /* Release access to time-of-day clock                     */ 
    } 
} 
 
/*$PAGE*/ 
/* 
********************************************************************************************************* 
*                                            UPDATE THE DATE 
* 
* Description : This function is called to update the date (i.e. month, day and year) 
* Arguments   : None. 
* Returns     : None. 
* Notes       : This function updates ClkDay, ClkMonth, ClkYear and ClkDOW. 
********************************************************************************************************* 
*/ 
 
#if CLK_DATE_EN 
static  void  ClkUpdateDate (void) 
{ 
    BOOLEAN newmonth; 
 
 
    newmonth = TRUE; 
    if (ClkDay >= ClkMonthTbl[ClkMonth].MonthDays) {  /* Last day of the month?                        */ 
        if (ClkMonth == 2) {                          /* Is this February?                             */ 
            if (ClkIsLeapYear(ClkYear) == TRUE) {     /* Yes, Is this a leap year?                     */ 
                if (ClkDay >= 29) {                   /* Yes, Last day in february?                    */ 
                    ClkDay = 1;                       /* Yes, Set to 1st day in March                  */ 
                } else { 
                    ClkDay++; 
                    newmonth = FALSE; 
                } 
            } else { 
                ClkDay = 1; 
            } 
        } else { 
            ClkDay = 1; 
        } 
    } else { 
        ClkDay++; 
        newmonth = FALSE; 
    } 
    if (newmonth == TRUE) {                      /* See if we have completed a month                   */ 
        if (ClkMonth >= 12) {                    /* Yes, Is this december ?                            */ 
            ClkMonth = 1;                        /* Yes, set month to january...                       */ 
            ClkYear++;                           /*      ...we have a new year!                        */ 
        } else { 
            ClkMonth++;                          /* No,  increment the month                           */ 
        } 
    } 
    ClkUpdateDOW();                              /* Compute the day of the week (i.e. Sunday ...)      */ 
} 
#endif 
 
/*$PAGE*/ 
/* 
********************************************************************************************************* 
*                                         COMPUTE DAY-OF-WEEK 
* 
* Description : This function computes the day of the week (0 == Sunday) based on the current month, 
*               day and year. 
* Arguments   : None. 
* Returns     : None. 
* Notes       : - This function updates ClkDOW. 
*               - This function is called by ClkUpdateDate(). 
********************************************************************************************************* 
*/ 
#if CLK_DATE_EN 
static  void  ClkUpdateDOW (void) 
{ 
    INT16U dow; 
 
 
    dow = ClkDay + ClkMonthTbl[ClkMonth].MonthVal; 
    if (ClkMonth < 3) { 
        if (ClkIsLeapYear(ClkYear)) { 
            dow--; 
        } 
    } 
    dow    += ClkYear + (ClkYear / 4); 
    dow    += (ClkYear / 400) - (ClkYear / 100); 
    dow    %= 7; 
    ClkDOW  = dow; 
} 
#endif 
 
/*$PAGE*/ 
/* 
********************************************************************************************************* 
*                                            UPDATE THE TIME 
* 
* Description : This function is called to update the time (i.e. hours, minutes and seconds) 
* Arguments   : None. 
* Returns     : TRUE     if we have completed one day. 
*               FALSE    otherwise 
* Notes       : This function updates ClkSec, ClkMin and ClkHr. 
********************************************************************************************************* 
*/ 
 
static  BOOLEAN  ClkUpdateTime (void) 
{ 
    BOOLEAN newday; 
 
 
    newday = FALSE;                         /* Assume that we haven't completed one whole day yet      */ 
    if (ClkSec >= 59) {                     /* See if we have completed one minute yet                 */ 
        ClkSec = 0;                         /* Yes, clear seconds                                      */ 
        if (ClkMin >= 59) {                 /*    See if we have completed one hour yet                */ 
            ClkMin = 0;                     /*    Yes, clear minutes                                   */ 
            if (ClkHr >= 23) {              /*        See if we have completed one day yet             */ 
                ClkHr = 0;                  /*        Yes, clear hours ...                             */ 
                newday    = TRUE;           /*        ... change flag to indicate we have a new day    */ 
            } else { 
                ClkHr++;                    /*        No,  increment hours                             */ 
            } 
        } else { 
            ClkMin++;                       /*    No,  increment minutes                               */ 
        } 
    } else { 
        ClkSec++;                           /* No,  increment seconds                                  */ 
    } 
    return (newday); 
}