Académique Documents
Professionnel Documents
Culture Documents
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.
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
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.
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
;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.
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: