Hola, mi pequeño aporte, el tema de la precisión ya te comentaron como hacerlo. Por lo que vi el código esta bien escrito pero se simplificaria mucho si cambias la manera de hacer el calculo. Lo prinicipal es tener una base de tiempo la cual vas a contar, en tu caso deberia ser un timer de 1s lo mas exacto posible, en el handler de la interrupción actualizas un contador de 32 bits para que te de la precisión. Ejemplo: ( No uso MicroChip ni CCS espero que entiendas las lineas de C )
volatile INT32 TimerTicks;
TimerInterruptHandler( void )
{
TimerTicks ++;
}
INT32 GetTimerTicks( void )
{
volatile INT32 ReadTicks;
ReadTicks = TimerTicks;
while ( ReadTicks != TimerTicks )
{
ReadTicks = TimerTicks;
}
return( ReadTicks );
}
La primera función cuenta los ticks que se producen por segundo, deberas colocar el codigo correspondiente para tu micro para el manejo de la interrupcion, en la segunda se devuelve ese contador de manera "atomica".
Una vez que tenes ese contador, lo que resta es transformar los segundos, en minutos, horas, dias, meses y años, simplemente haciendo cuentas. Para finalizar usar solamente una funcion para escribir el display como string, tomas los valores anteriores ( segundos, minutos, horas, etc ) convertidos a string y los mostras.
Te dejo un ejemplo de como desde una base de tiempo se convierte a dias, horas, minutos pero la idea es la misma.
/*------------------------------------------------------------------------------------------------
** Function Name : GetElapsedTime
** Description : Get elpased time form startup in DD:HH:MM:SS:mmm format
** Input : Destinity vars
** Output : Nothing
** Notes :
--------------------------------------------------------------------------------------------------*/
void GetElapsedTime( byte *Days, byte *Hours, byte *Mins, byte *Secs, word *Miliseconds )
{
dword CurrentTime = GetMiliSecondsFromStartup();
*Days = CurrentTime / MILISECOND_IN_DAY;
CurrentTime %= MILISECOND_IN_DAY;
*Hours = CurrentTime / MILISECOND_IN_HOUR;
CurrentTime %= MILISECOND_IN_HOUR;
*Mins = CurrentTime / MILISECOND_IN_MINUTES;
CurrentTime %= MILISECOND_IN_MINUTES;
*Secs = CurrentTime / MILISECOND_IN_SECONDS;
*Miliseconds = CurrentTime % MILISECOND_IN_SECONDS;
}
Saludos !