Autor Tema: Uso de los bits INTF (Flag de interrupción externa)  (Leído 4939 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado julioJF

  • PIC10
  • *
  • Mensajes: 25
Uso de los bits INTF (Flag de interrupción externa)
« en: 24 de Noviembre de 2010, 08:58:25 »
Hola a todos,

he empezado hace nada a programar microcontroladores (como hooby) y me he decidido a utilizar ATMEL. He comprado una STK500 y utilizo WINAVR para programar en C (me parece más sencillo que el ensamblador). Utilizo el AtMega8515 ya que es el que trae la placa.
Ahora mismo estoy estudiando las interrupciones externas, y me gustaría profundizar con vosotros en el uso de los flags INTF. Voy a dar una explicación de este flag tal y como yo lo he entendido y experimentado y espero que vosotros, que sois más experimentados verifiquéis si el planteamiento es correcto o hay algo que añadir.

Suponemos que implementamos la INT0 (PD2), configurada por flanco de subida y tenemos el I-bit en SREG y el bit INT0 en GICR activados(a 1). Bien, cuando se produce tal interrupción, el micro pasa a ejecutar el código implementado para dicha interrupción (función ISR(INT0_vect)). Una vez ejecutado el código de la interrupción, el micro continúa su ejecución normal (donde estaba antes de producirse la interrupción).

Bien, ahora veamos dónde entra el flag INTF0: inicialmente el valor es INTF0=0. Cuando se produce un flanco de subida en PD2, el micro pone INTF0=1, y como el I-bit en SREG y el bit INT0 en GICR activados(a 1), pasa a ejecutarse la interrupción. En ese momento, el micro pone INTF0=0 y I-bit=0 y comienza a ejecutarse el código de la Interupción. Vemos que INTF0 en 1 no dura casi nada.

Vale, ahora, si se produce un nuevo flanco de subida en PD2 mientras se está ejecutando el código de la Interupción, se establecerá INTF0=1. Cuando acabe la ejecución actual de la interrupción, el micro automáticamente reactivará el I-bit=1 y en ese momento se encontrará con INTF0=1, lo que volverá a provocar una nueva interrupción, y el proceso se repetirá, estableciéndo INTF0=0 cuando empiece a ejecutar de nuevo el código de la interrupción.

Bien, pues esta es la idea que tengo de funcionamiento del INTF después de haber leído distintos apuntes y de haber hecho algunas implementaciones prácticas. Ahora necesito que comentéis sobre este tema a ver si me equivoco en algo y necesito resolver alguna duda:

- para "limpiar" el INTF0 y evitar que al acabar una interuupción salte otra pendiente, escribes INTF0=1. Esto es correcto porue lo he comprobado experimentalmente. Pero mi lógica me decía que tendría que escribir INTF0=0. ¿Alguien puede razonarme esta manera de "limpiar" este flag?.

El uso de este Flag lo veo muuy útil cuando quieres evitar el bouncing al realizar una pulsación sobre un switch. Sólo estableces el INTF0=1 al final del código de interrupción y listo. Eso sí, tienes que asegurarte que la duración de la ejecución del código de la interrupción dure más tiempo que el posible Bouncing.

- ¿alguien ha utiliza este flag para algún propósito?

Un saludo a todos y espero que esto sirva aportar.
P.D.: he subido este tema también el el foro de ATMEL de http://foros.solocodigo.com, ya que son los dos únicos foros de ATMEL que he encontrado en español.

Desconectado stk500

  • Moderador Local
  • DsPIC33
  • *****
  • Mensajes: 4923
Re: Uso de los bits INTF (Flag de interrupción externa)
« Respuesta #1 en: 24 de Noviembre de 2010, 09:58:01 »
Hola Julio y Bienvenido a nuestros Foros Todopic.
Muy interesante tu Tema aunque no programo en C, uso mas AVRBascom osea Basic, por otro seria muy interesante simularlo con el proteus ya que no todos tenemos el STK500, aunque yo lo tengo  :P
podia poner algun codigo de ejemplo de esa funcion que comenta?

Saludos

Desconectado julioJF

  • PIC10
  • *
  • Mensajes: 25
Re: Uso de los bits INTF (Flag de interrupción externa)
« Respuesta #2 en: 24 de Noviembre de 2010, 11:45:34 »
Hola STK500,

entiendo por tu nick que sí tienes la placa!!, jeje

Bien, pues el programita con el que estoy probando esta función es el siguiente:
Código: [Seleccionar]
#include <avr/io.h>
#include <avr/interrupt.h>

#define F_CPU 3680000 /* 3.68 Mhz. Es la frecuencia que me proporciona el stk500. Hay que definirlo antes del #include "delay_x.h" */
#include "delay_x.h"     // una librería para generar retardos.

int main (void)
{
// PORTB: LED´s como salidas.
PORTB = 0xFF; // Inicialmente todos apagados.
DDRB = 0xFF;

// PORTD: SWITCH´s (PD2 y PD3 como entradas). Habilitamos tb sus PULL-UP.
PORTD |= _BV(PD2)|_BV(PD3); // activar resistencia de pull-up
DDRD &= ~(_BV(DDD2)|_BV(DDD3)); // PD2 y PD3 como entradas.

// configuramos INT0 como activación por flanco de subida: ISC01=1, ISC00=1.
MCUCR |= _BV(ISC01)|_BV(ISC00);

// activación de interrupcion externa 0
GICR |= _BV(INT0);

// activación de interrupciones globales
sei();

for(;;) // Main loop
{
}

}

// interrupción INT0

ISR(INT0_vect){
PORTB &= ~(_BV(PORTB4)|_BV(PORTB5)); // encendemos los 2 penúltimos LED´s
_delay_s(5); // reatrdo de 5 segundos
PORTB |= _BV(PORTB4)|_BV(PORTB5); // apagamos los 2 penúltimos LED´s

                // observo si INTF0 está activado. Si está activado, parpadea el LED 3 durante 2 segundos, sino se enciende contínuamente durante 2 seg.
if (GIFR & _BV(INTF0)){ // encendemos durante 2 seg.
PORTB &= ~_BV(PORTB3);
_delay_s(2);
PORTB |= _BV(PORTB3);
} else { // intermitencia durante 2 seg.
PORTB &= ~_BV(PORTB3);
_delay_s(0.2);
PORTB |= _BV(PORTB3);
_delay_s(0.2);
PORTB &= ~_BV(PORTB3);
_delay_s(0.2);
PORTB |= _BV(PORTB3);
_delay_s(0.2);
PORTB &= ~_BV(PORTB3);
_delay_s(0.2);
PORTB |= _BV(PORTB3);
_delay_s(0.2);
PORTB &= ~_BV(PORTB3);
_delay_s(0.2);
PORTB |= _BV(PORTB3);
_delay_s(0.2);
PORTB &= ~_BV(PORTB3);
_delay_s(0.2);
PORTB |= _BV(PORTB3);
_delay_s(0.2);
}


// limpio el INTF0 para evitar el bouncing en la pulsación. Esta linea la comentamos o no para ver la diferencia
// GIFR |= _BV(INTF0);

}
 



con este programita, si mientras se está ejecutando una interrupción, pulsamos sobre PD2 para provocar otra, en cuanto termine la ejecución activa saltará una nueva provocada por nuestra pulsación.

Si para el mismo caso, tenemos sin comentar la linea

//   GIFR |= _BV(INTF0);   

entonces, no saltará la interrupción pendiente. Estamos limpiando el INTF0.


Podrías simularlo con Proteus y ver cómo se mueve el Flag INTF0?? Yo no sé usar el Proteus y me sería más costoso.

Un saludo.
« Última modificación: 24 de Noviembre de 2010, 14:16:22 por stk500 »

Desconectado stk500

  • Moderador Local
  • DsPIC33
  • *****
  • Mensajes: 4923
Re: Uso de los bits INTF (Flag de interrupción externa)
« Respuesta #3 en: 24 de Noviembre de 2010, 14:19:44 »
como podra ver modifique el mensaje, te recomiendo que use el icono # de insertar codigo, asi se encuadra mejor pera leerlo :mrgreen:

pues bien voy a intentarlo simularlor con proteus y luego te cuento.

Saludos


 

anything