Software Real-Time Clock using TIMER0


Example implements software Real Time Clock using Timer0 of 8051.

Toolkit:SDCC 8051 Development System

Location:/bipom/devtools/SDCC/examples/timer0/

Code Example


#define UBYTE unsigned char
#define ONE_SECOND 	120 

register struct 
  {
    UBYTE Second ;
    UBYTE Minute ;
    UBYTE Hour ;
    UBYTE Day;
    UBYTE Date;
    UBYTE Month;
    UBYTE Year;
    UBYTE Control;
  } time;

// TIMER INTERRUPT SERVICE ROUTINE

// 120 (8.33 ms) Hertz interrupt


register	UBYTE c_tick;
register	UBYTE k_date;
register	int k_year;

const  char datetab  [13] = { 0 , 
                             31 , 28 , 31 , 30 , 31 , 30 ,
                             31 , 31 , 30 , 31 , 30 , 31 } ;


void external_timer_handler(void) __interrupt(1)   
{
	TH0  =  0xC4; /* Re-initialize Timer 0. 
					 We do not need to write TL0.
					 TL0 should work as free running timer  	
				  */
				  
    /* SOFTWARE CLOCK PROCESSING */
	if( ! ( c_tick = ( c_tick == ONE_SECOND ) ? 0 : ++c_tick ) )
	{   
	    /* Is it time for minute tick ? */
		if( ++time.Second == 60 ) 
		{ 
			time.Second = 0; 
		
		    /* Is it time for hour tick ? */
			if( ++time.Minute == 60 ) 
			{
				time.Minute = 0;
			
			    /* Is it time for day tick ? */
				if( ++time.Hour == 24 ) 
				{
					time.Hour = 0;
					
					k_year = time.Year & 0x03;
					k_date = datetab [time.Month];
					
					if( ( k_year == 0 ) && ( time.Month == 2 ) )
					{
					   k_date++;
					}
					
					if( k_date == time.Date ) 
					{ 
					   time.Date = 1; 
					   time.Month++; 
					}
					else 
					{
					   time.Date++; 
					}
					
					/* Is it time for year tick ? */
					if ( time.Month == 13 ) { time.Month = 1 ; time.Year++; }
				}
			}
		}
	}
}

/*******************************************************************************
*	Function:		printTimeStamp
*	
*	Desription:		prints the system time and date
*
*	Inputs:			None
*
*
*	Returns:		None
*					 
*******************************************************************************/
void printTimeStamp(void)
{
	 printf("\n\rDate: %02d.%02d.%02d Time: %02d:%02d:%02d",
	 time.Date, time.Month,  time.Year,
	 time.Hour, time.Minute, time.Second);
}

/*******************************************************************************
*	Function:		InitCPU
*	
*	Desription:		initializes serial port,timer0 interrupts 
*
*	Inputs:			None
*
*
*	Returns:		None
*					 
*******************************************************************************/
void InitCPU(void)
{
    serinit(CBR_19200);     /* Initialize serial port to 19200 baud */

	TMOD &= 0xF0;	/* Clear Timer0 settings */
	TL0  =  0x00;	/* Initialize Timer 0 */
	TH0  =  0xC4;
	TMOD |= 1;		/* Set 16-bit mode of Timer0*/
	TCON |= 0x10; 	/* Enable Timer0  counting */
	IE   = 0x82;	/* Enable Timer0 interrupts */
}


main()
{
	UBYTE previousSecond; 

    /* 
	For now initialize the system clock by default values.
	We can plug RTC board on top of MM51C board.
	In this case we can synchronize the system clock with real time
    */	
	c_tick			=0;
	time.Second		=0;
    time.Minute		=0;
    time.Hour		=0;
    time.Day		=1;
    time.Date		=1;
    time.Month		=1;
    time.Year		=10;
    time.Control	=0;
    
    previousSecond = 60;

    /* Initialize hardware */
    InitCPU();

    /* Infinite loop; waiting for seconds to tick */
    for ( ;; )
    {
        /* When the seconds tick */
    	if ( previousSecond != time.Second )
 		{
 		    /* Print the time to serial console */
 			printTimeStamp();
 			
 			previousSecond = time.Second;
 		}
 	}
}