Kann man Interrupts auch in ihnen selber mit cli() beenden, so dass bei schnellen Interruppts diese definitiv nicht ein x-tes mal aufgerufen werden. Wenn ich das in der main machen würde, könnte es ja sonst sein, dass der Interruppt noch einmal ausgeführt wird. Mit Flag setzen und jedes mal if-Abfrage machen, habe ich evtl zu viel Zeitverlust.
>Kann man Interrupts auch in ihnen selber mit cli() beenden, Ein 'cli' beendet überhaupt keinen Interrupt, sondern eine sogenannte Critical Section, d. h. einen kurzen, interruptgesperrten Codeabschnitt. Interrupts finden ihr Ende üblicherweise mit 'reti' oder 'ret'. >so dass bei schnellen Interruppts diese definitiv nicht ein x-tes mal >aufgerufen werden. Das widerspricht dem Sinn und Zweck von Interrupts. Immer wenn ein Ereignis auftritt, soll auch der Interrupt aufgerufen werden, in dessen Handler das Ereignis "verarbeitet" werden kann. Dadurch kann, wenn man es richtig macht, kein Ereignis verlorengehen. >Wenn ich das in der main machen würde, könnte es ja sonst sein, >dass der Interruppt noch einmal ausgeführt wird. ? >Mit Flag setzen und jedes mal if-Abfrage machen, habe ich evtl zu viel >Zeitverlust. ?
Glasskugel: Du willst nicht, dass ein Interrupt ein weiteres mal ausgeführt wird, während noch die erste ISR läuft? Das macht der AVR schon von ganz alleine. Beim Sprung in den Interrupt Handler werden weitere Interrupts abgeschaltet, beim "reti" werden sie wieder aktiviert...
ISR wrote:
> Kann man Interrupts auch in ihnen selber mit cli() beenden
Ein CLI innerhalb eines Interrupthandlers wirkt wie ein NOP.
Ein CLI würde außerdem sämtliche anderen Interrupts abschalten.
Du mußt das Enablebit genau des einen Interrupts auf 0 setzen, damit er
nicht nochmal ausgeführt wird.
Und vor der erneuten Freigabe das Interruptflag löschen (auf 1 setzen).
Peter
>beim "reti" werden sie wieder aktiviert...
und wenn in der Zwischenzeit der Interrupt wieder ausgelöst wurde, wird
die ISR sofort wieder aufgerufen. Verhindern lässt sich das nur, wenn
der jeweilige Interrupt gesperrt wird.
Ob das das Problem löst, wer weiss?
Oliver
Ich will nicht, dass er wieder ausgeführt wird, wenn er zurückgesprungen ist. Es kann ja sein, dass so schnell wieder ein Interrupt ansteht, dass nach dem Rücksprung sofort wieder hineingesprungen wird. Je nach dem and welcher Stelle er in den Interrupt hinein bzw zurück gesprungen ist, kann da ja ein wenig Zeit bis zum cli() vergehen. Genau diese Zeit zw. Rücksprung und dem cli() möchte ich vermeiden. Bsp.: bei Frequenzmessung mit hohen Frequenzen wird aus dem capture Interrupt zurückgesprungen (wieder in die main). Bevor ich die Interruppt ausstellen kann, wird wieder in diesen gesprungen und der Zeitpunkt der Ersten Flanke überschrieben, da ich cli() nicht schnell genug ausführen konnte. Deswegen habe ich gefragt, ob ich die Interrupts schon in der ISR ausstellen kann, damit nicht wieder hinein gesprungen wird. Es wird ja an die Stelle wieder gesprungen, an welcher in den Interrupt gesprungen wurde. UND DAS KANN JA ÜBERALL SEIN. >>Beim Sprung in den Interrupt Handler werden weitere Interrupts abgeschaltet, >>beim "reti" werden sie wieder aktiviert... weiss ich, das "wieder aktivieren" ist das Problem
@ Peter Dannegger: ich glaub das mit dem Enablebit ist genau das was ich gesucht habe gibts da irgendwo eine Zusammenstellung der einzelnen Enablebits für die ISR (außer jetzt das ganze Datenblatt zu durchforsten)
ISR wrote: > gibts da irgendwo eine Zusammenstellung der einzelnen Enablebits für die > ISR (außer jetzt das ganze Datenblatt zu durchforsten) Na Du wirst doch wohl wissen, mit welchem Bit Du den Interrupt freigegeben hast. Und mit genau dem gleichen sperrst Du ihn eben. Peter
1) IIRC wird nach dem RETI immer eine Instruktion ausgeführt bevor wieder in eine ISR gesprungen wird. Dein Hauptprogramm kann also nicht verhungern. 2) Normalerweise nimmt man Interrupts für Sachen, die zu wichtig sind um sie einfach mal auszulassen, Beispiel Frequenzzähler: Der würde falsche Werte anzeigen. 3) Wenn du genaue Kontrolle darüber brauchst, wann deine ISR ausgeführt wird/werden kann, schalt den Interrupt generell ab, mach ne normale Funktion draus, und überprüf einfach an festen Stellen in deiner Main-Schleife das entsprechende Bit, ruf die Methode auf wenn gesetzt.
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.