El Timer 0 es un modulo temporizador/contador de 8 bits que cuenta con un preescalador programable también de 8 bits. Puede funcionar como temporizador o como contador. En modo temporizador el valor del registro TMR0 se incrementa con cada ciclo de instrucción (o cada X ciclos dependiendo del preescalador). En modo contador el valor del registro TMR0 se incrementa en cada flanco (ascendente o descendente) del pin RA4/T0CKI. En ambos casos al desbordarse (pasar de 0xFF a 0x0) el registro TMR0 la bandera de interrupción del timer 0 (bit T0IF del registro INTCON) se pone a 1.

El modo temporizador se selecciona poniendo a cero el bit T0CS del registro OPTION. Poniendo a uno ese bit el modulo trabaja en modo
contador
, en este modo de operación además se debe seleccionar si el incremento se producirá en cada filo ascendente o descendente, al poner a cero el bit T0SE del registro OPTION se selecciona el filo ascendente.

El preescalador es compartido por el Timer 0 y por el Watchdog. Se asigna a un módulo o a otro mediante el bit PSA del registro OPTION. Poniendo el bit a 1 el preescalador se asigna al Watchdog y poniendolo a 0 el preescalador se asigna al Timer 0. El valor del preescalador se selecciona con los bits PS2:PS0 de la siguiente manera:
PS2:P20    TMR0    WDT
  000      1:2     1:1
  001      1:4     1:2
  010      1:8     1:4
  011      1:16    1:8
  100      1:32    1:16
  101      1:64    1:32
  110      1:128   1:64
  111      1:256   1:128
Carga y temporización

En modo temporizador el Timer 0 incrementa su cuenta en cada ciclo de instrucción. Este modo sirve para generar temporizaciones y bases de tiempo de la misma forma que los retardos por software, sin embargo las temporizaciones con el Timer 0 pueden ser más exactas y además se cuenta con la ventaja de que el módulo puede trabajar mediante interrupciones así que el programa puede ejecutar otras isntrucciones mientras se realiza la temporización.

La temporización que se puede obtener con este módulo se obtiene de la siguiente relación:

Temporización = [(256 - precarga)*PS+2]*Tinstruccion

Donde:
precarga = Valor que se le asigna al registro TMR0 al comenzar la temporización
PS = Preescalador. Si esta asignado al watchdog tomará el valor de 1
Tinstrucción = 4/frecuencia de oscilación
y la temporización está dada en segundos.

La temporización máxima utilizando el oscilador interno del pic 16f628 es:

Temp.max. = [(256 - 0)*256+2]*1uS = 65528uS

De modo que la temporizacion máxima que se puede tener con el es solamente de 65.538mS. Si se desea obtener una temporizacion distinta solo se debe escribir en el registro TMR0 el valor de la precarga necesaria.

precarga = -[([Temporizacion/(4/fosc)]-2)/PS]+256

Donde, de nuevo, la temporización está dada en segundos.

Veamos un ejemplo de aplicación: Se desea complementar el valor del puerto B cada 50mS. Se estará revisando que se haya cumplido el tiempo de la temporización checando la bandera T0IF. Utilizando la expresión de la precarga y utilizando el preescalador más grande (256) obtenemos el valor que necesitamos cargar al registro TMR0 para obtener una temporización de 50mS.

precarga = -[([50mS/(4/4Mhz)]-2)/256]+256 = 60.69 ≈ 60

Ya que no podemos cargar numeros fraccionarios el valor de precarga necesario es 60. Teniendo entonces el valor de la precarga el código del programa sería el siguiente:
INICIO
    bsf     STATUS,RP0
    clrf    TRISB
    movlw   b'00000111'
    movwf   OPTION_REG
    bcf     STATUS,RP0
    clrf    PORTB
    bcf     INTCON,T0IF
PRECARGA
    movlw   .60
    movwf   TMR0
ESPERA
    btfss   INTCON,T0IF
    goto    ESPERA
    bcf     INTCON,T0IF
    comf    PORTB,f
    goto    PRECARGA
La configuración del Timer 0 se realiza mediante las líneas "movlw b'00000111'" y "movwf OPTION_REG". Mediante estas lineas se configura el timer en modo temporizador (T0CS = 0), el preescalador se asigna al timer 0 (PSA = 0) y se selecciona el preescalador máximo (PS2:PS0 = 111). Una vez configurado el timer 0 se limpia el puerto B y la bandera T0IF. Posteriormente se realiza la precarga cargando un 60 al registro TMR0 y en ese momento la temporización comienza.

Para saber si la temporización terminó se está revisando la bandera T0IF. Mientras esta sea 0 la temporización aún no habrá terminado, cuando la bandera es 1 entonces la temporización finalizó, se borra la bandera, se complementa el puerto B y se vuelve a realizar la precarga. De este modo el programa está complementado el puerto B cada 50mS.

Descargar código: Ejemplo del temporizador Timer 0