Está en la página 1de 17

CAPITULO 4

TEMPORIZADORES
DE AVRs
PROGRAMACION EN
C

OBJECTIVOS

Al terminar este capítulo, usted será capaz de:

»Listar los temporizadores de los AVR ATMEGA y sus registros asociados


»Describir los modos Normal y CTC del timer AVR
»Programar los temporizadores en C y generar retardos de tiempo
»Programa los contadores del AVR en C y obtener contadores de eventos

Muchas aplicaciones necesitan contar un evento o generar retardos de tiempo. Por lo


tanto, hay registros de conteo en los microcontroladores para este fin. Cuando
queremos contar un acontecimiento, conectamos el origen del evento externo al pin
de reloj del registro contador. Entonces, cuando se produce un evento externo, el
contenido del contador se incrementa, de esta manera, el contenido del contador
representa cuántas veces ha ocurrido un evento. Cuando queremos generar retardos
de tiempo, se conecta el oscilador al pin de reloj del contador. Así, mientras el
oscilador corre, el contenido del contador se incrementa. Como resultado, el
contenido del contador representa cuantos pulsos han ocurrido desde el momento en
que se haya borrado el contador. Dado que la velocidad del oscilador del
microcontrolador conoce, se puede calcular el período de cada pulso, y con el
contenido del registro contador sabremos cuánto tiempo ha transcurrido.

Por lo tanto, una manera de generar un retardo de tiempo es borrar el contador en el


momento de inicio y esperar hasta que el contador alcanza un número determinado,
por ejemplo, considerar un microcontrolador con un oscilador con una frecuencia de 1
MHz, el contenido del registro contador incrementa una vez por microsegundo. Por lo
tanto, si queremos un retardo de tiempo de 100 microsegundos, debemos borrar el
contador y espere hasta que llega a ser igual a 100.
En los microcontroladores, hay una bandera para cada uno de los contadores. El flag o
indicador es puesto a uno cuando se desborda el contador, y se borra por software. El
segundo método para generar un retardo de tiempo es cargar el registro contador con
un valor y esperar a que se desborde y la bandera se establezca a uno. Por ejemplo, en
un microcontrolador con una frecuencia de 1 MHz, con un registro contador de 8-bit, si
queremos un retardo de 3 microsegundos, se puede cargar el registro del contador con
0xFD y esperar hasta que el indicador se establezca a uno después de 3 pulsos.
Después del primer pulso, el contenido del registro incrementa a 0xFE; después del
segundo a 0xFF, y después del tercero, se desborda (el contenido del registro se
convierte en 0x00) y el indicador se ha establecido a uno.
El AVR tiene hasta seis temporizadores dependiendo del miembro de la familia. Se les
conoce como temporizadores 0, 1,2,3,4, y 5. Se pueden utilizar como temporizadores
para generar un retardo de tiempo o como contadores para contar eventos que tienen
lugar fuera del microcontrolador.
En el AVR algunos de los temporizadores / contadores son 8-bit y algunos son 16-bit,
En el ATMEGA8, hay tres temporizadores: Timer0, Timer 1 y Timer2. Timer0 y Timer2
son 8-bits, mientras que Timer1 es l6 bits.
Si aprende a utilizar los temporizadores del ATMEGA8, podrá usar los temporizadores
de otros AVRs.

PROGRAMACIÓN DE TEMPORIZADORES 0,1 Y 2

Cada temporizador requiere un pulso de reloj que produzca el incremento en


contador. La fuente de reloj puede ser interna o externa. Si nosotros utilizamos la
fuente de reloj interna, la frecuencia del cristal oscilador se alimenta al temporizador,
Por lo tanto, se utiliza para la generación de retardos de tiempo y consecuentemente
es llamado temporizador. Al elegir la opción de reloj externa, alimentamos con pulsos
a través de un pin del AVR, así es llamado contador.

Registros básicos de los temporizadores

Examine la figura. En el AVR, para cada uno de los Timers hay


