Hice un programa simple que se ejecuta en un microcontrolador P12F629 usando MikroC.
Necesito ejecutar algunas tareas críticas en el tiempo (por ejemplo, aumentar el reloj interno, enviar datos a la matriz LED, ...).
En lugar de un bucle simple + Delay_ms()
(que tiene su propio conjunto de problemas), utilizo una interrupción:
void main()
{
InitTimer0();
while(1);
}
void InitTimer0()
{
//setup timer0 interrupt
//...
}
void Interrupt() //will be fired every x ms
{
//perform some time-critical tasks
//e.g. increase internal clock
//...
}
El problema es que un while
bucle consume ciclos de CPU para nada (y, por lo tanto, reduce la duración de la batería).
Hay alguna manera de evitar esto?
Si elimino la while(1);
llamada al final de main()
, el programa se ejecuta exactamente igual. ¿Hace alguna diferencia? ¿Agregar una Delay_ms(1000)
llamada dentro del ciclo while ayudaría a reducir el estrés de la CPU?
En x86, recuerdo que hay una halt
instrucción que detiene la CPU hasta que se dispara una interrupción externa. Esto sería perfecto aquí. ¿Existe tal cosa en MikroC?
Si está manejando una matriz LED, no creo que el microconsumo de energía sea tan significativo.
Si pone el micro a dormir, el reloj se detiene y no recibe ninguna interrupción del temporizador 0 para traerlo de vuelta. Puede usar el temporizador de vigilancia para recuperarlo, pero es muy variable y el retraso puede ser de hasta 25 ms.
Si realmente desea reducir el consumo de energía y mantener el tiempo, puede ejecutar el micro con un cristal de 32 kHz, que mantendrá un tiempo razonable y solo consumirá microamperios (dependiendo de qué más esté encendido).
Necesita RTFM ( hoja de datos ) sobre los distintos tipos y modos de reloj. También hay un manual de referencia de Microchip con más información. Y luego puede descubrir cómo hacer que su compilador le dé las instrucciones requeridas al chip.
Ignacio Vázquez-Abrams