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
. "In einer ISR will ich am Ende erzwingen, zu einem bestimmten Punkt im Hauptprogramm zurückzuspringen." Wozu macht man sowas?
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
@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.
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.
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
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.