un registro TCNTn. Esto significa que en el ATMEGA8 tenemos
TCNT0, TCNT1 y TCNT2. El registro TCNTn es un contador.
Después del reset, TCNTn contiene cero. Cuenta con cada
pulso. Al contenido de los temporizadores / contadores se
puede acceder usando TCNTn. Se puede cargar un valor en el
registro TCNTn o leer su valor.
Cada temporizador tiene una bandera de desbordamiento
TOVn (timer overflow). Cuando un desbordamiento ocurre en
el temporizador, su bandera TOVn se establecerá a uno.
Cada temporizador también tiene un registro de control
llamado TCCRn (timer/counter control register), utilizado
para el establecimiento de modos de funcionamiento. Por
ejemplo, puede especificarle a un Timer para que trabaje
como un temporizador o un contador cuando se le cargue con
valores adecuados en TCCRO.
Cada temporizador también tiene un Registro OCRn (Output Compare Registrarse), el
contenido del OCRn se compara con el contenido del TCNTn. Cuando son iguales, la
bandera OCFn (Output Compare Flag) se establecerá a uno.
Los registros del temporizador se encuentran en la memoria de registro l/O.
Programación del Timer 0
Este es un timer de 8 bits y posee un registro contador TCNT0 de 8 bits.

TCCRO (Timer / Counter Control de Register)


TCCRO es un registro de 8-bit utilizado para el control del Timer0.
Los bits para TCCRO se muestran en la Figura

.
FOC0 : es D7 Force compare match: Esto es de sólo escritura, puede utilizarse mientras
se genera una onda. Escribirle un 1 causa que al generar la onda actué como si un
match de comparación se ha producido.
WGMO0, WGMO1
D6 D3 bits de selección del modo del Timer0
0 0 normal
0 1 CTC (Borrar contador en comparación Match)
1 0 PWM, fase correcta
1 1 PWM rápido
COM01:COM00 DS D4 Comparar Modo de salida: Estos bits controlan el generador de
forma de onda.
CS02: CS00
D2 DI D0 Selector fuente de reloj del Timer 0
0 0 0 Ninguna fuente (Timer / Contador parado)
0 0 1 CLK (Sin preescalar)
0 1 0 CLK / 8
0 1 1 CLK 1/64
1 0 0 CLK / 256
1 0 1 CLK / 1024
1 1 0 fuente de reloj externa en el pin T0 con flanco descendente.
1 1 1 fuente de reloj externa en el pin T0 con flanco ascendente.

CS02: CS00 (selección de fuente de reloj)


Estos bits en el registro TCCRO se utilizan para seleccionar la fuente de reloj. Si CS02:
CS00 = 000, entonces se detiene el contador. Si CS02-CS00 tienen valores entre 001 y
101, el oscilador se utiliza como fuente de reloj y el temporizador / contador actúa
como un temporizador. En este caso, los temporizadores se utilizan con frecuencia
para la generación de retardo de tiempo.
Ejemplo 1:
Encuentra el valor de TCCR0 si queremos programar el Timer 0 en modo Normal, no
preescalar, Usando un cristal oscilador en el AVR para la fuente de reloj.
Solución:

Ejemplo 2:
Encuentra la frecuencia del reloj del temporizador y su periodo para varios sistemas
basados en AVR, con las siguientes frecuencias de cristales. Supongamos que no se
utiliza preescalar.
(a) 10 MHz
(b) 8 MHz
(c) 1 MHz
Solución:
(a) F = 10 MHz y T = 1/10 MHz = 0,1 uS
(b) F = 8 MHz y T = 1/8 MHz = 0,125 uS
(c) F = 1 MHz y T= 1/1 MHz = 1 uS

Si CS02:CS00 tienen un valor igual a 110 o 111, se utiliza una fuente de reloj externa y
actúa como un contador.
Registro TIFR (Timer/counter Interrupt Flag Register)

El registro TIFR contiene las banderas de diferentes temporizadores, como se muestra


en la Figura. Trataremos la bandera TOV0, que se relaciona con temporizador 0.

