Está en la página 1de 5

PROGRAMACIN DEL TEMPORIZADOR COMO CONTADOR DE EVENTOS

En la seccin anterior, hemos utilizado los temporizadores del AVR para generar retardos de tiempo. El temporizador del AVR tambin puede ser usado para contar, detectar y medir el tiempo de los acontecimientos que suceden fuera del AVR Cuando el temporizador se utiliza como un contador de tiempo, la frecuencia del cristal del AVR se usa como fuente de reloj. Cuando se utiliza como un contador, sin embargo, se trata de una salida de impulsos del lado del AVR que incrementa el registro TCNTx. Observe que, en el modo de contador, los registros TCCR, OCR0, y TCNT son los mismos que para el temporizador discutido en la seccin anterior.

Los bits CS00, CS01, and CS02 en el registr0 TCCR0


Recuerde que en la seccin anterior que los bits de CS (clock selector) en el registro TCCR0 sirven para seleccionar la fuente de para el temporizador. If CS02:CS00 est entre 1 y 5, el temporizador recibe impulsos del oscilador de cristal. En contraste, cuando CS02:CS00 es 6 o 7, el temporizador se utiliza como un contador de impulsos y obtiene los pulsos desde una fuente externa al chip AVR. Vea la Figura. Por lo tanto, cuando CS02:CS00 es 6 o 7, el registro contador TCNT0 incrementa su cuenta cuando los pulsos se alimentan por el pin T0 (entrada externa del reloj del Timer / Contador 0).

Ejemplo Encuentra el valor de TCCR0 si queremos programar Timer 0 como contador en modo Normal. Utiliza un reloj externo para la fuente de reloj y el incremento es con el flanco positivo. Solucin: TCCR0 = 0000 0111 Normal; fuente de reloj externa, no prescaler T0 es un pin de funcin alternativa de PORTB bit 0.En el caso del Timer 0, cuando CS02:CS00 es 6 o 7, el pin T0 proporciona el pulso de reloj y el contador cuenta hacia

arriba despus de cada pulso de reloj procedente de pin, para el Timer 1, cuando CS12: 10 es 6 o 7, el pulso de reloj viene por el pin T1 (entrada de reloj externa del Timer / Contador 1) hace que el contador TCNT1 incremente. Cuando CS12:CS10 es 6, el contador cuenta hacia arriba en el flanco negativo. Cuando CS12:CS10 es 7, el contador cuenta hacia arriba en el flanco positivo. T1 es un pin de funcin alternativa de PORTB bit 1. Ejemplo Suponiendo que un pulso de reloj de 1 Hz se alimenta en el pin T0 (PD4), escriba un programa para que Contador 0 cuente en el modo normal contando los pulsos en el flanco descendente y mostrar el estado de la cuenta TCNT0 en PORTC. #include <avr\io.h> int main () { PORTD|=(1<<PD4); //Pullup activada DDRC = 0xFF; //PORTC como salida TCCR0 = 0x6; //Timer 0, contador, flanco bajada while (1) { PORTC = TCNT0; if((TIFR&(1<<TOV0))==1)//desbordamiento TIFR |=(1<<TOV0); //Borra el indicador }//repite por siempre } En el Ejemplo de arriba, estamos utilizando Timer 0 como un contador de eventos que cuenta los pulsos de reloj que se alimentan en PD4. Estos pulsos de reloj podra representar el nmero de personas que pasan a travs de una entrada, o de rotaciones de una rueda, o cualquier otro evento que se puede convertir en pulsos. Los datos de TCNT0 se muestran en binario. Antes de terminar esta seccin, es necesario establecer un punto importante. Se podra pensar que monitorear las banderas TOV y OCR el microcontrolador pierde tiempo. Eso es cierto pero hay una solucin para esto: el uso de las interrupciones. Usando interrupciones nos permite hacer otras tareas con el microcontrolador. Ejemplo Supongamos que un reloj externo de 1hz se alimenta en el pin T1 (PD5). Escriba un programa en C para que el contador 1 con flanco ascendente se incremente para contar los pulsos y mostrar los registros TCNT1H y TCNT1L en PORTB y PORTC, respectivamente.

Solucin: #include "avr/io.h" int main () { PORTD |= (1<<PD5); //activa pull-up de PD5 = T1 DDRC = 0xFF; //PORTC salida DDRB = 0xFF; //PORTB salida TCCR1A = 0x00; //Fuente de reloj configurada TCCR1B = 0x06; //como contador con flanco desendente TCNT1H = 0x00; //Inicia en cero TCNT1L = 0x00; //Inicia en cero while (1) { do { PORTC = TCNT1L; PORTB = TCNT1H; //escribe el valor en los puertos }while ((TIFR&(1<<TOV1))==0);//espera desbordamiento TIFR |=(1<<TOV1); //Borra el indicador } }

