Manejo de Temporizadores AVR

17
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. CAPITULO 4 TEMPORIZADORES DE AVRs PROGRAMACION EN C

Transcript of Manejo de Temporizadores AVR

Page 1: Manejo de Temporizadores AVR

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.

CAPITULO 4

TEMPORIZADORES

DE AVRs

PROGRAMACION EN

C

Page 2: Manejo de Temporizadores AVR

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.

Page 3: Manejo de Temporizadores AVR

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.

Page 4: Manejo de Temporizadores AVR

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.

Page 5: Manejo de Temporizadores AVR

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.

Page 6: Manejo de Temporizadores AVR

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

Escriba un programa en C para alternar el bit 4 de PORTB de forma continua con algún retraso. Utilice Timer 0, el modo Normal, y sin opciones de preescalar para generar el retraso.

#include "avr/io.h"

void retardo ( );

int main ( ) {

DDRB = 0xFF; //PORTB como salida

while (1) {

PORTB|= _BV(PB4);

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

}

Page 7: Manejo de Temporizadores AVR

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.

Page 8: Manejo de Temporizadores 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.

Page 9: Manejo de Temporizadores AVR

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

Escribe programa para cambiar sólo el bit 4 de PORTB continuamente cada 70 uS. Utilice Timer 0, el modo Normal, y preescalar 1:8 para crear el retardo. Supongamos XTAL = 8 MHz. Solución:

XTAL = 8MHz -> Tiempo de ciclo maquina= 1/8 MHz preescalador = 1:8 -> Treloj = 8 x 1/8 MHz = 1 uS 70 us / 1uS = 70 pulsos -> 1 + 0xFF -70 = 0x100 - 0x46 = 0xBA = 186

#include "avr/io.h" void retardo ( ); int main ( ) { DDRB = 0xFF; //PORTB como salida while (1) { retardo (); PORTB ^= _BV(PB4); }//repite por siempre } void retardo ( ) { TCNT0 = 186; //carga de TCNT0 TCCR0 = 0x02; //Timer 0, Normal mode, 1:8 preescalar while ((TIFR&(1<<TOV0))==0);//espera desbordamiento TCCR0 = 0; TIFR = 0x1; //Borra el indicador }

Page 10: Manejo de Temporizadores AVR

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.

Page 11: Manejo de Temporizadores AVR

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

Con el uso de un preescalar de 64, escribir un programa para generar un retardo de 1920 uS. Supongamos XTAL = 8 MHz. Solución: Reloj del Timer= 8 MHz/64 = 125 KHz Periodo del temporizador = 1/125 kHz = 8 uS Valor del temporizador= 1920uS/8uS= 240

#include "avr/io.h"

void retardo ( ) {

TCNT2 = -240; //carga de TCNT2

TCCR2 = 0x04; //Timer 2, Normal mode, reloj

Interno,preescalar 64

while ((TIFR&(1<<TOV2))==0);//espera

desbordamiento

TCCR2 = 0;

TIFR |=(1<<TVO2); //Borra el indicador

}

Page 12: Manejo de Temporizadores AVR

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

Page 13: Manejo de Temporizadores AVR

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

Page 14: Manejo de Temporizadores AVR

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.

Page 15: Manejo de Temporizadores AVR

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

Page 16: Manejo de Temporizadores AVR

#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.

Page 17: Manejo de Temporizadores AVR

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

}