TOV0 D0 bit indicador de Desbordamiento del Timer 0


0 = Timer 0 sin desbordamiento.
1 = Timer 0 se ha desbordado (pasando de 0xFF a 0x00).
OCF0 D1 bit indicador de salida de comparación del Timer 0
0 = no tuvo lugar un match de comparación..
1 = ocurrió un match de comparación.
TOV1 D2 1 bit indicador de desbordamiento del Timer 1
OCF1B D3 bit indicador de salida de comparación B del Timer 1
OCFIA D4 bit indicador de salida de comparación A del Timer 1
ICF1 D5 bandera de entrada de Captura
TOV2 D6 bit indicador de Desbordamiento del Timer 2
OCF2 D7 bit indicador de salida de comparación del Timer 2

TOV0 (Timer 0 Overflow)


Este flag es puesto a uno cuando se desborda el contador, al pasar de 0xFF a 0x00.
Cuando el temporizador incrementa de 0xFF a 0x00, la bandera TOV0 se pone a 1 y
permanece en uno hasta que se borra por software.
El modo normal
En este modo, el contenido del temporizador / contador incrementa con cada pulso.
Se cuenta hacia arriba hasta que alcanza el máximo de 0xFF. Cuando pasa de 0xFF a
Ox00, fija a uno la bandera TOV0 (desbordamiento del temporizador). Esta bandera del
temporizador puede ser monitoreada.

Pasos para programar el Timer 0 en el modo normal


Para generar un retardo de tiempo utilizando Timer 0 en el modo Normal, los pasos a
seguir son:
1. Cargar el registro TCNT0 con el valor de recuento inicial.
2. Cargar el valor en el registro TCCR0, indicando que el modo de (8-bit o 16 bit-) se va
a utilizar y la opción de pre-escalador. Cuando seleccione la fuente de reloj, el
temporizador / contador empieza a contar, y cada pulso hace que el contenido del
registro temporizador/contador se incremente en 1.
3. Mantener el monitoreo de la bandera de desbordamiento del temporizador (TOV0)
para ver si está activo en uno. Salga del bucle cuando TOV0 llegue a ser uno.
4. Detener el temporizador para desconectarlo de la fuente de reloj, utilizando el
registro TCCR0.
9. Desactive la bandera TOV0 para la siguiente ronda.
10. Vuelva al paso 1 para cargar TCNT0 nuevo.

Ejemplo #include "avr/io.h"


Escriba un programa en C para void retardo ( );
alternar el bit 4 de PORTB de forma int main ( ) {
continua con algún retraso. Utilice DDRB = 0xFF; //PORTB como salida
Timer 0, el modo Normal, y sin while (1) {
opciones de preescalar para generar PORTB|= _BV(PB4);
el retraso. retardo ();
PORTB &= ~_BV(PB4);
retardo ();
}//repite por siempre
}
void retardo ( ) {
TCNT0 = 0xF2; //carga de TCNT0
TCCR0 = 0x01; //Timer 0, Normal mode, no
preescalar
while ((TIFR&0x1)==0); //espera desbordamiento
TCCR0 = 0;
TIFR = 0x1; //Borra el indicador
}
En el programa anterior note los siguientes pasos:
1. El valor 0xF2 se carga en TCNT0.
2. TCCR0 se carga y el Timer 0 se inicia.
3. Timer 0 cuenta hacia arriba con cada paso de reloj, que es proporcionado por el
oscilador del cristal. A medida que el temporizador cuenta hacia arriba, pasa por los
estados de 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, y así sucesivamente
hasta que alcanza 0xFF. Un pulso de reloj más lleva el contador a 0x00, colocando la
bandera del Timer 0 (TOV0 = 1).
4. El Timer 0 se detiene utilizando a TCCR0.
5. La bandera TOV0 se borra.

Para calcular el retardo de tiempo exacto y la onda cuadrada de frecuencia generada


en el pin PB4, necesitamos saber la frecuencia XTAL.

En el Ejemplo, calcular el retardo de tiempo generado por el temporizador.


