Capitulo 4 temporizador/ temporizador/contador contador 4.0 Introducción. Los temporizadores/contadores son probablemente los periféricos complejos de mayor uso en los microcontroladores. Los temporizadores/contadores son altamente versátiles, se pueden emplear para medir periodos de tiempo, para determinar el ancho de un pulso, para medir una velocidad, para medir frecuencia, o para proporcionar señales de salida. Ejemplos de aplicaciones pueden incluir la medición de las revoluciones por minuto de un motor de automóvil, el periodo exacto de un tiempo especifico, tal como el tiempo de trayectoria de una bala, producir tonos para crear música o para producir la chispa de una bujía de un sistema de ignición, o proveer el ancho especifico de un pulso u obtener frecuencias especificas para el control de la velocidad de un motor. En este capítulo se estudian los temporizadores/contadores del AVR. No
obstante
el
empleo
de
dos
modos
distintos,
temporizadores
y
contadores,
temporizadores/contadores son simples contadores binarios ascendentes. Cuando se emplea el temporizador, el contador binario estará contando periodos de tiempo aplicados a sus entradas, y en el modo contador, estará contando los eve ntos o pulsos de alguna naturaleza. Por ejemplo, si el contador binario tiene pulsos de 1 milisegundo en su entrada, el periodo de tiempo puede ser medido iniciando el contador al inicio de un evento y parando el contador al final del evento. La cuenta final en el contador será e l número de milisegundos que ha transcurrido durante el evento. Cuando el temporizador/contador es empleado como un contador, los eventos a ser contados son aplicados a la entrada del contador binario, el número de eventos es contado. Por ejemplo, el contador puede ser empleado para contar el número de latas de sopa en una línea de llenado de una fábrica de sopas, aplicando un pulso a la entrada del contador por cada lata de sopa. En cualquier momento, el contador podrá ser leído para dete rminar cuántas latas de sopa han pasado en la línea de llenado. Los microcontroladores AVR poseen dos temporizadores/contadores de 8 bits y uno de 16 bits. En uno y otro caso, lo importante para el programa es conocer cuando se alcanza la máxima cuenta y los desbordamientos correspondientes. En el caso de un contador de 8 bits, la cuenta máxima que puede alcanzar es 255, en cuyo caso la siguiente cuanta puede causar un desbordamiento y llevar al contador a 0. En el caso del contador de 16 bits, lo mismo ocurre para 65,535.El evento de desbordamiento es muy importante para que el programa lea exactamente los resultados del temporizador/contador. De hecho, los desbordamientos son tan importantes que se proporciona la interrupción cuando ocurre está en el temporizador/contador.
4.1 Temporizador y contador. Un temporizador o
timer ,
es un reloj especializado, que regularmente se ocupa para controlar la
secuencia de un evento o proceso. Un contador es en términos generales, un dispositivo que almacena el número de veces que un evento se lleva a cabo. Un temporizador en un microcontrolador AVR, es un registro que almacena el número de pulsos de reloj que ocupa como base de tiempo y que, al llegar a un valor de sobre flujo, regularmente genera una interrupción. Por otro lado el contador del AVR es un registro que se compara constantemente contra otro registro y que al igualarse el valor de ambos regularmente se ge nera una interrupción. El AVR atmega8 posee tres temporizadores, dos de ellos, timer 0 y timer 2, son de 8 bits, mientras que uno de ellos, el timer 1, es de 16 bits.
4.2 Uso de timer 1. 4.2.1 Registro de cuenta TCNT1.
Este es el registro encargado de llevar la cuenta de los pulsos de reloj.
4.2.2 Registro de control A, TCCR1A.
Bit 7:6 - COM1A1:0 Modo de salida de c omparación para canal A.
Bit 5:4 - COM1B1:0 Modo de salida de comparación para canal B.
Bit 3 – Forzamiento de salida de comparación, canal A.
Bit2 – Forzamiento de salida de comparación, canal B.
Bit 1:0 – WGM11:10 Modo de generación de formas de onda.
Los bits COM1A1:0 y COM1B1:0 controlan el estado de las terminales del microcontrolador – OC1A y OC1B respectivamente- . Si una o ambas terminales de comparación COM1A1:0 son puestas a uno, la salida OC1A anula la funcionalidad normal del puerto I/O conectando a la función OC1A, lo mismo ocurre si ambos bits COM1B1:0, la salida OC1B anula la funcionalidad del puerto
I/O conectando a la función OC1B. Hay que notar que el registro DDR correspondiente a OC1A y OC1B debe ser puesto a uno para habilitar la salida. Cuando los bits OC1A o OC1B son conectados a la terminal, la función de los bits COM1x1:0 es independiente de los bits WGM13:0. La siguiente tabla muestra los bits COM1x1:0 cuando se esta trabajando el timer en modo no PWM.
COM1A1/COM1B1 0
COM1A0/COM1B0 0
0 1
1 0
1
1
Descripción Operación normal del puerto, OC1A/OC1B desconectada Conmutación OC1A/OC1B encendida en comparación En cero OC1A/OC1B en comparación (poner salida en nivel bajo) Poner en uno OC1A/OC1B en comparación (poner salida en nivel alto
4.2.3 Registro de control B, TCCR1B.
Bit 7 – INC1 Cancela de ruido de entrada de captura.
Bit 6 – ICES1 Selección de flanco de activación para entrada de captura.
Bit 5 – Reservado.
Bit 4:3 – WGM13:12 Modo de generación de formas de onda.
Bit
2:3
–
CS12:10 Fuente de reloj para el temporizador 1. Estos últimos tres bits,
configuran la fuente de reloj que utiliza el temporizador 1, de acuerdo a la siguiente tabla.
CS12 0 0 0 0 1 1 1 1
CS11 0 0 1 1 0 0 1 1
CS10 0 1 0 1 0 1 0 1
Descripción Sin fuente de reloj (timer/counter detenido) Sistema de reloj, CK (sin pre escalador) Sistema de reloj, CK/8 Sistema de reloj, CK/64 Sistema de reloj, CK/256 Sistema de reloj, CK/1024 Fuente externa en la terminal 1, flanco de subida Fuente externa en la terminal 1, flanco de bajada
Tabla 4.1 Bits de selección de fuente de reloj.
4.2.4 Registro de salida de comparación 1 A, OCR1A.
4.2.5 Registro de salida de comparación 1B, OCR1B.
Los registros OCR1A y OCR1B son constantemente comparados contra el valor del registro TCNT1, una igualdad entre estos registros se puede utilizar para generar una interrupción.
4.2.6 Registro de entrada de captura 1, ICR1.
Este registro es actualizado cada vez que ocurre un evento e pin de captura ICP1.
4.2.7 Registro de mascaras de interrupción del timer/counter, TIMSK.
Bit 5 – TICIE1 Habilitación de interrupción por entrada de captura 1.
Bit 4 – OCIE1A Habilitación de interrupción por salida de comparación 1, c anal A.
Bit 3 – OCIE1B Habilitación de interrupción por salida de comparación 1, c anal B.
Bit 2 – TOIE1 Habilitación de interrupción por desbordamiento del timer 1.
4.2.8 Registro de banderas de interrupciones del timer/counter, TIFR.
Bit 5 – ICF1 Bandera de entrada de captura 1.
Bit 4 – OCF1A Bandera de salida de comparación 1, canal A.
Bit 3 - OCF1B Bandera de salida de comparación 1, canal B.
Bit 2 – TOV1 Bandera de desbordamiento del timer 1.
4.3 Práctica del timer 1. 4.3.1 Objetivo. Comprender el funcionamiento de los timers del AVR atmega8 así como los registros que intervienen en su configuración.
4.3.2 Material. El material necesario para realizar esta práct ica es el siguiente:
Cantidad 1 2 1 1 1 4 4 1 1 1
cantidad Cristal de cuarzo de 4 MHZ. Capacitores de 22 pf Interruptor tipo push button Resistor de 10KΩ Resistor de 1KΩ Resistores de 220Ω
Diodos emisores de luz LEDs Programador de microcontroladores Microcontrolador atmega8 Fuente de alimentación de 5 volts Pinzas, protoboard, cable telefónico
4.3.3 Desarrollo. Para realizar esta práctica se emplea el siguiente circuito.
Xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
4.3.4 Código. //____________Inicio del programa #include
#include #include #define step1 8 #define step2 4 #define step3 2 #define step4 1
static int8_t step;
//declaración de una variable entera estática de 8 bits
void config_io(void) {
//declaración de una función de configuración IO
DDRC =0x0F;
//configuración de puertos de IO
TCCR1B = _BV (CS11);
//pre escala para el timer 1 (clk/8)
TIMSK = _BV (TOIE1);
//activar interrupción por sobre flujo del timer 1
sei();
//activación de interrupciones globales
} INTERRUPT (SIG_OVERFLOW1){ step++; switch (step){ case (1):
//interrupción por sobre flujo timer 1
PORTC=step4; break; case (2): PORTC=step3; break; case (3): PORTC=step2; break; case (4): PORTC=step1; step=0; break; } } void main (void){ config_io ();
//función principal //llamada a función config_io
while (1); } //_____________fin de programa
4.4 Uso del counter 0. A continuación veremos cómo configurar el counter 0 del AVR. Este timer/counter es de 8 bits. Su configuración es análoga al timer 1, y que los registros para su configuración son similares.
4.4.1 Registro de control del timer 0, TCCR0.
CS02 0 0 0 0 1 1 1 1
Bit 2:0 – CS02:CS00 fuente de reloj para el timer/counter0.
CS01 0 0 1 1 0 0 1 1
CS00 0 1 0 1 0 1 0 1
Descripción Sin fuente de reloj (timer/counter detenido) Sistema de reloj, CK (sin pre escalador) Sistema de reloj, CK/8 Sistema de reloj, CK/64 Sistema de reloj, CK/256 Sistema de reloj, CK/1024 Fuente externa en la terminal 0, flanco de subida Fuente externa en la terminal 0, flanco de bajada
4.4.2 Registro de cuenta 0, TCNT0.
4.4.3 Registro de mascara de interrupciones de timer/counter, TIMSK y registro de banderas de interrupción del timer/counter, TIFR.
Son los mismos registros que se utilizaron para configurar el timer 1, la diferencia radica en seleccionar los bits adecuados para el timer 0 .
4.5 Práctica del counter 0 y timer 1. 4.5.1 Objetivo. Comprender el funcionamiento de los contadores del AVR atmega8 así como los registros que interviene en su configuración.
4.5.2 Desarrollo. Cantidad 1
Descripción Push button
1 2 5 4 1 1 1
Capacitor cerámico de 0.22 µf Resistores de 10 kΩ Resistores de 220Ω
LEDs Programador de microcontroladores AVR Microcontrolador atmega8 Protoboard, pinzas, cable telefónico, fuente de alimentación
4.5.3 Desarrollo. Arma el circuito de la siguiente figura.
Xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
4.5.4 Código. //____________Inicio del programa #include #include #include #define step1 8 #define step2 4 #define step3 2 #define step4 1
static int8_t step;
//declaración de una variable entera estática de 8 bits
void config_io(void) {
//declaración de una función de configuración IO
DDRC =0x0F;
//configuración de puertos de IO
DDRD=0b11101111;
//PD2 como entrada
TIMSK = _BV (TOIE0);
//activar interrupción por sobre flujo del timer 0
TCCR0=_BV (CS02) |_BV (CS01);
// fuente externa, flanco de bajada
TCNT0=251;
//cargar el 251 al registro de cuenta del timer/counter0
sei();
//activación de interrupciones globales
} void config_timer1 (void){ TCCR1B=_BV (CS11);
//pre escala para el timer 1 (clk/8)
TIMSK=_BV (TOIE1);
//activar interrupción por sobre flujo del timer 1
INTERRUPT (SIG_OVERFLOW1) { step++; Switch (step) { case (1): PORTC=step4; break; case (2): PORTC=step3; break; case (3): PORTC=step2; break; case (4): PORTC=step1; step=0; break; } } INTERRUPT (SIG_OVERFLOW0) { Config_timer1 ();
//interrupción por sobre flujo timer 1
} void main (void){ config_io (); While (1); } //_____________fin de programa
//función principal //llamada a función config_io