Hallo allerseits, ich programmiere momentan gerade einen Atmel AT90S2313. In meinem Programm möchte ich gerne eine Interrupt-Routine laufen lassen. Nun stehe ich vor dem Problem, dass ich in der I-Routine eine Programmverzweigung benötige. Hierfür ist es doch erforderlich bestimmte Register per POP & PUSH zu sichern, oder?? Kann mir jemand sagen, wie ich es hinbekomme, dass nach dem Sprung das Programm an der richtigen Stelle abläuft?? Folgenden Code habe ich: int0_handler: in temp, pind sbrc temp, 4 rcall rueck vorwaerts: adiw Messwertl, 1 rcall serout reti rueck: sbiw Messwertl, 1 rcall serout reti Problem: Wenn das Unterprogramm rueck ausgeführt wird, wird nicht die Interrupt-Routine verlassen, sondern bei vorwaerts eingesprungen. Gruß Michi
Hallo Michi, wenn Du in int0_handler einen cal auf rueck machst, dann springt der ret aus rueck auch dorthin wieder zurück. Danach fehlt der reti um wieder ins Hauptprogramm zurückzukehren. Aber wenn ich das richtig verstehe, dann sollte ein rjmp rueck anstelle rcall rueck das machen was Du möchtest. Was retten: Alles das was das Hauptprogramm nicht gewünscht beeinflußt. Also im Detail: - Das Statusregister (da i.d.R. Flags geändert werden) - Alle Register die verwendet werden. Volkmar
Super, vielen Dank. Es funzt. Eine kleine frage habe ich noch. Wie rettet man das Statusregister?? Mit POP SREG ja wohl nicht. Michi
Aus der Erinnerung heraus (habe schon lange nichts mehr mit Assembler gemacht): push r16 in r16, SREG push r16 und dann zum Abschluß: pop r16 out SREG, r16 pop r16 reti Man muß ein Register dafür misbrauchen. Und dieses muß dann vorher gesichert werden, da es verändert wird. Volkmar
Stimmt. Aber was hat das mit C zu tun? :-)
Macht GCC das mit dem Sichern von alleine? Und sichert der dann alles oder nur was man benutzt hat?
GCC macht das alles alleine, soweit er davon weiß. Volkmar
"Soweit er davon weiß" heisst auch, dass er nicht einfach alles sichert(wie etwa Bascom)? Unter welchen Umständen merkt GCC denn nicht, dass die Routine etwas verändert(inline Assembler?)?
Einfach alles sichern würde zuviel Performance kosten. "Soweit er davon weiß" setze ich mit "Solange alles in C geschrieben ist" gleich. D.h. das was GCC selber verursacht ist ihm bekannt und kann er auch sichern. Wenn die ISR komplett in Assembler geschrieben ist, wird man es selber machen müssen. Wenn Du inline Assembler in einer ISR benutzt, bin ich, ehrlich gesagt, überfragt. Zur Not mit einem kleinen Testprogramm selber ausprobieren ;-) Volkmar
Ordentlich benutzter inline asm sollte dem Compiler kundtun, welche Register alle benutzt werden, so daß er auch weiß, was zu retten ist.
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.