Supongamos que XTAL = 8MHz.
Solución:
Tenemos 8 MHz como la frecuencia del temporizador. Como resultado, cada pulso
tiene un periodo de T = 1/8 MHz = 0.125 uS. En otras palabras, El Timer 0 cuenta cada
0.125uS y el resultado del retardo = número de recuentos x 0.125uS.
El número de conteos hasta el máximo es de 0xFF(255) – 0xF2(242) = 0xD(13 decimal).
Sin embargo se le agrega uno a 13 debido a que un pulso de reloj extra es necesario
cuando se pasa de 0xFF a 0x00 y la bandera TOV0 se activa. Esto da 14 x 0.125uS =
1.75uS para cada mitad del pulso.

Búsqueda de valores que se cargan en el registro contador del temporizador


Suponiendo que se conoce la cantidad de retardo del temporizador que necesitamos,
la pregunta es cómo encontrar los valores necesarios para el registro TCNT0. Para
calcular el valor que se carga en el registro TCNT0, podemos utilizar los siguientes
pasos:
1. Calcular el periodo pulso de reloj del temporizador mediante la siguiente fórmula:
Treloj = 1/Ftimer
donde Ftimer es la frecuencia utilizada para el temporizador. Por ejemplo, en modo no
preescalar, Ftimer = Foscilador: Treloj indica el período en el que ocurren los
incrementos del temporizador.
2. Dividir el tiempo de retardo deseado por Treloj Esto dice cuantos pulsos de reloj
necesitamos.
3. Realizar 256 - n, donde n es el valor decimal que nos dieron en el paso 2.
4. Convertir el resultado del Paso 3 en hexadecimal, donde xx es el valor hexadecimal
inicial que se carga en el registro del temporizador.
5. Establecer TCNT0 = xx.
Mira el siguiente ejemplo, donde se utiliza una frecuencia de cristal de 8 MHz para el
sistema AVR.
Suponiendo que XTAL = 8 MHz, escribir un programa para generar una onda cuadrada
con un periodo de 12.5uS en el pin 4 de PORTB.
Solución:
Para una onda cuadrada con T = 12.5 uS debemos tener un tiempo de demora de
6.25uS, debido a que el XTAL = 8 MHz, el contador cuenta cada 0.125uS. Esto significa
que tenemos que 6.25 uS x 0.125 uS = 50 pulsos de reloj. 256-50 = 206 = 0xCE. Por lo
tanto, tenemos TCNT0 = 0xCE.

Suponiendo que XTAL = 8 MHz, modificar el programa anterior para generar una onda
cuadrada de frecuencia de 16 kHz en el pin 4 de PORTB.
Solución:
Mira los siguientes pasos.
(a) T = 1 / f = 1/16 kHz = 62.5 uS es el periodo de la onda cuadrada.
(b) 1/2 del periodo para las partes alta y baja del pulso es de 31.25 uS.
(e) 31.25 uS / 0.125 uS=250 y 256 - 250 = 6, que en hexadecimal es 0x06.
(d) TCNT0 = 0x06.

Uso del Preescalar y como generar un retardo de tiempo grande

Como se ha visto en los ejemplos hasta el momento, el tamaño del retardo de tiempo
depende de dos factores, (a) la frecuencia del cristal, y (b) registro del temporizador de
8-bits. Ambos factores están fuera del control del programador.

El retraso más grande de tiempo se consigue haciendo TCNT0 igual a cero. Pero ¿ es
eso suficiente?. Podemos utilizar la opción de pre-escalador en el registro TCCR0 para
aumentar el retraso al reducir el periodo. La opción preescalar de TCCR0 nos permite
dividir el reloj por un factor de 8 a 1024 como se muestra en la Figura anterior. El
preescalar del temporizador/contador 0 se muestra en esa figura.
Como hemos visto hasta ahora, sin preescalar habilitado, la frecuencia del cristal
oscilador se alimenta directamente al Timer 0, Si nosotros habilitamos el bit preescalar
en el registro TCCR0, sin embargo, podemos dividir el pulso antes de que se alimente al
Timer 0 . Los 3 bits más bajos del registro TCCR0 dan las opciones del número por el
que se puede dividir. Como se muestra en la Figura, este número puede ser de 8,
64.256, y 1024. Observe que el número más bajo es de 8 y el número más alto es 1024.

