La idea de compartirlo es por si alguien encuentra algún fallo o circunstancia en la que el cálculo de la hora de alarma no se haga o se pueda hacer mal. Y también como no, si merece la pena hacerlo de otra forma.
No hacer las variables globales para no ocupar los nombres (polucion del espacio global).
Es decir una función que te retorne el puntero a una estructura, únicamente la hora/min/seg actual del RTC por si queres leerlo, y otra "privado" (static) que solo se acceda desde la libreria del RTC que maneje el temporizador.
El leer el RTC solo actualizaría esta estructura.
El pedido de tiempo se podría hacer de hora, minuto y segundo, para no tener que hacer los modulos y divisiones (que son computacionalmente demandantes) de cada uno de los valores, y solo representen una suma.
Ademas si queres esperar HORAS, me parece mas sensato hacerlo como comenté, en ves de hacerlo como lo planteas. sino habría que pasar todas esas horas a segundos (trabajo extra para el programador).
No considera si segundos es 60, lo cual debería aumentar el minutero, lo cual el reemplazo seria por un mayor o igual o cambiarlo a 59. Y luego haces:
segundos_ = segundos_ % 60;
Lo cual no tiene sentido, debido a que el maximo de cada uno es 59, por lo tanto la suma llegaria 118, y solo deberias restarle 60. Asi lo mismo con los minutos.
La funcion temp_out, es muy dependiente del momento de lectura. Ejemplos:
Si las lecturas son en el mismo dia, es decir mas24 = 0, el peor caso que podemos llegar a tener es que ocurra que el temporizador quede seteado en 23h59m29s, eso haria que si no lo lees en ese segundo, el temporizador no funcionaria. Las soluciones que se pueden plantear y que se me ocurren son:
- Leer el dia tambien
- Mantener un bit interno que ademas de mantener la hora, cuando se este ejecutando el temporizador, revise cuando se pasaron las 24hs del reloj RTC, asi activar un bit y tener en cuenta que hubo un cambio de dia.
Si la lectura fuera del siguiente dia, es decir mas24=1. Se presenta el mismo problema que antes, y ademas la comparacion de horas no es >= sino ==, es decir tenes una ventana de 1 hora para leer los datos.
Por supuesto todo esto depende del tiempo entre de lecturas. La solución mas simple seria incluir el día también lo cual aumentaria la ventana y prestar especial atencion al caso de fin de mes con 23hs59m59s. Y limitar las horas, ejemplo :
/*
* Parámetros:
* In:
* 1: hour Cantidad de horas a esperar
* 2: min Cantidad de min a esperar
* 3: seg Cantidad de seg a esperar
*
* Out:
* RTCT_BUSY_E Error ante el cambio de datos cuando esta marchando
* RTCT_MAX_HOUR_E Error se supera el máximo de horas, que son 24 o mas
* RTCT_MAX_MIN_E Error se supera el máximo de minutos, que son 59 o mas
* RTCT_MAX_SEG_E Error se supera el máximo de segundos, que son 59 o mas
* RTCT_OK Temporizador seteado correctamente.
*
*/
int8 tempo(int8 hour, int8 min, int8 seg){
// Check
if (RTCTemp.busy == 1) return RTCT_BUSY_E;
if (hour > 23) return RTCT_MAX_HOUR_E;
if (min > 59) return RTCT_MAX_MIN_E;
if (seg > 59) return RTCT_MAX_SEG_E;
// Set Initial Values
RTCTemp.mas24 = 0;
// Set Temp
read_rtc();
RTCTemp.seg = RTC.segundos + seg;
RTCTemp.min = RTC.minutos + min;
RTCTemp.hour = RTC.hora + hour;
// Correction
if (RTCTemp.seg > 59) { RTCTemp.seg -= 60; RTCTemp.min++;}
if (RTCTemp.min > 59) { RTCTemp.min -= 60; RTCTemp.hour++;}
if (RTCTemp.hour > 23) {RTCTemp.hour -= 24; RTCTemp.mas24 = 1;}
// Leaving
RTCTemp.busy = 1;
return RTCT_OK;
}
Al limitarlas en 24hs solo presentas el caso de cambio de dia.