2016-07-10 40 views
0

Ich verwende einen Arduino Uno mit dem Atmega328p-Mikrocontroller. Ich versuche, INT1 als Software-Interrupt zu verwenden. Ich habe INT1 den zugehörigen PORTD3 abhängig von externen Informationen manuell hoch oder niedrig gesetzt. Was ich will, ist, den Pin beim Start des Geräts hoch oder niedrig zu setzen und dann den Interrupt auf dem Pin zu aktivieren, ohne einen Interrupt zu verursachen, wenn ich den Pin auf "high" setze, bevor der Interrupt aktiviert wird.Interrupt tritt durch Änderung auf, die vor der Aktivierung der Interrupt-Funktion aufgetreten ist

Es scheint nicht wichtig zu sein, wo ich den Interrupt aktiviert habe - wenn ich den Zustand des Pins an einem Punkt änderte, wird der Interrupt auftreten, sobald er aktiviert ist. Hier ist ein Ausschnitt des Codes:

int main(void) 
{ 
    DDRD |= (1<<DDD7)|(1<<DDD3);//7 for siren 3 for software int1 
    USART_Init(MYUBRR);//Initialize USART 
    while(door!='C' && door!='O'){//get door state on startup 
     door = getDoorState(); 
    } 
    if(door=='O') 
     PORTD |= 1<<PORTD3; 
    else 
     PORTD &= ~(1<<PORTD3); 
    EIFR &= ~(1<<INTF1);//clear flag bit before enable, I'd heard this may help???? 
    EIMSK |= (1<<INT1);//enable door switch interrupt 
    EICRA |= (1<<ISC00)|(1<<ISC10);//int1 and int0 set for any logical change 

    sei();//global interrupt enable 

    while (1) 
     {} 
} 

Sobald die globale Interrupt durch einen Aufruf wäre aktiviert ist() wird die Interrupt auftreten, wenn PORTD3 hoch ist, unabhängig davon, wo PORTD3 eingestellt war hoch oder wo sei () ist. Der Aufruf von sei() sollte im Idealfall niemals einen Interrupt in diesem Code verursachen.

+0

Viele HW-Geräte setzen den Interrupt-Status für einzelne Ereignisse (z. B. Inport-Änderungen) unabhängig vom globalen Interrupt-Status. Wenn Sie dann den globalen Interruptstatus aktivieren, erhalten Sie einen Interrupt für das alte Ereignis. Sie müssen sicherstellen, dass ein altes Ereignis gelöscht oder bestätigt wird, bevor der Interrupt aktiviert wird. Wie das gemacht wird, steht im Handbuch. – 4386427

+1

Ein kurzer Blick auf das Datenblatt lässt mich glauben, dass das falsch ist: 'EIFR & = ~ (1 << INTF1);' Diese Zeile schreibt '0' nach INTF1 (aufgrund des ~). Es scheint jedoch, dass Sie die Flagge löschen müssen, indem Sie eine "1" schreiben. Versuchen Sie 'EIFR | = (1 << INTF1);' stattdessen. – 4386427

Antwort

0

4386427 ist korrekt. Das Bit wird gelöscht, indem es auf Eins und nicht auf Null gesetzt wird. Scheint kontraintuitiv zu mir, so dass es mich abwarf, aber es funktioniert jetzt.

EIFR |= (1<<INTF1); 
0

EIFR &= ~(1<<INTF1) ist falsch.

Die korrekte Vorgehensweise ist EIFR = 1<<INTF1.

Datenblatt sagt: Die Flagge wird gelöscht, indem eine '1' an sie geschrieben wird.