La mayoría de los microcontroladores cuentan con Timers. Un timers (en AVR) es un simple registro con una resolución de 8 bits a 16 bits dependiendo del Timer. En el Atmega2560 existen 2 Timers de 8 bits y 4 de 16 bits. En este post vamos a trabajar con el Timer más simple, el Timer0.
El Timer0 es un registro contador, que incrementa o decrementa su valor automáticamente en un tiempo (rate) determinado (esto lo vamos a setear). Lo interesente es que la operación del Timer no ncesita de la intervención de la CPU, es decir que hay un HW dedicado a esto.
Como los Timer trabajan independiemente de la CPU, puede ser utilizado para medir el tiempo. Cuando el contador del Timer llega a un cierto valor (es decir, se cumple una condición), este le puede avisar automáticamente a la CPU, a través de una interrupción; o puede tomar una derminada acción. Lo más sencillo que puede ocurrir es que el contador produzca un overflow. Esta situación se da cuando el contador llega a 255, cuando quiere saltar al próximo valor produce una interrupción (overflow) y se vuelve a setear en 0. Nosotros como programadores deberíamos escribir una Rutina de Servicio de Interrupción (en ingles, ISR -> Interruption Service Routine) para manejar el desborde (interrupción).
Clock
Para que funcione el contador, necesita de un reloj (clock). Este clock genera un señal, que producen que el Timer0 incremente/decremente su valor. Este clock puede ser:
- El clock interno, que como máximo se puede generar 16Mhz
- Algún clock externo.
- Un prescaled clock
El prescaler clock es un mecanismo para generar una señal utilizando el clock de la CPU. Lo que se hace es dividir la frecuencia del clock de la CPU y producir una señal para el Timer.
Registros del TIMER0
Existen varios registros que son utilizados por el Timer0. El Timer/Counter (TCNT0) y el Output Compare Register (OCR0A y OCR0B) son registros de 8 bits. Las interrupciones son visibles en el Timer Interrupt Flag Register (TIFR0). Las interrupciones son enmascaradas con el Timer Interrupt Mask Register (TIMSK0). Los registros OCR0A y OCR0B están comparando en todo momento el valor del contador TCNT0. El resultado de la comparación puede ser usado por el Waveform Generator, registro que es utilizado para generar PWM. Los Timer/Counter Control Register 0 (TCCR0A y TCCR0B) son utilizados para configurar el contador.
TCCR0A
Bits 7:6 – COM0A1:0: Compare Match Output A Mode
Estos bits son utilizados para configurar el comportamiento del Pin de Comparación de Salida A (OC0A),
Bits 5:4 – COM0B1:0: Compare Match Output B Mode
Similar a lo anterior pero afecta al OC0B.
Bits 1:0 – WGM01:0: Waveform Generation Mode
Para mayor información sobre este modo sería bueno mirar este post.
TCCR0B
Bits 2:0 – CS02:0: Clock Select
Estos bits son utilizados para elegir la fuente del clock.
TCNT0 - Timer/Counter Register
Es el registro que lleva el contador.
OCR0A - Output Compare Register A
Este registro contiene un valor de 8 bits que continuamente es comparado con el TCNT0. En caso que los valores coincidan se produce una interrupción.
OCR0B- Output Compare Register B
Similar al OCR0A.
TIMSK0 – Timer/Counter Interrupt Mask Register
Este registro es para activar las interrupciones. Si el bit 0 está activo signifca que está permitido las interrupciones de overflow. Si el bit 1 está activo, significa que cuando se compare el valor del OCR0A y TCNT0, y sean iguales, entonces se disparará una interrupción. Igualmente si está en 1 el bit 3, ocurre lo mismo pero con el OCR0B.