mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Funktionsaufruf aus Interrupt


Autor: Johannes H. (menschenskind)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo

Bei mir öffnet ein Interrupt eine Funktion und führt dort eine 
Switch-Case-Anweisung aus, welche auf ein paar Defines aus einer 
Header-Datei zugreift.
Und diese Defines sollen meinen MP3-Player steuern.
Leider klappt das irgendwie gar nicht :(

Beispiel Pause:

switch...
   case 5: Pause();
           break;

in der .h-Datei sieht das so aus:

#define Pause() Control ^= (1<<0)

und dieses Bit wird dann im Hauptprogramm abgefragt mit
while(Control &0x01){}

Control ist bei mir volatile char

Ich las, dass Funktionsaufrufe in ISRn zu vermeiden sind. Aber ich 
wollte einfach mehr Übersicht in meinem Code und hab das deswegen so 
gelöst.
Gebt einfach mal eure Meinungen ab. Ich hab ein dickes Fell :D

Danke

Autor: Peter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
bestimmt fehlt da ein volatile - für mehr raten müssen man den code 
sehen.

Autor: Tim Seidel (maxxie)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Der Interrupt ist nicht zufällig ein Pin-Change Interrupt ohne, dass du 
das Prellen des angeschlossenen Tasters berücksichtigt hast?

Dann wäre die Funktion Pause rein zufällig, je nachdem ob die Taste eine 
gerade/ungerade Anzahl von Prellungen zeigt.

Autor: Blinder (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich sehe keinen Funktionsaufruf.

Autor: Johannes H. (menschenskind)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Aber wo sollte denn da ein Volatile fehlen? Die einzige Variable, die da 
ne Rolle spielt ist und bleibt 'Control'.

Die Tasten sind entprellt.

@Blinder: lass dir einfach noch mal den Text vorlesen ;)

Autor: Blinder (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Autsch.

Autor: Tim Seidel (maxxie)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Er hat schon Recht, es existiert in deinem geposteten Code kein 
Funktionsaufruf.

Den Fehler existiert in dem geposteten Code aber auch nicht. Der wird 
wohl an anderer Stelle sein. (Control lokal erneut definiert? Wird die 
case bzw die Bedingung der While nach Eintritt jemeils wieder erreicht? 
etc ...)

Autor: Johannes H. (menschenskind)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Deswegen steht ja auch das Stück Text davor: 
ISR-->Funktionsaufruf-->SwitchCase

Nein, Control wird nach den Defines in der main.c deklariert.

Also müsste es eurer Meinung nach so funktionieren, wie ich es hab?

Autor: Christopher G. (cbg)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Johannes Hofmann schrieb:
> Also müsste es eurer Meinung nach so funktionieren, wie ich es hab?

Nein. Unserer Meinung nach solltest du deinen Code posten. Die 
Glaskugeln von heute sind nicht so gut wie sie einmal waren.

Autor: oldmax (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi
Wenn ich ISR-Abhängige Funktionsaufrufe habe, dann setze ich mir in der 
ISR ein Flag, welches vom Hauptprogramm bearbeitet wird. Vorteil: Die 
ISR wird nicht durch eine unbekannte Länge einer Funktion belastet und 
kann andere Aufgaben auch noch erfüllen.
Im Hauptprogramm wird dann die eigentliche Funktion bedingt aufgerufen 
und am Schluß das Flag zurückgesetzt.
Z.B. Du hast eine Variable auf 0 solange kein ISR erfolgt ist. Im 
Hauptprogramm fragst du nach ungleich 0 ab und rufst entsprechende 
Unterprogramme auf. Am Ende setzt du die Variable wieder auf 0 und 
kannst auf den nächsten Interrupt warten.
Gruß oldmax

Autor: Tim Seidel (maxxie)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Was Interrupts ad absurdum führt ...

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Siehe Interrupt

Autor: oldmax (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi
>Was Interrupts ad absurdum führt ...
Nicht ganz. Angenommen, es kommt ein Byte im USART an und ein Interrupt 
wird ausgelöst. Natürlich lege ich dieses Byte auf den Empfangspuffer 
und passe den Schreibzeiger für diesen Puffer an. Das Hauptprogramm 
erkennt den Unterschied zwischen Schreib- und Lesezeiger und bearbeitet 
den Empfang in den wesentlich aufwändigeren Programmabschnitten. Das mit 
dem Flag sollte lediglich ein Hinweis auf die unbekannte Länge der ISR 
sein. Diese sollte nicht aufwändige Routinen aufrufen, es sei denn, es 
ist wichtig, zeitnah abzuarbeiten. Es gibt auch Kollegen, die qualmen 
ein recht umfangreiches Auswahlprogramm in einen Interrupt und rufen 
dazu noch Unterprogramme in dieser Auswahl auf. In dieser Zeit sind u.U. 
weitere Ereignisse eingetroffen, aber niemand hat sie gehört.....
>Bei mir öffnet ein Interrupt eine Funktion und führt dort eine
>Switch-Case-Anweisung aus, welche auf ein paar Defines aus einer
>Header-Datei zugreift.
und dann das ...
>case 5: Pause();
>           break;

Gruß oldmax

Autor: Reinhard Kern (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
oldmax schrieb:
> .... In dieser Zeit sind u.U.
> weitere Ereignisse eingetroffen, aber niemand hat sie gehört.....

Hi,

das ist ja noch einer der einfachsten Fälle, viel schlimmer ist es, wenn 
der nächste Interrupt die aufgerufen Unterprogramme an einer beliebigen 
und wie es der Teufel will ganz ungünstigen Stelle unterbricht. Und 
Variablenzugriffe müssen atomar ausgeführt oder entsprechend abgesichert 
werden - auch wenn man das auf Anhieb nicht sieht, gerade Bitoperationen 
sind z.B. bei vielen Prozessoren keineswegs atomar, sondern werden als 
Read-Modify-Write ausgeführt. Ob sie unterbrechbar sind, müsste man im 
Prozessorhandbuch nachlesen.

In komplexen Systemen (z.B. Windows) wird oft nur ein "Stub"-Programm 
von möglichst wenigen Befehlen als ISR ausgeführt und dann an ein 
normales Programm übergeben - kein Problem, wenn man ein RTOS zur 
Verfügung hat. Wenn nicht, kann man ev. auch dem Prozessor per 
Stackmanipulation ein Unteprogramm unterschieben, aber das ist dann 
schon sehr tricky und hardwarespezifisch.

Gruss Reinhard

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.