Dentro de la interrupción se debe ó no reiniciar la cuenta del contador, dependiendo del módo de trabajo del timer.
Los modos de trabajo se configuran en el registro TMOD, y son :
Modo 0: 13-bit Timer.
Modo 1: 16-bit Timer
Modo 2: 8-bit auto-reload
Modo 3: Split timer mode
Si estas usando el modo auto-reload (autorecargable) no tenes que volver a inicializar dentro de la interrupción, ya que el timer recarga el registro automáticamente copiando el valor de TH0 a TL0 ( éste ultimo es el registro de cuenta).
En todos los demás modos de trabajo del timer debes reiniciar la cuenta, de lo contrario inicia en 0.
Otra cosa que debes tener en cuenta, para que se produzca la interrupción en el overflow ( desborde del timer), es setear en el registro TMOD el bit de GATE.
Todo esto parece difícil, pero en realidad es muy facil, se aclara con el siguiente ejemplo:
/*
Este ejemplo configura el timer 0 como contador autorecargable. Una vez iniciado el timer se bloquea el programa porque no hay nada que hacer.
De todas formas el timer continua contando. En el overflow se produce un salto al handler de interrupción
del timer, que lo unico que hace es cambiar el estado del pin P1_0. Luego vuelve al programa principal, donde continua bloqueado.
La cuenta del timer se recarga en AA luego del overflow, ya que funciona como contador de 8 bits autorecargable.
*/
#include "reg_c51.h"
void main(void)
{
TMOD &= 0xF0; /*Timer 0 en modo 2: Contador autorecargable */
TMOD |= 0x0A; /* GATE0=1; C/T0#=0; T0M1=1; T0M0=0; */
TH0 = 0xAA; /* Valor inicial de autorecarga */
TL0 = 0xAA; /* Valor inicial del contador
ET0=1; /* Configura interrupción de timer 0 */
EA=1; /* Habilita interrupciones */
TR0=1; /* Inicia timer0 */
while(1); /* Bloquea programa, pero aqui podrica hacer lo que desee */
}
/**
Handler de atención a interrupción
*/
void it_timer0(void) interrupt 1 /* interrupt address is 0x000b */
{
TF0 = 0; /* Pone a 0 el flag de interrupción */
P1_0 = ~P1_0; /* Invierte el estado de P1.0 */
}