Ejemplo

Encontrar la frecuencia de reloj del temporizador y el período de varios sistemas AVR


basados en las frecuencias de cristal siguientes.
Supongamos que se utiliza un preescalar de 1: 64
(a) 8 MHz (b) 16 MHz (c) 10 MHz

(a) 1/64 x 8 MHz= 125 kHz debido a 1:64 preesealar y T = 1/125 kHz = 8 uS
(b) 1/64 x 16 MHz = 250 kHz debido a preescalar y T = 1/250 kHz = 4 uS
(e) 1/64 x 10 = 156.2 MHz kHz debido a preesealar y T = 1/156 kHz = 6.4 uS

Ejemplo

Encuentra el valor de TCCR0 si queremos programar Timer 0 en modo Normal con un


preescalar de 64 con el reloj interno de la fuente de reloj.
Solución:
Tenemos TCCR0 = 0000 0011; fuente de reloj XTAL. Preescalar de 64.

Ejemplo #include "avr/io.h"


Escribe programa para void retardo ( );
cambiar sólo el bit 4 de int main ( ) {
PORTB continuamente cada DDRB = 0xFF; //PORTB como salida
70 uS. Utilice Timer 0, el while (1) {
modo Normal, y preescalar retardo ();
1:8 para crear el retardo. PORTB ^= _BV(PB4);
Supongamos XTAL = 8 MHz. }//repite por siempre
Solución: }
XTAL = 8MHz -> Tiempo de void retardo ( ) {
ciclo maquina= 1/8 MHz TCNT0 = 186; //carga de TCNT0
preescalador = 1:8 -> Treloj TCCR0 = 0x02; //Timer 0, Normal mode, 1:8 preescalar
= 8 x 1/8 MHz = 1 uS while ((TIFR&(1<<TOV0))==0);//espera desbordamiento
70 us / 1uS = 70 pulsos -> 1 TCCR0 = 0;
+ 0xFF -70 = 0x100 - 0x46 = TIFR = 0x1; //Borra el indicador
0xBA = 186 }
Ejemplo
Supongamos XTAL = 8 MHz.
(a) Determinar el período de reloj alimentado al Timer 0 si una opción de pre-
escalador de 1024 es elegido.
(b) Demostrar cual es el mayor retardo tiempo que podamos utilizar con esta opción
preescalar y Timer 0.
Solución:
(a) 8 x MHz 1/1024 = 7812.5 Hz debido a 1:1024 preescalar y T = 117812.5 Hz = 128
uS = 0.128 ms
(b) Para obtener el mayor retraso, hacemos TCNT0 cero. Haciendo TCNT0= cero
significa que la cuenta del temporizador va de 00 a 0xFF, y después volverá a
activarse la bandera TOV0. Como resultado de ello, pasa por un total de 256 estados.
Por lo tanto, tenemos un retardo = (256 - 0) x 128 = 32.768 uS = 0.032768 segundos.

Programación Temporizador 2

El Timer2 es un temporizador de 8-bit. Por lo tanto, funciona de la misma manera


que Timer 0. Pero hay dos diferencias entre Timer 0 y Timer 2:
1. El Timer2 se puede utilizar como un contador de tiempo real. Para ello, se debe
conectar un cristal de 32.768 kHz a los pines del AVR TOSC1 y TOSC2 y establecer el
bit AS2. Para obtener más información sobre esta función, consulte la hoja de datos
AVR.
2. En Timer 0, cuando CS02-CS00 tienen valores de 110 o 111, Timer 0 cuenta los
eventos externos. Pero en Timer2, el multip1exor selecciona entre las diferentes
escalas del reloj. En otras palabras, los mismos valores de los bits CS puede tener
diferentes significados para Timer 0 y Timer2.