PROGRAMACIN DE INTERRUPCIONES DEL TEMPORIZADOR


Desbordamiento del temporizador y bandera de interrupcin La bandera de desbordamiento del temporizador se pone a uno cuando el temporizador se desborda, vimos cmo monitorear la bandera del temporizador. En el monitoreo de TOV0, tenemos que esperar hasta TOV0 sea uno. El problema con este mtodo es que el microcontrolador tiene que esperar hasta que TOV0 se coloque a uno, y no se puede hacer nada ms. Usando las interrupciones evitamos atar al microcontrolador en este tiempo. Si la interrupcin del temporizador est habilitada en el registro de interrupcin, TOV0 se pone a uno cada vez que el temporizador se desborda y el microcontrolador salta a la tabla de vectores de interrupcin para dar servicio a la ISR. De esta manera, el microcontrolador puede hacer otras cosas hasta que sea notificado de que el temporizador se ha desbordado. Para utilizar una interrupcin en lugar de un monitoreo constante de TOV, primero debemos activar la interrupcin porque todas las interrupciones estn enmascaradas en el reset. El bit TOIEx permite la interrupcin para un temporizador determinado. Los bits TOIEx estn en el registro TIMSK como se muestra en la Tabla. Bits bandera de interrupcin de temporizador y registros asociados Interrupcin Bandera Registro Bit Habilitacin Registro Timer 0 TOV0 TIFR TOIE0 TIMSK Timer 1 TOV1 TIFR TOlE1 TIMSK Timer 2 TOV2 TIFR TOIE2 TIMSK

Ejemplo Uso del Timer 0 para generar una onda cuadrada en el pin PORTB bit 1, mientras que al mismo tiempo transfiere datos del PORTC a PORTD. #include "avr/io.h" #include "avr/interrupt.h" int main (){ DDRB |= 0x02;//DDRB 1 = output TCNT0= -32; //valor del timer para 4uS TCCR0 =0x01; //Normal mode, int clk, no prescaler TIMSK=(1<<TOIE0) ; //enable TimerO overflow interrupt sei (); //enable interrupts DDRC= 0x00; //make PORTC input DDRD=0xFF; //make PORTD output while (1) PORTD=PINC; //wait here } ISR(TIMER0_OVF_vect) { //ISR for TimerO overflow TCNT0 = -32; PORTB ^= 0x2; } Ejemplo Usando las interrupciones Timer 0 y Timer 1 y cristal de 8Mhz, escriba un programa en el que: (a) PORTC se incrementa cada vez que el Timer 1 se desborda una vez por segundo. (b) Un pulso se alimenta al Timer 0 y se usa como contador. Cada vez que el contador llegue a 200 se cambiar el estado del pin PORTB bit 4. Solucin: Para preescalar = 256 tenemos TClock= (1/ 8 MHz) x 256 = 32 uS y 1 s/32 us = 31250. De manera que TCNT1 = 31250 = 0x7A12 #include "avr/io.h" #include "avr/interrupt.h" int main (){ DDRB |= 0x10;//DDRB 4 = salida PORTB |= 0x10;// activa pullup TCNT0= -200; //carga el TimerO con -200 TCNT1H=(-31250) >>8; //byte alto para Timer 1 TCNT1L = (-31250)&0xFF;//se desborda despues de 31250 pulsos TCCR1A= 0x00; //modo Normal TCCR1B= 0x04; //,reloj interno, prescaler 1:256 TCCR0 =0x06; //Modo Normal , flanco descendente, no prescaler TIMSK=(1<<TOIE0)|(1<<TOIE1) ; //habilta las interrupciones del TimerO y del Timer 1 sei (); //habilita todas las interrupciones

PORTD|=(1<<PD2); //Pullup activada DDRC=0xFF; // PORTC como salida while (1) ; //wait here } ISR(SIG_OVERFLOW0) { //ISR para TimerO TCNT0 = -200; PORTB ^= 0x10; } ISR (SIG_OVERFLOW1) {//ISR para Timer1 TCNT1H=(-31250) >>8; //byte alto para Timer 1 TCNT1L = (-31250)&0xFF;//se desborda despues de 31250 pulsos PORTC ++; //incrementa PORTC }

También podría gustarte