Vous êtes sur la page 1sur 7

TIMER 0

Introduccin
A menudo al utilizar un microcontrolador nos encontramos con la necesidad de contar o generar eventos
cada cierto tiempo. Para ayudar en este tipo de tareas, es habitual que los microcontroladores dispongan de
circuitos internos para ello. Este circuito, es comnmente denominado Timer/Counter (Temporizador/Contador)
aunque tambin por motivos histricos es habitual encontrarlo con el nombre de RTCC (Real Time Clock
Counter).
Nos vamos a centrar en el Timer/Counter de 8 bits habitual en los microcontroladores PIC 16F87X,
denominado en la hoja de especificaciones como mdulo Timer0 (en otros modelos es posible encontrar
mdulos adicionales de 8 16 bits, cuyo funcionamiento bsico es el mismo). Antes de explicar el
funcionamiento y uso del Timer0, vamos de definir los siguientes conceptos para evitar confusiones:
Frecuencia de oscilacin (Fosc): Frecuencia de trabajo externa del PIC (un cristal de cuarzo, un resonador,
etc.).
Frecuencia interna de instrucciones (Fint): Frecuencia del reloj interno de instrucciones generada a partir de
la frecuencia de oscilacin externa. Para los microcontroladores PIC est frecuencia no coincide con Fosc, ya
es necesario dividirla por cuatro:

Fint = Fosc/4
Un ciclo de instruccin equivale a 4 ciclos de reloj. Esto es porque con el primer ciclo de reloj
Celbusca en su
memoria a la instruccin a leer, en el segundo ciclo se carga en la memoria principal, el tercer ciclo es el encargado
de ejecutarla propiamente dicho y el ltimo y cuarto ciclo limpia la memoria para volver a buscar la siguiente
instruccin y as sucesivamente.

Funcionamiento del Timer0


El Timer0 es un dispositivo que puede funcionar conceptualmente de dos formas: como contador de pulsos
externos o como temporizador para calcular intervalos de tiempo. En el caso que dicha seal provenga del reloj
interno de instrucciones (Fint), el Timer0 se utiliza para generar interrupciones peridicas a travs de una cuenta
programada.
Ya que conocemos la frecuencia de funcionamiento y en base a un valor cargado en el contador del timer (lo
veremos ms adelante) podemos temporizar eventos. En el caso que dicha seal sea de una fuente externa al
microcontrolador (Fext), es especialmente til para contar el nmero de pulsos que dicha seal genera en el
tiempo ya que cada pulso de dicha seal incrementa el TMR0.
Ejemplo: Queremos medir el intervalo de tiempo entre los pulsos del cardiograma de un paciente.
Usando el timer como temporizador, podemos contar por ejemplo- periodos de 1 ms, acumulndolos en un
registro auxiliar. Cada vez que ocurra un pulso del electrocardiograma podemos consultar el registro auxiliar y
ver cuntos incrementos han sucedido desde el ltimo 2 pulsos y sabiendo que el temporizador cuenta periodos
de 1ms, calcular el tiempo transcurrido.
Una vez conocido el tiempo, iniciamos la cuenta de los incrementos desde 0 para el siguiente pulso.

Estructura general del Timer0


La figura que sigue se muestra el temporizador (TMR0) y el temporizador perro guardin (WDT) en
diagrama de bloques. Al pie de la figura (en amarillo) los bits relacionados, de cada registro que afecta el ajuste
de los temporizadores.

Entrada de reloj del modulo Timer0


Como anteriormente se indic, la seal de reloj base de entrada al mdulo Timer0 se puede obtener de
dos maneras: con un oscilador externo a travs de la patilla RA4/T0CKI -Fext-, o bien con el oscilador interno de
instrucciones -Fint- (recordemos que es un cuarto de la frecuencia de oscilacin del microcontrolador).
Tambin podemos indicar si el disparo se realizar por flanco ascendente o flanco descendente de la seal.
La configuracin la podemos realizar con los siguientes bits de control:

T0SC (Timer0 Clock Select) en el registro OPTION_REG[5]: Indica el origen del reloj del
contador: oscilador interno o seal externa
T0SE (Timer0 Set Edge) en el registro OPTION_REG[4]: Cuando se selecciona seal
externa, indica el flanco activo que se usar.

