Count seconds and minutes with MCU timer/interrupt?
- by arynhard
I am trying to figure out how to create a timer for my C8051F020 MCU. The following code uses the value passed to init_Timer2() with the following formula:
65535-(0.1 / (12/2000000)=48868.
I set up the timer to count every time it executes and for every 10 counts, count one second. This is based on the above formula. 48868 when passed to init_Timer2 will produce a 0.1 second delay. It would take ten of them per second. However, when I test the timer it is a little fast. At ten seconds the timer reports 11 seconds, at 20 seconds the timer reports 22 seconds. I would like to get as close to a perfect second as I can.
Here is my code:
#include <compiler_defs.h>
#include <C8051F020_defs.h>
void init_Clock(void);
void init_Watchdog(void);
void init_Ports(void);
void init_Timer2(unsigned int counts);
void start_Timer2(void);
void timer2_ISR(void);
unsigned int timer2_Count;
unsigned int seconds;
unsigned int minutes;
int main(void)
{
    init_Clock();
    init_Watchdog();
    init_Ports();
    start_Timer2();
    P5 &= 0xFF;
    while (1);
}
//=============================================================
//Functions
//=============================================================
void init_Clock(void)
{
    OSCICN = 0x04;  //2Mhz
    //OSCICN = 0x07;    //16Mhz
}
void init_Watchdog(void)
{
    //Disable watchdog timer
    WDTCN = 0xDE;
    WDTCN = 0xAD;
}
void init_Ports(void)
{
    XBR0    = 0x00;
    XBR1    = 0x00;
    XBR2    = 0x40;
    P0      = 0x00;
    P0MDOUT = 0x00;
    P5      = 0x00; //Set P5 to 1111
    P74OUT  = 0x08; //Set P5 4 - 7 (LEDs) to push pull (Output)
}
void init_Timer2(unsigned int counts)
{
    CKCON = 0x00;   //Set all timers to system clock divided by 12
    T2CON = 0x00;   //Set timer 2 to timer mode
    RCAP2 = counts; 
    T2 = 0xFFFF;    //655535
    IE |= 0x20;     //Enable timer 2
    T2CON |= 0x04;  //Start timer 2
}
void start_Timer2(void)
{
    EA = 0;
    init_Timer2(48868);
    EA = 1;
}
void timer2_ISR(void) interrupt 5
{    
    T2CON &= ~(0x80);
        P5 ^= 0xF0;
        timer2_Count++;
        if(timer2_Count % 10 == 0)
        {
            seconds++;
        }
        if(seconds % 60 == 0  && seconds != 0)
        {
            minutes++;
        }
}