Você está na página 1de 15

seminario

sesion11

PRCTICA1.-: USO DE LA INTERRUPCIN INTX


Realizar El programa para realizar dos tareas: la rutina principal se encargar de parpadear un LED y la funcin de interrupcin har bascular otro LED cada vez que presionemos un pulsador. De las seales que se generan al presionar el botn escogeremos el flanco de bajada para disparar la interrupcin INT0.

EL PROGRAMA Cada aplicacin puede tener sus propias especificaciones, pero, en general, un buen hbito de programacin es poner la sentencia sie(); que setea el bit I del registro SREG cuando ya todo est listo para atender a la interrupcin. Al analizar la estructura del programa, notamos que la funcin ISR es totalmente independiente de main, es decir, no es referenciada desde ningn punto de main. Una vez habilitada, la interrupcin se disparar cuando alguien presione el botn (en el flanco de bajada). En ese preciso instante (quiz cuando se est ejecutando PINC = 0x02 o quiz en algn punto dentro de delay_ms(600)) el CPU pasar a ejecutar la funcin ISR. Al salir de ISR, el CPU regresar a continuar la tarea que estaba ejecutando antes de la interrupcin.

#include "avr_compiler.h void delay_ms (unsigned int t) { while(t--) delay_us(1000); } // Interrupt Service Routine, ISRI SR (INT0_vect) { PINC = 0x01; // conmuta pin PC0 delay_ms(40); // Para pasar los rebotes } int main(void) { DDRC = 0x03; // Pines PC0 y PC1 para salida PORTD = 0x04; // Habilitar pull-up de pin PD2/INT0 cli(); GIFR= 0X40 GICR = (1<<INT0); // Habilitar INT0 MCUCR=0X03; // Elegir flanco de bajada (modo 2) sei(); // Habilitacin global de interru while(1) // Bucle infinito { PINC = 0x02; // Conmutar pin PC1 delay_ms(600); // Pausa de 600ms }

EL MODO SLEEP (sueo del uC) El modo Sleep es un estado en que se detiene el oscilador del sistema y, por tanto, dejan de funcionar todas las partes del microcontrolador que dependen de l, incluyendo en algunos casos el mismo procesador, es decir, se congela la ejecucin del programa. Sin embargo los valores de todos los registros y puertos del microcontrolador permanecern inalterables. En este estado se dice que el microcontrolador est durmiendo, por el trmino sleep = sueo, en ingls.
Al hacer que el microcontrolador se ponga a dormir y que despierte solo cuando cierto evento se lo demande, se consigue ahorrar muchsima energa que se perdera con el CPU y dems perifricos estando activos en vano. Esto es clave sobre todo en circuitos alimentados por bateras. Los microcontroladores AVR tienen un sistema oscilador sofisticado que divide el reloj en varias ramificaciones que van a los diferentes mdulos del AVR el mayor nivel, es decir, donde el hardware del AVR se congela por completo se denomina Power-down. El modo Power-down se configura escribiendo el valor 0x02 en el registro SMCR y luego la instruccin de ensamblador sleep para que el AVR cierre sus ojos

Practica 02
PRCTICA: INTERRUPCIONES MLTIPLES + MODO SLEEP Si al ejercicio anterior le quitsemos la tarea de la rutina principal, el AVR ya no tendra nada que hacer all. ste puede ser un buen momento para tomar una siesta. Por otro lado, en esta ocasin experimentaremos con las dos interrupciones, INT0, INT1 , al mismo tiempo como ejemplo de uso de interrupciones mltiples.

#include "avr_compiler.h void delay_ms (unsigned int t) { while(t--) delay_us(1000); } //.. ISR (INT0_vect) { PINC = 0x01; // Conmutar pin PC0 delay_ms(40); // Para pasar los rebotes } //. I SR (INT1_vect) { PINC = 0x02; // Conmutar pin PC1 delay_ms(40); // Para pasar los rebotes } //********************

