Sistemas Microprocesados I UPS Autor: Ing. Junior Figueroa
1
TEMPORIZADORES
En muchas aplicaciones el microcontrolador debe trabajar con la variable tiempo. Por
ejemplo, para generar señales de una determinada frecuencia, para medir la duración de
una señal, o simplemente para llevar la fecha y la hora, así pues el microcontrolador
necesita algún recurso para contar el tiempo con precisión.
El microcontrolador PIC16F877A cuenta con tres módulos básicos para temporizar, que se
identifican con los nombres Timer0, Timer1 y Timer2. Además este microcontrolador
cuenta con módulos adicionales para temporizar, que amplían las posibilidades de los
módulos básicos. Son los denominados módulos de Comparación, Captura y Modulación
Pulsos en Anchura o módulos CCP (Capture/Compare/PWM), que comparten componentes
y funciones con el Timer1 y el Timer2.
1. LOS TEMPORIZADORES EN EL PIC16F877A
Cada uno de los temporizadores disponibles en el PIC16F877A tiene como elemento
esencial un contador sincrónico ascendente de 8 o 16 bits. Estos contadores se pueden
programar para contar pulsos internos o externos, según se expondrá más adelante al
estudiar cada temporizador por separado. El número almacenado en cada contador (valor
de la cuenta) se puede leer o modificar mediante la lectura o escritura de registros de
funciones especiales asociados al temporizador en cuestión. El desbordamiento de los
contadores queda reportado en bits indicadores disponibles en esos registros, y puede
generar también una solicitud de interrupción al microcontrolador. La figura 1 muestra el
esquema general de los módulos para temporizar Timer0, Timer1 y Timer2, cuyas
principales características se resumen en la Tabla1.
Figura 1: Esquema de bloques general de los temporizadores del PIC16F877A.
Los temporizadores pueden disponer de un contador asincrónico auxiliar. Este contador
auxiliar se inserta en el camino de los pulsos, antes del contador principal, en cuyo caso
funciona como un pre-divisor (prescaler) o después del contador principal, funcionando
entonces como post-divisor (postscaler). Los temporizadores Timer0 y Timer1 tienen
solamente un pre-divisor; el Timer2, en cambio, dispone de un pre-divisor y un post-divisor.
Sistemas Microprocesados I UPS Autor: Ing. Junior Figueroa
2
Tabla 1: Característica principales de los temporizadores del PIC16F877A.
1.1. EL MÓDULO TIMER0
El módulo Timer0 consta básicamente de un pre-divisor y un contador ascendente de 8 bits
(figura 2). El pre-divisor es un contador asincrónico ascendente con factor de división
programable cuyo conteo no es visible para el programador. El contador ascendente de 8
bits se puede leer o escribir a través del registro de funciones especiales TMR0.
Figura 2: Diagrama de bloques del Timer0.
El Timer0 puede trabajar como contador de ciclos de máquina o como contador de pulsos externos. En el primer caso se dice que el módulo opera en el modo temporizador (timer) y los pulsos de reloj que llegan al Timer0 llegan con una frecuencia 𝐹𝑂𝑆𝐶 4⁄ , donde 𝐹𝑂𝑆𝐶 es la frecuencia del oscilador principal del PIC. Si cuenta pulsos externos, el módulo opera como contador (counter). Los pulsos externos llegan por el terminal RA4/T0CKI/C1OUT del microcontrolador. A su paso por el Timer0, los pulsos llegan al bloque de sincronización. En este bloque, los
pulsos que entran son muestreados en dos instantes de tiempo dentro de cada ciclo de
máquina, de lo que resulta una señal cuyos flancos ocurren en fase con el reloj del
microcontrolador. Con esta señal sincronizada se excita el contador TMR0.
Cuando el Timer0 trabaja en el modo contador, el bloque de sincronización determina el
valor mínimo del periodo (o la frecuencia máxima) de los pulsos que entran por el terminal
RA4/T0CKI/C1OUT del microcontrolador. Si 𝑇𝑂𝑆𝐶 es el periodo del oscilador principal del
microcontrolador y 𝑃 es el factor de división del pre-divisor, el período 𝑇𝑖 de los pulsos que
entran por el terminal T0CKI debe cumplir
𝑇𝑖 >4 𝑥 𝑇𝑂𝑆𝐶
𝑃
Sistemas Microprocesados I UPS Autor: Ing. Junior Figueroa
3
donde 𝑃 = 1 si no se usa el pre-divisor y 𝑃 = 2, 4, … , 256 si se usa.
Hay tres registros de funciones especiales asociados al Timer0: TMR0, OPTION_REG e
INTCON. La figura 3 muestra los nombres de los bits de los registros OPTION_REG e INTCON.
El registro TMR0 almacena el valor que tiene el contador del Timer0. Este valor se puede
leer o escribir en cualquier momento desde el programa que ejecuta el microcontrolador.
Cuando se escribe un valor en TMR0, la cuenta del pre-divisor, si está asignado al Timer0,
se pone a 0. Además, una escritura en el registro TMR0 inhibe el conteo del Timer0 durante
dos ciclos de máquina.
Figura 3: Registros de funciones especiales OPTION_REG e INTCON.
El desbordamiento del Timer0 hace que el indicador TMR0IF (bit 2 del registro INTCON)
pase a 1. Si la atención al Timer0 se hace usando la técnica de E/S programada, entonces se
debe consultar el bit TMR0IF para saber si el Timer0 se ha desbordado.
Si la interrupción del Timer0 está habilitada, lo cual se hace poniendo a 1 el bit TMR0IE (bit
5 del registro INTCON), cuando se desborda el Timer0 se produce una solicitud de
interrupción.
En el registro OPTION_REG están los bits de control del Timer0. La fuente de los pulsos de
reloj se selecciona con el bit T0CS. Si se selecciona una fuente de reloj externa en el terminal
RA4/T0CKI/C1OUT, el bit T0SE sirve para hacer que el contador se incremente con los
flancos de subida (con T0SE = 0) o de bajada (con T0SE = 1) de los pulsos en T0CKI.
El Timer0 y el WDT comparten el pre-divisor, en un esquema como el que se muestra en la
figura 4. El pre-divisor, un contador asincrónico ascendente de 8 bits, puede ser asignado al
Timer0 o al WDT. Esta asignación es excluyente, es decir, si el pre-divisor se asigna al WDT,
el Timer0 no lo puede usar y viceversa. Cuando está asignado al WDT, el pre-divisor funciona
como post-divisor del Perro Guardián.
El pre-divisor se asigna al Timer0 poniendo a 1 el bit PSA (bit 3 del registro OPTION_REG).
Si PSA es puesto a 0, el pre-divisor queda asignado al WDT. El factor de división del pre-
divisor asignado al Timer0 se selecciona con los bits PS2, PS1 y PS0 del registro
OPTION_REG.
Sistemas Microprocesados I UPS Autor: Ing. Junior Figueroa
4
Figura 4: El pre-divisor se puede asignar al Timer0 o al Perro Guardián (WDT).
El factor de división 𝑃 del pre-divisor asignado al Timer0 puede tomar los valores:
𝑃 = 2, 4, 8, … , 2𝑛+1, … , 256
donde 𝑛 = 1, 2, … , 7 es el valor situado en los bits PS2:PS0.
Para calcular el tiempo de desbordamiento del Timer0 se puede proceder de la siguiente
forma. Sea 𝑁 la cantidad de pulsos que deben llegar al Timer0 para que se desborde, 𝑃 el
factor de división del pre-divisor y 𝑇𝑖 el período de los pulsos de entrada al pre-divisor. Si el
Timer0 opera como temporizador, entonces 𝑇𝑖 es la duración de un ciclo de máquina (𝑇𝑖 =
4 𝐹𝑂𝑆𝐶⁄ ); si opera como contador, 𝑇𝑖 es el período de los pulsos externos. El tiempo 𝑇𝑑 que
tarda en desbordarse el Timer0 es
𝑇𝑑 = 𝑇𝑖 𝑥 𝑃 𝑥 𝑁
Debe tenerse en cuenta que el valor que se carga en el registro TMR0 es el valor inicial
desde donde el Timer0 empezará la cuenta hasta llegar al valor máximo de 256. Se puede
afirmar que 𝑁 = 256 − 𝑁𝑇𝑀𝑅0, donde 𝑁𝑇𝑀𝑅0 es el valor inicial que se cargará en el registro
TMR0. Por lo tanto, la ecuación anterior puede reescribirse como
𝑇𝑑 = 𝑇𝑖 𝑥 𝑃 𝑥 (256 − 𝑁𝑇𝑀𝑅0)
1.2. EL MÓDULO TIMER0 EN C
La función para configurar el Timer0 es:
setup_timer_0 (modo);
donde modo está definido en el fichero de cabecera (afecta a los bits 5:0 del registro
OPTION_REG):
Sistemas Microprocesados I UPS Autor: Ing. Junior Figueroa
5
Tabla 2: Posibles valores que se pueden colocar en modo.
Los distintos modos se pueden agrupar mediante el empleo del símbolo |, como se muestra
en el siguiente ejemplo:
setup_timer_0 (RTCC_DIV_2 | RTCC_EXT_L_TO_H)
donde el orden de las posiciones de las etiquetas que están en paréntesis es irrelevante.
Sistemas Microprocesados I UPS Autor: Ing. Junior Figueroa
6
El compilador C suministra una serie de funciones para leer o escribir en el Timer0. Para
escribir un valor en el registro TMR0:
set_timer0 (valor);
valor: entero de 8 bits.
Para leer el valor actual del registro:
valor = get_timer0 ( );
valor = entero de 8 bits.
Ejemplo 1: Generar una señal cuadrada de 1 kHz utilizando la interrupción Timer0 (ver
figura 5). Para visualizar la frecuencia y la señal generada utilice los instrumentos virtuales
OSCILLOSCOPE y COUNTER TIMER ubicados en INSTRUMENTS ( ).
Figura 5: Circuito para generar la señal de 1 KHz del ejemplo 1.
Sistemas Microprocesados I UPS Autor: Ing. Junior Figueroa
7
Para generar una señal de 1 kHz se necesita un semiperiodo de 500 𝜇𝑠. Según la ecuación
de desbordamiento del registro TMR0, utilizando un cristal de 4 MHz un factor de división
de 2 del pre-divisor se tiene:
𝑇𝑑 = 𝑇𝑖 𝑥 𝑃 𝑥 (256 − 𝑁𝑇𝑀𝑅0)
500 𝜇𝑠 = (4
4000000) 𝑥 2 𝑥 (256 − 𝑁𝑇𝑀𝑅0 )
donde 𝑁𝑇𝑀𝑅0 = 6, es decir, se debe cargar el registro TMR0 con el valor de 6. Pero esta
relación sólo se cumple si se trabaja en ensamblador. Al trabajar en C, el compilador genera
líneas de código que aumentan el tiempo de ejecución del programa y, por ello, es necesario
ajustar el valor final sumándole un valor de 20 o 21. En este caso se ha utilizado un valor de
carga de 26 (0x1A).
PROGRAMA:
El compilador se encarga al entrar en la interrupción de habilitar la interrupción por
desbordamiento del Timer0 (TMR0IE = 1) y al salir de borrar el bit indicador (TMR0IF = 0),
por lo que no es necesario hacerlo por programa.
Se puede observar la señal con el osciloscopio digital y activando los cursores en el menú
de Trigger (figura 6) y la medida es de 1000 ms.
Sistemas Microprocesados I UPS Autor: Ing. Junior Figueroa
8
Figura 6: Señal cuadrada capturada por el osciloscopio digital.
1.3. EL MÓDULO TIMER1
El Timer1 es un segundo módulo disponible para procesos de temporización en el
PIC16F877A y su estructura se muestra en la figura 7. Costa fundamentalmente de un
contador ascendente de 16 bits precedido por un pre-divisor programable con factor de
división de 1, 2, 4 u 8.
Figura 7: Diagrama de bloques del Timer1.
Sistemas Microprocesados I UPS Autor: Ing. Junior Figueroa
9
El Timer1 puede operar como temporizador (al contar ciclos de máquina) o como contador
(si cuenta pulsos externos). Como contador, el Timer1 puede ser programado para que
trabaje en modo sincronizado o en modo no sincronizado. Para ello se usa el bit 𝑇1𝑆𝑌𝑁𝐶̅̅ ̅̅ ̅̅ ̅̅ ̅̅ ̅
del registro T1CON. Si 𝑇1𝑆𝑌𝑁𝐶̅̅ ̅̅ ̅̅ ̅̅ ̅̅ ̅ = 0, el Timer1 trabaja como contador sincronizado, pue los
pulsos de entrada al contador TMR1 pasan por el bloque de sincronización. En este bloque
se muestrea la señal entrante y se sincroniza con el reloj interno del microcontrolador, de
lo que resulta una señal cuyos flancos ocurren en fase con el reloj principal del PIC. La señal
ya sincronizada excita el contador de 16 bits TMR1, formado por los registros TMR1L y
TMR1H.
Los modos sincronizado y no sincronizado se aplican sólo al trabajo del Timer1 como
contador, pues cuando este módulo opera como temporizador, lo hace obviamente en
modo sincronizado. De hecho, el bit 𝑇1𝑆𝑌𝑁𝐶̅̅ ̅̅ ̅̅ ̅̅ ̅̅ ̅ se ignora si el Timer1 se programa como
temporizador con 𝑇𝑀𝑅1𝐶𝑆 = 0.
Si 𝑇𝑂𝑆𝐶 es el periodo del oscilador principal del microcontrolador y 𝑃 es el factor de división
del pre-divisor (𝑃 = 1, 2, 4, 8) entonces el período 𝑇𝑖 de los pulsos en el terminal
RC0/T1OSO/T1CKI debe cumplir
𝑇𝑖 >4 𝑥 𝑇𝑂𝑆𝐶
𝑃
Si el Timer1 está programado como contador no sincronizado (𝑇1𝑆𝑌𝑁𝐶̅̅ ̅̅ ̅̅ ̅̅ ̅̅ ̅ = 1), continúa
operando incluso cuando el microcontrolador esté en el modo de bajo consumo. Esta
característica del Timer1 lo hace apropiado para implementar con él un reloj de tiempo real
(RTC: Real Time Clock).
El valor del conteo se puede leer y/o escribir en los registros de funciones especiales TMR1H
y TMR1L. Cuando se escribe en estos registros, la cuenta del pre-divisor va a 0.
Figura 8: T1CON, registro de control del Timer1.
En el registro T1CON están los bits de control del Timer1. La fuente de los pulsos de reloj se
selecciona con el bit TMR1CS y puede ser interna o externa. Si se selecciona el reloj externo,
éste puede ser pulsos que entren por el terminal RC0/T1OSO/T1CKI o también puede
colocarse un cristal entre los terminales RC0/T1OSO/T1CKI y RC1/T1OSI/CCP2. El bit
T10SCEN sirve para habilitar el oscilador si se usa un cristal. Con el bit TMR1ON se habilita
el conteo.
Sistemas Microprocesados I UPS Autor: Ing. Junior Figueroa
10
El valor 𝑛 (𝑛 = 0, 1, 2, 3) de los bits T1CKPS1 y T1CKPS0 del registro T1CON fija el factor de
división 𝑃 (𝑃 = 1, 2, 4, 8 = 2𝑛) del pre-divisor del Timer1. Por ejemplo, si se quiere un factor
de división de 8, hay que poner el valor 3 en los bits mencionados.
El desbordamiento del Timer1 hace que el bit TMR1IF del registro PIR1 pase a 1. Si la
interrupción del Timer1 está habilitada, lo cual se hace poniendo a 1 el bit TMR1IE registro
PIE1, el desbordamiento genera una interrupción.
El cálculo del tiempo de desbordamiento del Timer1 sigue un razonamiento semejante al
utilizado en el Timer0. Si 𝑁 es la cantidad de pulsos que deben llegar al Timer1 (contador
de 16 bits) para que éste se desborde, 𝑃 el factor de división del pre-divisor y 𝑇𝑖 el período
de los pulsos de entrada al pre-divisor, el tiempo 𝑇𝑑 que tarda en desbordarse el Timer1 es
𝑇𝑑 = 𝑇𝑖 𝑥 𝑃 𝑥 𝑁
Si el Timer1 opera como temporizador, entonces 𝑇𝑖 es la duración de un ciclo de máquina
(𝑇𝑖 = 4 𝐹𝑂𝑆𝐶⁄ ); si opera como contador, 𝑇𝑖 es el período de los pulsos externos.
Debe tenerse en cuenta que el valor que se carga en la pareja de registros TMR1L y TMR1H
es el valor inicial desde donde el Timer1 empezará la cuenta hasta llegar al valor máximo
de 65536. Se puede afirmar que 𝑁 = 65536 − 𝑁𝑇𝑀𝑅1, donde 𝑁𝑇𝑀𝑅1 es el valor inicial que
se cargará en los registros TMR1L y TMR1H. Por lo tanto, la ecuación anterior puede
reescribirse como
𝑇𝑑 = 𝑇𝑖 𝑥 𝑃 𝑥 (65536 − 𝑁𝑇𝑀𝑅1)
Si el Timer1 se deja correr libremente, entonces, de modo natural, 𝑁 = 216. En este caso,
𝑇𝑑 = 𝑇𝑖 𝑥 𝑃 𝑥 216
1.4. EL MÓDULO TIMER1 EN C
La configuración del módulo Timer1 en el compilador de C se realiza a través de la función:
setup_timer_1 (modo);
Donde modo está definido en el fichero de cabecera (afecta a los bits 5:0 del registro
T1CON). En la tabla 3 se pueden observar las posibles alternativas que se pueden colocar
en modo.
Los distintos modos se pueden agrupar mediante el empleo del símbolo |.
Sistemas Microprocesados I UPS Autor: Ing. Junior Figueroa
11
Tabla 3: Posibles valores que se pueden colocar en modo.
La lectura y escritura en el registro TMR1 se realiza a través de las siguientes funciones:
valor = get_timer1 ( );
set_timer1 (valor);
donde valor es un entero de 16 bits.
Ejemplo 2: Generar una función que permita realizar retardos de 1 segundo empleando el
temporizador Timer1. Este retardo será mostrado en un LED conectado al terminal RB1 y se
comprobará dicho valor utilizando el instrumento virtual COUNTER TIMER ubicado en
INSTRUMENTS ( ).
Sistemas Microprocesados I UPS Autor: Ing. Junior Figueroa
12
Figura 8: Circuito para visualizar y medir el retardo de 1 segundo del ejemplo 2.
Se calcula un periodo de 0.5 segundos y se repite dos veces. Según la ecuación de
desbordamiento del registro TMR1, utilizando un cristal con 𝐹𝑂𝑆𝐶 = 4 𝑀𝐻𝑧, un factor de
división de 8 del pre-divisor se tiene:
𝑇𝑑 = 𝑇𝑖 𝑥 𝑃 𝑥 (65536 − 𝑁𝑇𝑀𝑅1)
0.5 𝑠 =4
4000000 𝑥 8 𝑥 (65536 − 𝑁𝑇𝑀𝑅1)
donde 𝑁𝑇𝑀𝑅1 = 3036, es decir, se debe cargar el registro TMR1 con el valor de 3036
(0xBDC).
Para observar mejor el periodo se va a conectar el terminal RB1 a la entrada CE del
COUNTER TIMER y el modo de funcionamiento se lo coloca en TIME (secs).
Sistemas Microprocesados I UPS Autor: Ing. Junior Figueroa
13
PROGRAMA:
También se podría realizar sin interrupciones, esperando a que el registro TMR1 se
desbordase.
Recommended