Hallo wie kann ich wenn meine ISR zu ende an eine andere Stelle springen, als aus der ich gekommen bin??
Davon ist eher abzuraten. Wenn es denn aber doch sein muss oder von prinzipiellem Interesse ist, muss man sich nur klarmachen, das (je nach Programmiersprache) evtl. gerettete Register, mindestens aber eine Rückkehradresse auf dem Stack sind. Diese kann man manipulieren. Dazu am besten mal den Abschnitt über Interrupts des entsprechenden Prozessors lesen.
pop r16 pop r16 sei rjmp Marke Zweimal pop um die Rücksprungadresse vom Stack zu holen. Das Register ist egal. Ist aber sehr schlechter Stil und kann auch anders gelöst werden. Wenn es nicht nur mal zum Testen oder für's Verständnis ist, solltest du das anders machen.
Das geht nur indem Du in Assembler die Rücksprungadresse manipulierst, aber das ist selten eine gute Idee. Beschreib einmalwarum Du das benötigst, dann findet sich möglicherweise eine andere Lösung.
Wenn in einer bestimmten Zeit kein Interrupt ausgelöt wurde soll etwas passieren. Wird aber doch ein Interrupt ausgelöst soll er natürlich nach beendigung des Interrupts sofort aufhören in der delay funktion rum zutrödeln. Wenn das mit dem Stack schlecht ist dann muss es doch noch ne andere Lösung geben.
>Wird aber doch ein Interrupt ausgelöst soll er natürlich nach >beendigung des Interrupts sofort aufhören in der delay funktion rum >zutrödeln. Da ist genau der Knackpunkt. Ein Delay wird ja nur angewendet, weil es nötig ist. Ein Delay wiederrum, das abgebrochen werden kann, weil ein Interrupt auftritt deutet auf einen Designfehler hin. Oder darauf, das Du im Programm sonst nicht weisst was Du machen sollst. ;-) Schreib doch mal wozu das Delay da ist?
Oh, tschuldigung, ich habe den ersten Teil der Antwort nicht richtig gelesen. Das Delay ist also da, zu warten "ob" was passiert. Richtig? Das machst Du dann aber am besten nicht mit einem Delay sondern mit einem Timer. Wenn der Timer abgelaufen ist, ohne das ein Interrupt kam, dann "passiert was". Falls der Timer noch nicht abgelaufen war, als der Interrupt kam, dann den Timer anhalten.
Ja du hast mich anscheinend richtig verstanden. Das mit dem Timer werde ich mal ausprobieren. Hört sich gut.
Ich würde das wohl so lösen:
1 | volatile char flag; |
2 | unsigned int i; |
3 | |
4 | /* Und dann in der Schleife */
|
5 | flag = 1; i = 1000; |
6 | |
7 | while(flag && i) i--; |
8 | |
9 | if (i) /* Interrupt ausgelöst */; |
10 | else /* Interrupt nicht ausgelöst */; |
flag wird in der Interruptroutine auf 0 gesetzt (deshalb volatile). Der Wert von 1000 ist natürlich nur ein Beispiel.
@Matthias Lobitz (mcl024) >Wenn das mit dem Stack schlecht ist dann muss es doch noch ne andere >Lösung geben. Gibt es, Multitasking und Timer MFG Falk
So ist es richtig:
> Ein Delay ... deutet auf einen Designfehler hin.
Dieses Zitat ist zwar etwas zusammengestückelt und aus dem Zusammehang
gerissen, gewinnt dadurch aber an Anschaulichkeit.
Ein Delay gibt es in meinen Programmen bestenfalls im us-Bereich, bei
Zugriffen auf Hardware (z.B. LCD...). Wozu sollte ich einen uC kaufen,
ihn mit Strom und einem Takt versorgen und ihn dann NICHTS tun lassen?
Dann könnte ich ihn ja gleich schlafen legen... ;-)
Mach eine Hauptschleife, die immer mit Vollgas durchlaufen wird. Und in
dieser Hauptschleife wird immer nur geschaut, ob was zu tun ist.
Bestenfalls für Designstudien und die Quick-And-Dirty Methode taucht
dann schon mal ein delay_ms() auf.
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.