El prescaler
El prescaler es un circuito que permite modificar la frecuencia del reloj de entrada del Timer0, dividiendo esta y
generando una nueva seal de menor frecuencia a la salida que ser la seal de reloj de entrada al registro
TMR0. El prescaler es una facilidad para cuando la seal de entrada es demasiado rpida para nuestros
propsitos y necesitamos ralentizarla.
Nota: El prescaler tambin se puede utilizar con el registro WDT (Watch Dog Timer) del PIC, pero en este caso
recibe el nombre de postescaler ya que se usa a la salida del WDT, no pudiendo estar asignado a la vez al
Timer0 y al WDT.
El prescaler del registro TMR0 es configurado a travs de 3 bits del registro OPTION_REG, ( PS2,PS1,PS0), y
permite dividir la frecuencia de una seal por 1, 2, 4, 8, 16, 32, 64, 128 o 256. En caso de utilizar un divisor por
1, la seal de salida es la de entrada sin ningn cambio.
Por ejemplo:
Si usamos como oscilador externo del PIC un cristal de 4Mhz, entonces el reloj interno de instrucciones
funciona a Fint = 4Mhz /4 = 1 Mhz.
Si el Timer0 usa la seal del reloj interno y la pasamos por el prescaler configurado para una divisin
por 4, la seal a la salida del prescaler ser Fpresc = 250 Khz.
La configuracin se realiza con los siguientes bits de control:
PSA (Post Scaler Assignament) en el registro OPTION_REG[3]: indica si el postscaler es

asignado al WDT (1) o al Timer0 (0).


PS2:0 en el registro OPTION_REG[2:0]: Indican el valor del divisor a utilizar en el

postscaler .

No debemos confundir la frecuencia de trabajo base del Timer0, con la frecuencia de trabajo del registro
TMR0: la primera es la frecuencia de entrada utilizada por el modulo, mientras que la segunda es dicha
frecuencia dividida por el prescaler y que es el reloj del registro TMR0.

El REGISTRO TMR0
El registro TMR0 es el corazn del mdulo Timer0. Es un registro contador de 8 bits (podemos contar hasta
28=256 valores, entre 0 y 255) que incrementa automticamente su contenido en cada oscilacin de su seal
de reloj Ftmr0 Cuando el valor del registro TMR0 pasa de 255 a 0, se produce una interrupcin por
desbordamiento u overflow. El PIC indica esta situacin activando el flag de interrupcin por desbordamiento
T0IF (Timer0 Interrupt Flag) del registro INTCON. Para ejecutar la rutina de interrupcin adems deben estar
habilitadas tanto las interrupciones globales como la especfica para el Timer0:
1. Interrupciones globales activadas: bit GIE (Global Interrupt Enable) de INTCON[7] activo.
2.

Mascara de interrupcin de Timer0 activada: bit T0IE (Timer0 Interrupt Enable) de INTCON[5]
activo
3. Ocurri un desbordamiento en el Timer0: bit T0IF (Timer0 Interupt Enable) de INTCON[2]
Activo.

Sincronizacin del Timer0


El TMR0 podra plantear algunos problemas si se modifica al mismo tiempo que este se incrementa. El
PIC resuelve esto internamente, mediante un mecanismo de sincronizacin de la seal de reloj del TMR0
cuando se escribe un dato en el Timer0 para ello se usa un registro de desplazamiento de 2 bis a la salida del
reloj del TMR0 de forma que produce un retraso de 2 * Fosc/4 en la seal que incrementa el contador (2 s con
un cristal de 4 Mhz; 1 con 8 Mhz). Esto se traduce en que cuando se escribe un dato en el TMR0, se
conecta al reloj interno introduciendo un retraso de 2 cuentas, en los cuales no ocurre nada en el TMR0 y ese
tiempo es aprovechado para escribir el dato escrito Estas dos cuentas de retraso nos permiten escribir y leer sin
interferencias con la cuenta actual del contador.
Una vez asignado el prescaler al Timer0, una instruccin que escriba el Timer0, provocar el borrado del
prescaler y sincronizar el reloj con el Timer0.

EL PROCESO
Cuando el valor del registro TMR0 pasa de 255 a 0 (0XFF a 0X00), se produce una interrupcin por
desbordamiento u overflow. El PIC indica esta situacin activando el flag de interrupcin por desbordamiento
T0IF (Timer0 Interrupt Flag) del registro INTCON. Para ejecutar la rutina de interrupcin adems deben estar
habilitadas tanto las interrupciones globales como la especfica para el Timer0:
1. Interrupciones globales activadas: bit GIE (Global Interrupt Enable) de INTCON[7] activo.
2. Mascara de interrupcin de Timer0 activada: bit T0IE (Timer0 Interrupt Enable) de INTCON[5]activo
3. Ocurri un desbordamiento en el Timer0: bit T0IF (Timer0 Interrupt Enable) de INTCON[2] activo.

