Calificación:
  • 0 voto(s) - 0 Media
  • 1
  • 2
  • 3
  • 4
  • 5
Duda con interrupciones externas en AVR
#1
Hola a todos, estoy comenzando a aprender el manejo de las interrupciones en AVR y tengo algunas dudas.

Estoy trabajando con un ATtiny13, cuya tabla de vectores de interrupción es esta:

resim

Como veis, sólo tiene un único vector para interrupciones externas (INT0).

Este es su pinout:

resim

Pero según he leído en su datasheet, se pueden poner interrupciones en cualquiera de sus pines, desde PCINT5 hasta PCINT0.

Esto significa que si se utiliza una interrupción externa (PCINT0 a PCINT5), la rutina de interrupción se realizará dentro de la siguiente función:

ISR(PCINT0_vect){
//tareas a realizar dentro de la rutina de interrupción de PCINT0 a PCINT5
}

Entonces para probar esto, he hecho una simulación muy simple. He montado este circuito:

resim

La idea es que cuando presione el botón, el led se encienda 100 ms. Quiero que se encienda únicamente cuando se presiona, es decir, cuando PB3 pase de nivel bajo a alto.

Este es el código que he escrito:

Código:
#define F_CPU 9600000UL

#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>

ISR(PCINT0_vect)
{
PORTB |= (1<<PB1);
_delay_ms(100);
PORTB &= ~(1<<PB1);
_delay_ms(100);
}

void SystemInit(void)
{
PCMSK |= (1<<PCINT3); // pin change mask: nos ponemos a escuchar en PB3
GIMSK |= (1<<PCIE); // habilita  las interrupciones PCINT 
sei(); // habilitamos las interrupciones globales
}

int main(void)
{
DDRB |= (1<<PB1);
DDRB |= (1<<PB3);

SystemInit();

    while (1) 
    {
    }
}

El problema es que funciona siempre que el pin cambia de estado, y yo sólo quiero que cambie cuando haya un cambio de nivel bajo a nivel alto.

He estado viendo el registro MCUCR en el datasheet:

resim

Y he a gente que hace esto:

Código:
MCUCR &= ~(_BV(ISC01) | _BV(ISC00));

Pero no termino de entender como hacerlo.

¿Alguien me podría arrojar algo de luz por favor?

Gracias!!!
Citar
#2
El caso que quieres es el último de la tabla, con los dos a 1:
Código:
MCUCR |= (_BV(ISC01) | _BV(ISC00));

P.D. Pon una resistencia de pulldown, para evitar estados indeterminados (desconozco como se comporta Proteus en esos casos).
NOVEDAD: CoreXY Eternal Edition (Custom) -> https://www.spainlabs.com/foros/tema-Ete...So-Edition
Mi Prusa i3, ¡con lista de componentes! -> http://www.spainlabs.com/foros/tema-Un-clon-mas
Citar