Hola.
¿Has intentado crear tu código por estados o tareas cooperativas?
Por ejemplo en main tienes varias tareas:
estadoTarea1 = 0;
estadoTarea2 = 0;
...
estadoTarean = 0;
void main(void)
{
while(1)
{
tarea1();
tarea2();
....
tarean();
}
}
]
Y cada tarea se divide en estados, de tal manera que ninguna se apropie de CPU 100%
por ejemplo
void tarea1(void)
{
switch(estadoTarea1)
{
case 0x00:
{
/** escribes tu poco de tu proceso aquí **/
estadoTarea = siguienteEstado;
break;
}
case 0x01:
{
/** escribes tu poco de tu proceso aquí **/
estadoTarea = siguienteEstado2;
break;
}
....
default; //ultimo case
{
/** escribes tu poco de tu proceso aquí **/
estadoTarea = siguienteEstadoM;
}
}
}
Utilizar los delays de PICC y otros compiladores son mala idea, ya que se apoderan del CPU y bloquean las interrupciones, por ejemplo, si tu delay es de 1000 ms, durante un segundo, el CPU del microcontrolador estará "colgado" sin ejecutar algo útil y puede perder la atención a una interrupción.
Entonces para no ocupar esos delays y generar retardos apropiativos ineficientes, debes usar un temporizador como a continuación te explico:
Dices que tienes un temporizador de 16 bits, este temporizador lo tienes activado que corra o funcione sin restricciones.
No estoy seguro de que micro usas , per supongamos que se incrementa con 4us, entonces con 16 bits tu podrías generar máximo 262.144ms, por lo que no nos sirve el pre escaler.
Con un preescaler de 16 bits, máximo puedes generar 524.288 ms.
Entonces se necesita una variable auxiliar por cada tarea que necesita un retardo (Esto es más fácil con temporizadores de 32 bits)
Regresando a la opción 1, vamos a contar valores mucho más pequeños de 262.144 ms, digamos 30ms.
El temporizador necesita 4us para incrementarse en una unidad, entonces para alcanzar 30ms sería Ciclos necesario = 30ms/4us = 7500
Y para generar 1000 ms se necesita 1000ms/30ms = 33 333, que sería lo que tiene la variable auxiliar.
Entonces para producir un retardo sería así para una tarea, digamos la 1.
case estado_A:
{
/* valorTemporizado es de tipo unsigned*/
valorTemporizador = funcionQueLeeTMR1(); //valor de 16 bits
variableAuxParaTarea1 = 33333;
estadoTarea1 = estado_B;
break;
}
case estado_B:
{
if ((funcionQueLeeTMR1() - valorTemporizador) > 7500) //cuando pasa 30 ms, el if es verdadero
{
variableAuxParaTarea1--;
if (0 == variableAuxParaTarea1) //el if es verdadero cuando ha pasado 1 segundo
{
/*Tu código de lo que desees hacer cuando han pasado 1000 ms*/
}
else // Si variableAuxParaTarea1 aun no es cero, debes capturar un nuevo valor del temp para nuevamente generar 30 ms
{
valorTemporizador = funcionQueLeeTMR1();
}
}
break;
}
Puedes ver que no es apropiativo como los delays este proceso. El caso estado_B solo verifica si el tiempo ha alcanzado el valor deseado, si no continua para que otro case de otra tarea se ejecute.