Las interrupciones del timer hacen que el programa del bucle principal sea interrumpido a intervalos precisos de tiempo para realizar una tarea especifica. Una vez realizada esta tarea el procesador vuelve a hacer la tarea que habia interrumpido en el bucle principal.
Las interrupciones son útiles para:
Medición de una señal de entrada a periodos iguales de tiempo.
Calcular el tiempo entre dos eventos.
El envío de una señal de una frecuencia específica.
Lectura de teclados matrizados.
Multiplexado de digitos Led, o matrices de leds.
Y mucho más …
Hay muchas maneras de hacer las interrupciones, por ahora me centraré en el tipo que me parece el más sencillo y útil llamado modo de CTC (Clear Timer on Compare). En este articulo escribire específicamente sobre los timers del Atmega328p).
Posee 3 timers (Timer0, Timer1 y Timer2). Cada uno de los timers tiene un contador que se incrementa en cada tic del reloj del timer. Las interrupciones del timer en el modo CTC se activan cuando el contador llegua a un valor especificado, almacenado en el registro de comparación OCR. Una vez que un contador llegue a este valor se borrará (a cero) en el siguiente pulso de reloj del timer, luego seguirá contando hasta hasta una nueva comparación.
El primer parámetro a tener en cuenta es la velocidad a la que el timer se incrementa.
Teniendo en cuenta que la placa Arduino tiene un cristal de 16MHz cada tic del timer representa 1/16.000.000 de segundo (~ 63ns),
Veamos un ejemplo sencillo
#include < avr/io.h > #include < avr/interrupt.h > #define F_CPU 16000000UL #include < util/delay.h > #define LED 0b00100000 /**************************************** * FileName: main.c * Purpose: Interrupcion del Timer0 en Modo Normal *****************************************/ int main(void){ DDRB |= LED; TCCR0A = 0x00; TCCR0B = (1 << CS01); TIMSK0 = (1 << TOIE0); sei(); for(;;){ } } /********************************************* * Gestor de Interrupción por Desbordamiento del Timer0. * Esta interrupción se dispara cada 100 microsegs exactamente. * Genera una señal PWM con una frecuencia de 500 Hz *********************************************/ ISR(TIMER0_OVF_vect){ static unsigned int ticks = 0; TCNT0 += 157; // Reponer registro TCNT0 if(ticks--){ // Sig. bloque se ejecuta cada 5000?ù100u = 500ms PORTB ^= LED; ticks = 5000; } }
En este ejemplo se genera una onda cuadrada de frecuencia 500 Hz. Es una practica muy simple y muy provechosa que aplicaremos en la mayoria de nuestros proyectos, el Timer0 funciona como se verá aquí. Dependerá del diseñador saber qué hacer con esta señal. En este ejemplo basculamos un LED en intervalos largos de tiempo, más allá de lo que permite el prescaler.
Continuaremos con mas sobre los timers y las interrupciones.
Deja un comentario