El proceso en general es muy similar al que se sigue con cualquier otra interrupcin: si se dan las tres
condiciones el PIC comienza a ejecutar la rutina de servicio de interrupcin, deshabilitando estas (GIE=0). La
rutina de interrupcin debera comprobar el flag T0IF para determinar el origen de la interrupcin y, si ocurri
una interrupcin por desbordamiento, borrar el flag T0IF (debemos hacerlo nosotros pues no es automtico),
para evitar que el PIC vuelva a la rutina de interrupcin cuando las interrupciones sean de nuevo habilitadas. A
la salida de la rutina de interrupcin con la instruccin retfie el PIC habilita estas de nuevo (GIE=1).
IMPORTANTE: El registro TMR0 contina incrementndose siempre segn dicta su reloj, por lo que si se
ha producido un desbordamiento, el registro seguir contando desde 0. Si interesa que la cuenta comience
desde un valor predeterminado, debemos precargar el TMR0 con dicho valor una vez detectado el
desbordamiento. Esto se realiza normalmente dentro de la rutina de interrupcin.

OBSERVACIONES:
1

Si el microcontrolador est dormido (mediante una instruccin SLEEP) y se utiliza como seal de
reloj del Timer0 el reloj interno de instrucciones, el Timer0 estar desactivado y no se incrementar
el contador TMR0 ya que el reloj interno se haya detenido. Por tanto jams se producir ninguna
interrupcin por desbordamiento que permita salir del estado SLEEP.

Si la fuente de la seal de reloj del modulo Timer0 es externa, si se puede producir interrupcin
miento, ya que aunque el Timer0 este desactivado, el contador no depende activamente del reloj
interno (parado) del microcontrolador sino que se incrementa en cada pulso de la seal externa. En
este caso si se puede salir del estado SLEEP a travs de la interrupcin.

Ejemplo:
Consideremos el diseo de un programa encargado de contar eventos con el timer TMR0, de tal
manera que cada seis eventos incrementar un contador hecho con el PORTA, cuyo valor binario se
visualizar en los leds conectados a l.
Veamos el programa fuente:
LIST
INCLUDE

P=16F877
<p16f877.inc>

; CONSTANTES
ValIni

EQU

D250 ; Valor inicial del timer

;PROGRAMA
org
goto
org
btfsc
goto
retfie

0X0000
Inicio
0X0004
; VECTOR DE INTERRUPCION
INTCON,T0IF ; Comprueba si la interrupcin es del timer.
IntExt
; RETORNA INTERRUPCION, GEI se vuelve al valor 1 automticamente

IntExt: incf
movlw
movwf
bcf
retfie

PORTA
ValIni
;Se reinicia con valor inicial del timer 0.
TMR0
INTCON,T0IF ;Se limpia FLAG TMR0.

Inicio: Bsf
Movlw
Movwf
movlw
movwf
Bcf
movlw
Movwf
movlw
movwf
bsf
Bsf
Fin:

STATUS,RP0
b'11110000
TRISA
b'11111000
OPTION_REG
STATUS,RP0
0X00
PORTA
ValIni
TMR0
INTCON,GIE
INTCON,T0IE
Goto fin

;Activa la pagina 1
;RA0..RA3 como salida.
;Valor de la preescala.
;Activa la pagina 0.

;valor inicial del timer 0.


;Activa todas las interrupciones.
;Activa la interrupcin del timer.
; Bucle de parada.

End

Analicemos el programa:
El valor de TMR0 se inicializa con ValIni (250), con lo que cada 6 pulsaciones en la tecla conectada
al pin RA4/T0CKI, el TMR0 pasara de 255 a 0, generando una interrupcin que incrementara el valor
del contador formado por los leds conectados al PORTA.
Lo importante a destacar es la programacin del OPTION_REG para configurar el TMRO.
Veamos dos ejemplos:

OPTION_REG = b11111000 : Con este valor hacemos T0CS=1 ( pone el timer


en modo contador de eventos), T0SE=1 ( el contador se incrementar con el
flanco de bajada de la seal el RA4/T0CKI), PSA=1 ( el divisor esta asignado al
WDT por lo que el ratio de la seal ser 1:1). Con esta configuracin se
necesitarn 6 pulsos para incrementar el valor de los leds.

OPTION_REG = b11110000 : Con este valor hacemos T0CS=1 ( pone el timer


en modo contador de eventos), T0SE=1 ( el contador se incrementar con el
flanco de bajada de la seal el RA4/T0CKI), PSA=0 ( el divisor esta asignado al
TMR0 por lo que el ratio de la seal vendr determinado por el valor de
PS2:PS0, como es 000 el rango ser 1:2. Con esta configuracin se necesitarn
12 pulsos para incrementar el valor de los leds.

Vous aimerez peut-être aussi