Forum: Mikrocontroller und Digitale Elektronik Interrupt nur 1x ausführen


von Dirk (Gast)


Lesenswert?

Ich habe hier einen Pin den ich als Interrupt konfiguriere, der 
Interrupt wird ausgelöst, dann werden über den selben Pin Daten 
ausgetauscht, Da der Pegel wechselt, wird also zwangsläufig der 
Interrupt nochmal ausgelöst.

Nach beenden des Interrupts wird dann der Interrupt noch mal ausgeführt 
was wohl normal ist wenn der INterrupt im Interrupt nochmal auftritt.

Wie kann ich das verhindern?

Ich möchte also das der Interrupt nur ein mal getriggert wird, bis ich 
ihn wieder frei gebe.

Ich dachte das ginge so: (vor dem Interrupt-Ende)
GIFR&=~(1<<INTF0);

dem ist aber nicht so...

Bin für Hilfe sehr dankbar

von AVRFan (Gast)


Lesenswert?

GIFR enthält die Flags; die benötigten Enable/Disable-Bits befinden sich 
in GIMSK.  Nimm also GIMSK und INT0 statt GIFR und INTF0.

von AVRFan (Gast)


Lesenswert?

Upps, Korrektur: GICR heißt das Ding, nicht GIMSK.
                 ¯¯¯¯

von Johannes M. (johnny-m)


Lesenswert?

AVRFan wrote:
> Upps, Korrektur: GICR heißt das Ding, nicht GIMSK.
>                  ¯¯¯¯
Kommt drauf an, welchen AVR er verwendet (hat er ja bisher 
verschwiegen). Bei den älteren Typen heißt das Register tatsächlich 
GIMSK...

von Dirk (Gast)


Lesenswert?

Problem hat sich gerad erledigt..

Wer das gelesene auch umsetzt is klar im Vorteil grml

"Alternatively, the flag can be cleared by writing a logical one to it."
Also ja wohl: GIFR|=(1<<INTF0);

Btw. bei dieser Methode führe ich o.a. einfach nur 1x aus (am Ende des 
Interrupts) und gut.

Wenn ich Int0 im GICR lösche müsste ich es ja danach wieder setzen..

trotzdem Danke AVRFan

von Johannes M. (johnny-m)


Lesenswert?

Ach, das wolltest Du machen... Das war aus Deinem OP nicht 
herauszulesen. Da steht genaugenommen sogar das, was AVRFan ganz richtig 
beschrieben hat:
> Ich möchte also das der Interrupt nur ein mal getriggert wird, bis ich
> ihn wieder frei gebe.
Genau das (sperren und irgendwann wieder freigeben) macht man nämlich 
mit dem GICR bzw. GIMSK.

Wenn Du das Flag löschst, werden nur die Interrupt-Ereignisse, die 
bereits aufgetreten sind, gelöscht. Der Interrupt kann aber jederzeit 
erneut auftreten.

Mit den Interrupt-Flag-Registern sollte man übrigens keine 
Read-Modify-Write-Operationen machen (also kein "|="), da auf die Weise 
alle in dem Register befindlichen Flags gelöscht werden! Da eine Null 
jedoch keinen Effekt auf die Flags hat, lässt man einfach das "|" weg. 
Also einfach z.B.
1
GIFR = 1 << INTF0;

> Wenn ich Int0 im GICR lösche müsste ich es ja danach wieder setzen..
...genau das wolltest Du doch oben...

BTW:
Wenn Du einen Interrupt sperrst (über das zugehörige Enable, z.B. im 
GICR für die externen Interrupts), dann ist es in den meisten Fällen 
sinnvoll, vor der erneuten Freigabe das entsprechende Flag zu löschen. 
Ansonsten wird, falls das Flag während der Sperrphase gesetzt wurde, der 
Interrupt Handler sofort nach der Freigabe aufgerufen.

von Dirk (Gast)


Lesenswert?

>> Wenn ich Int0 im GICR lösche müsste ich es ja danach wieder setzen..
>...genau das wolltest Du doch oben...

Ja ich habe oben irgendwie nicht so das geschrieben was ich wollte..

Auf jeden Fall ist
>GIFR = 1 << INTF0;
ein sehr guter/wichtiger Hinweis

Danke euch Beiden!

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.