Registro TCCR2 (Timer/Counter Control Register)

FOC2 : es D7 Force compare match: Esto es de sólo escritura, puede utilizarse mientras
se genera una onda. Escribirle un 1 causa que al generar la onda actué como si un
match de comparación se ha producido.

WGM20, WGM21
D6 D3 bits de selección del modo del Timer2
0 0 normal
0 1 CTC (Borrar contador en comparación Match)
1 0 PWM, fase correcta
1 1 PWM rápido

COM21:COM20 DS D4 Comparar Modo de salida: Estos bits controlan el generador de


forma de onda.
CS22: CS20
D2 DI D0 Selector fuente de reloj del Timer 2
0 0 0 Ninguna fuente (Timer / Contador parado)
0 0 1 CLK (Sin preescalar)
0 1 0 CLK / 8
0 1 1 CLK 1/32
1 0 0 CLK / 64
1 0 1 CLK / 128
1 1 0 CLK / 256
1 1 1 CLK / 1024

Ejemplo
Encuentra el valor de TCCR2 si queremos programar Timer2 en modo normal con un
preescalar de 64, utiliza una base interna de la fuente de reloj.
Solución:
En la figura tenemos TCCR2 = 0000 0100; fuente de reloj XTAL. preescalar de 64 .

ASSR (Asynchronous Status Regíster)

AS2 Cuando es cero, el Timer2 obtiene el reloj desde clkI/o. Cuando se establece a
uno, el Timer2 actúa como RTC

Ejemplo #include "avr/io.h"


Con el uso de un preescalar de 64, void retardo ( ) {
escribir un programa para generar un TCNT2 = -240; //carga de TCNT2
retardo de 1920 uS. Supongamos XTAL TCCR2 = 0x04; //Timer 2, Normal mode, reloj
= 8 MHz. Interno,preescalar 64
Solución: while ((TIFR&(1<<TOV2))==0);//espera
Reloj del Timer= 8 MHz/64 = 125 KHz desbordamiento
Periodo del temporizador = 1/125 kHz TCCR2 = 0;
= 8 uS TIFR |=(1<<TVO2); //Borra el indicador
Valor del temporizador= 1920uS/8uS= }
240
Programación del modo Clear on compare match (CTC) de Timer 2

Examinando la figura anterior, una vez más, vemos el registro OCR2. El registro OCR2
se utiliza con el modo CTC. Como con el modo normal, en el modo CTC, el
temporizador se incrementa con un pulso. Pero cuenta hacia arriba hasta que el
contenido del registro TCNT2 se hace igual al contenido de OCR (se produce un
match de comparacion), y luego, el temporizador es borrado (0x00) y la bandera
OCF2 se establece a uno cuando se produce el siguiente pulso. La bandera OCF2 se
encuentra en el registro TIFR.
Ejemplo
En el siguiente programa, estamos creando una onda cuadrada con ciclo de trabajo
de 50% (con partes iguales de alta y baja) en el bit 4 de PORTB. Timer 2 se utiliza para
generar el tiempo de retardo. Analizar el programa
#include "avr/io.h"
void retardo ( );
int main ( ) {
DDRB = 0xFF; //PORTB como salida
while (1) {
retardo ();
PORTB ^= _BV(PB4);
}//repite por siempre
}
void retardo ( ) {
TCNT2 = 0; //carga de TCNT2
OCR2 = 0x9;
TCCR2 = 0x9; //Timer 2, CTC mode,reloj interno
while ((TIFR&(1<<OCF2))==0);//espera desbordamiento
TCCR2 = 0;
TIFR |=(1<<OCF2); //Borra el indicador
}
Solución:
El programa de arriba cuenta de los siguientes pasos:
1. Se carga 0x9 en OCR2.
2. Se carga TCCR2 y el Timer 2 inicia su conteo.
3. El Timer 2 cuenta hacia arriba con el paso de cada pulso de reloj, que es
proporcionado por el oscilador de cristal. A medida que el temporizador cuenta hacia
arriba, pasa por los estados de 00, 01, 02, 03, y así sucesivamente hasta que alcanzar
0x9. Un pulso más que lo lleva a cero, el Timer 2 coloca a uno la bandera de match de
comparación (OCF2 = 1).
4. El Timer 2 se detiene.
5. La bandera OCF2 se borra.

