comportamiento extraño para atmel 16

0

aquí está el código

#define F_CPU 1000000UL
#include <avr/io.h>
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
int main(void)
{

DDRA |= (1 << PA0);
DDRB |= (1 << PB0);
DDRD |= (1 << PD2);

MCUCR |= (1 << ISC01);
GICR |= (1 << INT0);
sei();

while(1)
{


if (PINB == 0b00000001) //when i trigger pbo it will light pa0
{PORTA = 0b00000001;}  

}
              //idont want any thing to happen i want pa0 is on for ever 

}

ISR(INT0_vect)
{
    _delay_ms(10000);

    PORTA ^=(1<<PA0); //toggle pa0

}

y el circuito

el propósito es cuando presiono que el interruptor PB0 led conectado a PA0 se encienda

luego, cuando dispare la interrupción en PD2, esto debería cambiar PA0 para apagarlo

lo extraño cuando enciendo PA0 para apagarlo, el led se enciende automáticamente de nuevo sin activar la interrupción, ¿por qué?

¿Aunque este comportamiento no ocurre en la simulación de Proteus?

    
pregunta Shady Mohamed

1 respuesta

1

Los interruptores del mundo real no contactan de manera limpia, rebotan, abren y cierran sus contactos varias veces en unos pocos milisegundos antes de establecerse en su posición cercana.

Es casi seguro que lo que está sucediendo es que cuando presionas el botón derecho se cierra, luego se abre nuevamente antes de cerrarse finalmente.

El cierre inicial causará una interrupción, pero el segundo cierre causará que una interrupción pendiente se trabe en el procesador.

Cuando el ISR salga después de encender el LED, habrá una segunda interrupción pendiente que hará que se ingrese nuevamente el ISR.

(De The Lab Book Pages )

Este es un problema muy común y una de las razones por las que no es una buena práctica conectar un conmutador directamente a una interrupción.

El problema se puede resolver en hardware o software. Este sitio muestra algunas formas Switch debouncing .

También como cuestión de diseño de software, se considera malo poner un bucle de retardo dentro de un ISR. Las rutinas de servicio de interrupción deben hacer lo menos razonable y salir rápidamente. Todo el tiempo que el ISR se está ejecutando, el procesador no puede procesar otras interrupciones. En su ejemplo, no importa, pero en un sistema real lo haría.

    
respondido por el Kevin White

Lea otras preguntas en las etiquetas