www.mikrocontroller.net

Forum: Compiler & IDEs Aus dem Interrupt vorzeitig rausspringen?


Autor: RichieRich (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich habe eine kleine Frage an die GCC experten.

Und zwar möchte ich, durch einen externen Interrupt(INT0) in die 
Interruptroutine reinkommen (was kein Problem ist) und bei einem 
erneuten externen Interrupt am INT0 wieder zum Anfang der 
Interruptroutine gelangen.

Geschieht dies dadurch, dass ich in der Interruptroutine folgendes 
Register zu 1 setze?

GIFR = 1 << INTF0;

geht das auch mit sei(); im Interrupt?

P.S. Es handelt sich um einen ATMega32.


Danke

Autor: Sven P. (haku) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das geht eigentlich nur mit sei(). Aber davon lässt du bitte die Flossen 
und liest dir stattdessen mal die Beschreibung zu 'ISR' durch.

Autor: sven (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das passiert von alleine. Jedoch musst Du zusehen, dass Du vor dem 
nächsten Ausführen deine ISR verlassen hast.

Sollte das für Dich nicht machbar sein, ist deine Architektur falsch.

Autor: Sven P. (haku) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
sven schrieb:
> Das passiert von alleine. Jedoch musst Du zusehen, dass Du vor dem
> nächsten Ausführen deine ISR verlassen hast.
Nein, eben nicht. Interrupts dürfen und können problemlos 
'verschachtelt' werden.

Ich sag ja -- Dokumentation lesen hilft ungemein.

Autor: Jörg G. (joergderxte)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Und zwar möchte ich, durch einen externen Interrupt(INT0) in die
> Interruptroutine reinkommen (was kein Problem ist) und bei einem
> erneuten externen Interrupt am INT0 wieder zum Anfang der
> Interruptroutine gelangen.
Wie meinst du das?
Du kannst mit "return" jederzeit aus der ISR (wie auch aus jeder anderen 
Funktion) 'aussteigen' - wenn die Bedingung für den Externen Interrupt 
noch/wieder besteht, landest du wieder in der ISR.

> Geschieht dies dadurch, dass ich in der Interruptroutine folgendes
> Register zu 1 setze?
>
> GIFR = 1 << INTF0;
Damit löschst du das Flag, das macht man normalerweise, damit die 
Hardware es wieder setzen kann (Schau noch mal in Datenblatt, wie die 
die Flags für den externen Interrupt funktionieren)
> geht das auch mit sei(); im Interrupt?
Damit geht einiges, aber wahrscheinlich viel ungewolltes.


hth, Jörg

Autor: RichieRich (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke erstmals für die Hinweise!

Die Grundidee war, beim erster Sprung ins Interrupt (ausgelöst durch 
INT0, extern) eine variable zu inkrementieren und dann 500ms zu warten 
ob ein zweiter Interrupt kommt.
Falls kein weiteres externes Interrupt kommt sollte eine Funktion_1 
aufgerufen werden. Sollte jedoch ein weiteres Interrupt kommen, kehrt 
das Programm zum Anfang des Interrupt zurück und die variable wird 
nochmals inkrementiert und es wird eine Funktion_2 aufgerufen.

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Im Interrupt-Handler 500ms warten? Urgs... Total falscher Ansatz.

Autor: Sven P. (haku) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Dann haste nen Konzeptfehler. In einer Interrupt-Routine 500ms zu 
warten, das is ne Katastrophe.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
RichieRich schrieb:
> Danke erstmals für die Hinweise!
>
> Die Grundidee war, beim erster Sprung ins Interrupt (ausgelöst durch
> INT0, extern) eine variable zu inkrementieren und dann 500ms zu warten
> ob ein zweiter Interrupt kommt.
> Falls kein weiteres externes Interrupt kommt sollte eine Funktion_1
> aufgerufen werden. Sollte jedoch ein weiteres Interrupt kommen, kehrt
> das Programm zum Anfang des Interrupt zurück und die variable wird
> nochmals inkrementiert und es wird eine Funktion_2 aufgerufen.

Dachte ich mir schon:
Falscher Ansatz.

Die komplette Auswertung machst du in main().
Die ISR signalisiert der Hauptschleife in main() nur, dass der Interrupt 
eingetreten ist.

In einer ISR auf irgendetwas zu warten, ist eigentlich fast immer ein 
sicherer Weg ins Chaos.

Wenn die ISR aufgerufen wird, setzt sie eine globale Variable auf 1.
Die Hauptschleife sieht sich ständig diese Variable an. Wird sie 1, dann 
setzt sie die Variable zurück auf 0 und startet sie den Timer (oder was 
du sonst benutzt um die 500ms abzuzählen). Nach Ablauf des Timers kann 
mann dann zb. nachsehen ob die globale Variable durch die ISR noch mal 
auf 1 gesetzt wurde und entsprechend reagieren.

Wie misst du denn die 500ms? Je nachdem welche Methode du benutzt, 
bietet sich ein anderer Ansatz an.

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Siehe Interrupt.

Autor: Mark Brandis (markbrandis)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ist das dann ein Interruptus interruptus? :-)

Autor: P. S. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sven P. schrieb:

> Dann haste nen Konzeptfehler. In einer Interrupt-Routine 500ms zu
> warten, das is ne Katastrophe.

Was passiert dann, explodiert der Controller?

Autor: Sven P. (haku) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ja, es kommt dann meistens zur Kernfusion.

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Peter Stegemann schrieb:

> Was passiert dann, explodiert der Controller?

Nein, aber der Programmierer, vor Frust und Verzweiflung.

Autor: PJ (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Was passiert dann, explodiert der Controller?

Nee, aber vielleicht der Stack.

Wenn man es schlau genug macht, kann man das aber verhindern.

Es gibt nichts, was prinzipiell dagegen spricht. Aber man muss sehr 
sorgfältig vorgehen.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
PJ schrieb:

> Aber man muss sehr
> sorgfältig vorgehen.

Du sagst es, Bruder!

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.