OCF2=0 OCF2=0 OCF2=0 OCF2=0 OCF2=1


TOV2=0 TOV2=0 TOV2=0 TOV2=0 TOCV=0
Programación del temporizador 1

El Timer 1 es un contador de 16 bits y tiene un montón de posibilidades. A


continuación, discutimos el Timer 1 y sus capacidades.

Puesto que el temporizador 1 es un temporizador de


16-bit su registro de 16-bit se divide en dos bytes. Estos
se conocen como TCNT1L (Timer 1 byte bajo) y TCNT 1
H (Temporizador 1 byte alto). Este Temporizador
también tiene dos registros de control llamados
TCCR1A (registro de control del temporizador/contador
1) y TCCR1B. El bit de bandera TOV1 (desbordamiento
del temporizador) pasa a ALTO cuando ocurre un
desbordamiento. Temporizador 1 también tiene las
opciones presca1er de 1:1, 1: 8, 1: 64, 1:256, y 1:1024.
Hay dos registros de OCR en Timer1: OCR1A y OCR1B.
hay dos banderas separadas para cada uno de los
registros de OCR, que actúan independientes uno del
otro. Siempre que TCNT1 sea igual a OCR1A, la bandera
OCF se establecerá a uno en el siguiente pulso de reloj. Al igual TCNT OCR1B, la
bandera OCF1B se establecerá a uno en el siguiente pulso de reloj. Como el Timer 1
es un temporizador de 16-bits, los registros OCR son de 16-bits están compuestos de
dos registros de 8-bits. Por ejemplo, OCR1A es de OCR1AH (byte alto de OCR1A) y
OCR1AL (byte bajo de OCR1A).

TIFR (Timer/Counter Interrupt Flag Register)

El registro TIFR contiene las banderas TOV1, OCF1A y OCF1B, ver Figura .

TOV0 D0 bit de bandera de desbordamiento del Timer 0


0 = Timer 0 no se ha desbordado.
1 = Timer 0 se ha desbordado (pasando de 0xFF a 0x00).
OCF0 D1 bit de bandera de salida de comparación del Timer 0
0 = un match de comparación no ha tenido lugar.
1 = un match de comparación ha ocurrido.
TOV1 D2 bit de bandera de desbordamiento del Timer 1
OCF1B D3 bit de bandera de salida de comparación B del Timer 1
OCF1A D4 bit de bandera de salida de comparación A del Timer 1
ICF1 D5 bit de bandera Captura de entrada
TOV2 D6 bit de bandera de desbordamiento del Timer 2
OCF2 D7 bit de bandera de salida de comparación del Timer 2
Registro TCCRIB (Timer 1 Control)

WGM13: 10

El WGM13, WGMI2, WGM11, y los bits WGM10 definen el modo del Timer 1, como
se muestra en la figura de arriba. El Timer 1 dispone de 16 modos diferentes. Uno de
ellos (modo 13) se reserva (no implementado). Tratremos modo normal y el modo
CTC.
Modos de operación del Timer 1
El modo Normal (WGM13:10 = 0000)

En este modo, el temporizador cuenta hacia arriba hasta que alcanza 0xFFFF (que es
el valor máximo) y luego pasa por encima de 0xFFFF a 0000. Cuando esto ocurre, la
bandera TOV1 se establecerá a uno.

TOV en modo Normal y PWM rápido

Modo CTC (WGM13: 10 = 0100)

En este modo, el temporizador cuenta hacia arriba hasta que el contenido del
registro TCNT1 se hace igual al contenido de OCR1A (se produce un match de
comparación), a continuación, el temporizador se borra cuando se produce el
siguiente pulso de reloj. La bandera OCF1 se establece a uno como resultado de
coincidir la comparación.

