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
bestimmt fehlt da ein volatile - für mehr raten müssen man den code sehen.
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.
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 ;)
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 ...)
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?
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.
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
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
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
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.