Example implements software Real Time Clock using Timer0 of 8051.
Toolkit:SDCC 8051 Development System
Location:/bipom/devtools/SDCC/examples/timer0/
#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; } } }