Forum: Mikrocontroller und Digitale Elektronik ISR-Rücksprung


von Oliver (Gast)


Lesenswert?

Hallo,
Ich habe leider das Problem, dass mein Assembler-Code (>10KB) auf
meinem  ATMega16 spinnt, sobald in der Nähe der ISR's auch nur noch
ein einziger NOP-Befehl hinzukommt. Ich habe eingesehen, dass ich jetzt
wohl den mühsamen Weg gehen muss und den ganzen Code auf korrekte
Rücksprünge usw. kontrollieren muss (kein ret nach jmp usw.).
Ich habe auch schon eine Stelle gefunden, welche ein Problem darstellen
kann: In einer ISR will ich am Ende erzwingen, zu einem bestimmten Punkt
im Hauptprogramm zurückzuspringen. Das mache ich zur Zeit mit:
...
sei
jmp loop
...
Ich weiß, eigentlich sollte ich am Ende mit "reti" rausspringen, weil
die Rücksprungadresse noch im Stack gespeichert ist. Gibt es eine
Möglichkeit das eleganter zu machen? Kann ich vielleicht irgendwie eine
fest definierte Rücksprungadresse auf den Stack pushen und wenn ja, wie
geht das?
besten Dank im Voraus,
Oliver

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

.

  "In einer ISR will ich am Ende erzwingen, zu einem
  bestimmten Punkt im Hauptprogramm zurückzuspringen."

Wozu macht man sowas?

von Peter Dannegger (Gast)


Lesenswert?

Ja, die Frage taucht regelmäßig auf, aber eben nur bei Anfängern.

Dein Hauptproblem ist eine nicht durchdachte Programmplanung.

Ein Interrupt wird nicht innerhalb des Kontextes aufgerufen, sondern
völlig willkürlich. Deshalb kann er nunmal nicht zum Kontext
zurückkehren.

Und deshalb muß Dein Programm crashen.


Wenn  es gar nicht anders geht, kann man ein Flag setzen, welches in
den jeweiligen Funktionen getestet wird und diese dann vorzeitig
verläßt, bis Du schließlich regulär im gerade aktiven Aufrufbaum an der
gewünschten Stelle angekommen bist und dort das Flag wieder löschst.

Einzige Ausnahme ist der Sprung ausm Interrupt nach 0000
(Software-Reset), d.h. alle Variablen, Peripherie und der Stack werden
wieder neu initialisiert.
Oftmals wird aber kein Sprung gemacht, sondern der Watchdog gestartet
und gewartet, bis er abläuft, dann sind auch sämtliche IO-Register
resettet.


Peter

von Oliver (Gast)


Lesenswert?

@Rufus
Mein Programm besteht aus 12 Unterprogrammen, welche jeweils eine
Endlosschleife haben. Nur ein Interrupt (ext Int0) kann ein Wechsel von
einem zum anderen Unterprogramm erzwingen, indem ich in seiner ISR das
anzuspringende Unterprogramm adressiere und dann im Hauptprogramm mit
dem ICALL-Befehl dahinspringe.
Das ganze ist also eine Menüsteuerung, welche mittels
Interruptauslösenden Taster realisiert ist. Ich habe es daher gemacht,
weil das Gerät zusätzlich mit diesem Interrupt aus dem Power Save Mode
geholt werden soll.

von Jadeclaw (Gast)


Lesenswert?

Ist trotzdem Murks.
Da es Endlosschleifen sind, sollte es kein Problem sein, im
Interrupthandler die Tastennummer abzulegen, mit RETI da rauszugehen
und in der Programmschleife dann anhand der Tastennummer den Wechsel
auszulösen.
Für solche Aktionen hat der ATmega aber auch einen Speziellen Befehl:
ICALL

Gruss
Jadeclaw.

von Oliver (Gast)


Lesenswert?

Das sehe ich auch ein und bin auch schon gewillt mein Programm
dahingehend zu ändern. Aber kann diese Geschichte auslöser für mein
Problem sein (ein NOP zuviel in der ISR und die Kiste macht nicht mehr
das was sie soll)?
Oliver

von Jadeclaw (Gast)


Lesenswert?

Sie ist es.

Gruss
Jadeclaw.

von Oliver (Gast)


Lesenswert?

OK, dann mach ich mich mal an die Arbeit! Alle ISRs erhalten ordentliche
RETIs am Ende. Falls das schlußendlich mein Problem nicht gelöst haben
sollte, lasse ich diesen Thread wieder aufleben.
besten Dank für Eure Hilfe!
Oliver

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
Noch kein Account? Hier anmelden.