AVR ATmega: Kann ich einen externen Interrupt auslösen, indem ich das entsprechende INTF-Flag-Bit setze?

Ich schreibe ein C-Programm für ATmega64A, das eine INT0 ISR hat. Diese ISR sollte im Falle einer fallenden Flanke von INT0 ausgeführt werden ODER wenn der TIMER3 überläuft.

Um eine Verdoppelung des Codes zu vermeiden, möchte ich Int0 ISR in der Überlauf-ISR von Timer 3 auslösen.

Leider fehlt im Datenblatt eine solche Angabe. Zumindest im INTF-Registerbeschreibungsabschnitt:

Geben Sie hier die Bildbeschreibung ein

Versucht das jemand? Oder kennt das vielleicht jemand theoretisch?

Könnten Sie in diesem ISR mehr tun, als Sie idealerweise sollten?

Antworten (1)

Nö.

Wenn Sie eine 1 in das Flag schreiben, wird es gelöscht. Das Schreiben einer 0 wird nichts tun.


avr-libcWenn Sie jedoch zwei (oder mehr) Vektoren mit genau demselben Code verwenden und haben möchten, ist dies möglich. Sie verwenden Interrupt-Aliasing. Ein Beispiel (von hier ):

ISR(PCINT0_vect){  
    ...  
    // Code to handle the event.
}

ISR(PCINT1_vect, ISR_ALIASOF(PCINT0_vect));

In diesem Beispiel teilen sich sowohl PCINT0als auch PCINT1denselben Unterbrechungscode – beide Einträge in der Vektortabelle zeigen auf dieselbe Funktion. Dies kann für Ihre Anforderungen ausreichend sein.

Gibt es also eine Lösung für eine solche Aufgabe (einen Code von mehreren ISRs ausführen)?
@RomanMatveev siehe meine Bearbeitung - ich musste die Syntax nachschlagen.
... oder Sie könnten einfach jede ISR als Shell (Wrapper) erstellen, die eine gemeinsame Unterfunktion aufruft.
@DaveTweed das ist möglich, aber das Aufrufen von Funktionen von ISRs ist zumindest mit avr-libc/ nicht immer eine gute Idee avr-gcc. Dies kann zu zusätzlichem Overhead durch zusätzliche Register führen, die geschoben und gepoppt werden, und fügt auch Overhead von den Call/Ret-Befehlen hinzu. Aliasing, falls verfügbar, ist eine schöne, saubere Methode, die zusätzlich zu der ursprünglichen Interrupt-Routine zu keinem Overhead führt.
Aliasing hat seinen eigenen Nachteil: ISRs sollten GENAU gleich sein. Daher kann ich INT0 ISR und das Timer-Register nicht gleichzeitig von Timer ISR löschen.
@RomanMatveev was versuchst du zu löschen? Wenn es nur die Flaggen sind, löschen sie sich selbst. Andernfalls ist die Verwendung von DaveTweeds Vorschlag die einzige einfache Möglichkeit, dies zu tun, wenn Sie möchten, dass jeder unterschiedliche Dinge tut.
Tom, ich spreche von Timer Counter Register (TCNT) klar. Es ist ein künstliches Beispiel (da TCNT eigentlich nicht gelöscht werden sollte). Außerdem dachte ich darüber nach, den INT0 ISR durch Ändern des Pin-Status auszulösen. Wird es funktionieren?
@RomanMatveev Ich glaube, dass das Ändern des Ausgangsregisters die ISR auslösen sollte, aber nicht 100% sicher.