Detectando interrupciones en Atmega8 desde el circuito detector de cruce por cero

0

Tengo un circuito detector de cruce por cero, cuya salida le estoy proporcionando a mi Atmega8 como una interrupción, pero desafortunadamente no está funcionando. Si utilizo el suministro de CC 5V (lógica 1) como una interrupción, funciona. ¿A dónde me voy mal?

Se adjunta la salida del circuito detector de cruce por cero:

Aquí está mi código completo:

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

#define F_CPU 1000000UL
#include <util/delay.h>

#define DataPort    PORTB   // Using PortB as our Dataport
#define DataDDR     DDRB

//Interrupt Service Routine for INT0
ISR(INT0_vect)
{
    ///* This for loop blink LEDs on Dataport 5 times*/
    for(int i = 0; i<3; i++)
    {
        DataPort = 0x00;
        _delay_ms(50);  // Wait 5 seconds
        DataPort = 0xFF;
        _delay_ms(50);  // Wait 5 seconds
    }
}

int main(void)
{
    DDRD = 1<<PD2;      // Set PD2 as input (Using for interupt INT0)
    PORTD = 0<<PD2;     // Enable PD2 pull-down resistor

    DataDDR = 0xFF;     // Configure Dataport as output
    DataPort = 0xFF;    // Initialise Dataport to 1

    GICR = 1<<INT0;                 // Enable INT0
    MCUCR = 1<<ISC01 | 1<<ISC00;    // Trigger INT0 on rising edge

    sei();              //Enable Global Interrupt

    while(1)
    {
        DataPort = 0xFF;
    }
}
    
pregunta Ali_Waris

2 respuestas

1

Aunque puede que no sea su único problema, su ISR tarda varias veces más en ejecutarse que el intervalo de 50 ms entre pulsos.

Los retrasos largos, especialmente los repetidos, son casi siempre una mala idea en un ISR. Intente pulsar un pin de datos durante unos pocos microsegundos (no mili) o, mejor aún, alternar su estado cada vez que se active la interrupción, y monitorear con el alcance en lugar de un LED.

Dado que su señal tiene un aumento lento y una fuerte caída, podría considerar una interrupción de flanco descendente.

También verifique si el tipo de interrupción que está utilizando debe borrarse o restablecerse explícitamente antes de que pueda dispararse de nuevo; algunas MCU lo requieren y otras no.

Siempre tenga mucho cuidado al trabajar con circuitos conectados a la línea.

    
respondido por el Chris Stratton
1

Parece que no está viendo ninguna interrupción esperada debido a que pd2 está configurado para salida, no entrada.

DDRD = 1<<PD2;      // Set PD2 as input (Using for interupt INT0)

Sólo hay resistencias de pull-up en el ATMEGA8. Esto puede afectar tu circuito.

PORTD = 0<<PD2;     // Enable PD2 pull-down resistor

De la hoja de datos,

  

El bit DDxn en el registro DDRx selecciona la dirección de este pin. Si DDxn es una lógica escrita,   Pxn se configura como un pin de salida. Si DDxn se escribe cero lógico, Pxn se configura como una entrada   pin.

El retraso en la interrupción también debe evitarse ...

    
respondido por el Rob

Lea otras preguntas en las etiquetas