Ejemplo

Encuentre los valores para TCCR1A y TCCR1B si queremos programar el Timer 1 en el


modo (Normal), sin preescalar. Utilice un oscilador de cristal para la fuente de reloj.
Solución:
TCCR1A = 0000 0000 WGM11 = 0, WGM10= 0
TCCR1B = 0000 0001 WGM13 = 0, WGM12 = 0, reloj con oscilador, no prescaler

Ejemplo
Escriba un programa C para alternar el bit 4 de PORTB continuamente cada 2 ms.
Utilice Timer 1, el modo Normal, y no preescalar para crear el retardo. Supongamos
XTAL = 8 MHz.
Solución:
XTAL = 8 MHz -> Tciclo maquina = 1/8 MHz = 0.125 uS
preescalador = 1:1 TClock  = 0.125 uS
2 mS/0.125uS = 16.000 = 0x3E80 pulsos
1 + 0xFFFF - 0x3E80 = 0xC180
#include "avr/io.h"
void retardo ( );
int main ( ) {
DDRB = 0xFF; //PORTB como salida
while (1) {
retardo ();
PORTB ^= _BV(PB4);
}//repite por siempre
}
void retardo ( ) {
TCNT1H = 0xC1;
TCNT1L = 0x80; //carga de TCNT2
TCCR1A = 0; //Modo Normal
TCCR1B = 0x1; //Timer 1, modo normal,Sin preescalar
while ((TIFR&(1<<TOV1))==0);//espera desbordamiento
TCCR1B = 0;
TIFR |=(1<<TOV1); //Borra el indicador
}

Generar un retardo grande usando un preescalar

Como se ha visto en los ejemplos hasta el momento, el tamaño del retardo de tiempo
depende de dos factores: (a) la frecuencia del cristal, y (b) el registro del
temporizador de 16-bit. Ambos de estos factores están fuera del control del
programador. Podemos utilizar la opción de pre-escalador en registro TCCR1B para
aumentar el retraso o tamaño del periodo. La opción preescalar de TCCR1B nos
permite dividir el reloj en un factor de 8 a 1024.

Como hemos visto hasta ahora, sin preescalar habilitado, la frecuencia del oscilado se
alimenta directamente al Timer 1. Si nosotros habilitamos el bit preescalar en el
registro TCCR1B, entonces podemos dividir el reloj antes de que se alimente al Timer
1. Los 3 bits menos significativos del registro TCCR1B dará el número de opciones en
que podemos dividir el reloj antes de que se alimente al temporizador. Como se
muestra en la figura anterior, este número puede ser 8, 64, 256, o 1024. Tenga en
cuenta que el número más bajo es de 8, y el número más alto es 1024.
Ejemplo
Escribe programa para cambiar sólo el bit 4 de PORTB continuamente cada segundo.
Utilice el modo Timer 1, modo Normal y preescalar 1:256 para crear el retardo.
Supongamos XTAL = 8 MHz.
Solución:
XTAL = 8 MHz -> Tciclomaquina = 1/8 MHz = 0.125 uS = Treloj
Preescalador = 1:256 -> Treloj = 256 x 0.125 = 32uS
1S/32uS = 31,250 = 0x7A12 pulsos de relojes -> = 1 + 0xFFFF - 0x7A12 = 0x85EE

#include "avr/io.h"
void retardo ( );
int main ( ) {
DDRB = 0xFF; //PORTB como salida
while (1) {
retardo ();
PORTB ^= _BV(PB4);
}//repite por siempre
}
void retardo ( ) {
TCNT1H = 0x85;
TCNT1L = 0xEE; //carga de TCNT2
TCCR1A = 0; //Modo Normal
TCCR1B = 0x4; //Timer 1, modo normal,1:256 preescalar
while ((TIFR&(1<<TOV1))==0);//espera desbordamiento
TCCR1B = 0;
TIFR |=(1<<TOV1); //Borra el indicador
}

También podría gustarte