/int main(void) {
DDRC = 0x07;

PORTD = 0x0C; PORTB = 0x04;

//

* Habilitar las interrupciones INT0, INT1 y configurarlas para que * se disparen: * INT0 con cada flanco (de bajada o subida) en el pin INT0/PD2 (modo 1) * INT1 con cada flanco de subida en el pin INT1/PD3 (modo 3) */

GICR = (1<<INT0)|(1<<INT1); // Habilitar INT0, INT1 MCUCR=0x0A; // Elegir flancos sei(); // Habilitacin general de interrupciones while(1) // Bucle infinito { /* Entrar en modo sleep (Power-Down mode) */ MCUCR = 0xB0 ; sleep(); nop(); } } }

PRCTICA: TEMPORIZACIN DEL TIMER0 GENERACION DE ONDA CUADRADA El programa genera una onda cuadrada conmuta cada 2.5 ms, la temporizacin debe ser lo ms precisa posible, ni 1 s ms ni 1 s menos. Visto de otro modo, el programa genera una seal de onda cuadrada de 200 Hz.

Descripcin del programa El punto crucial del programa es el clculo de la temporizacin. Segn mi cdigo, para que la seal cambie de nivel cada 2.5 ms, la funcin Pause debera tomar 2499.55s, ya que el bucle llega a dicha llamada cada 0.45 s (lo vi en el simulador de Atmel Studio 6). Por supuesto, este valor puede variar de un compilador a otro porque cada cual compila a su modo. Inclusive vara en un mismo compilador segn el nivel de optimizacin establecido o segn el microcontrolador usado. Esta exposicin la hago habiendo compilado el cdigo con AVR GCC con nivel de optimizacin Os.

while(1) { PINA = 0x01; Pause(); }

// Loop forever // Conmutar pin PB0 // Delay de 2499.55 us

El factor de prescaler sera:

Y el valor inicial del TCNT0 es:

El ajuste de la temporizacin se ha conseguido aadiendo algunos nops en Pause. Esto es tiempo muerto pero son solo 2 us, nada comparado con los 2500 us del total. Para calibrar estas precisiones es aconsejable recurrir al Cronmetro de Proteus o al Stopwatch de Atmel Studio 6.

#include "avr_compiler.h"
void Pause(void); // Prototipo de funcin //*************************************************************** // Funcin principal //************************************************************************ int main(void) { DDRB= 0x01; // PA0 salida de seal /* Configuracin del Timer0 * Modo de operacin = Normal * Factor de prescaler = 256 */ TCCR0A = 0x00; TCCR0B = (1<<CS02); while(1) // Loop forever { PINB = 0x01; // Conmutar pin PA0 Pause(); // Delay de 2499.55 us } }

//************************************************************************ // Produce 2499.55 s exactamente // Con el Prescaler de 256 y con con XTAL de 8 MHz el Timer0 se incrementa // cada 256/8 = 32 us. Por tanto, para alcanzar 2499.55 s se requieren de // 2499.55/32 = 78.1 ticks. Ergo, TCNT0 se debe cargar con 256-78.1 = 178 //************************************************************************ void Pause(void)

GTCCR = (1<<PSRSYNC); // Resetaer prescaler TCNT0 = 178; // Cargar registro TCNT0 TIFR0 = (1<<TOV0); // Limpiar flag de desbordamiento del Timer0 while((TIFR0&(1<<TOV0))==0); // Esperar hasta que ocurra el desbordamiento nop(); nop(); nop(); nop(); nop(); nop(); nop(); nop(); // NOPs para ajustar la precisin nop(); nop(); nop(); nop(); nop(); nop(); nop(); nop(); nop(); }

PRACTICA4 Prctica: El Timer0/2 Como Contador La prctica no puede ser ms sencilla: el Timer0 contar los flancos de bajada generados por un pulsador conectado al pin T0 del AVR. El valor del registro TCNT0 ser enviado al terminal serial. No se pondr ningn mecanismo antirebote. As que el Timer0 se incrementar con todo y los rebotes

#include "avr_compiler.h Int main(void) { unsigned char tcnt0; PORTB |= (1<<0); // Activar pull-up de pin PB0/T0 /* Configuracin del Timer0 * - Modo de operacin = Normal * - Fuente de reloj = Pin T0 *- El registro TCNT0 se incrementa con los flancos de bajada del pin T0 */ TCCR0A = 0X00; TCCR0B = (1<<CS02)|(1<<CS01); /* Resetear TCNT0 */ TCNT0 = 0x00; tcnt0 = ~TCNT0; for(;;) { if(tcnt0 != TCNT0) { tcnt0 = TCNT0; PORTD=tcnt0 } } }

Você também pode gostar