Hallo Leute, hab wieder mal eine Frage zu Assembler. Wie kann ich das hinbekommen dass bei einem Interrupt dieser auf keinen Fall zwischen diesen beiden Programmzeilen ausgeführt wird , jedoch falls einer auftritt nicht ignoriert wird. ..................... SUB R16 , R28 'Subtract without carry SBC R17,R29 'Subtract with carry .................... Sinn und Zweck ist dieser: R28 u. R29 werden in der Interruptroutine verändert also ist es möglich dass dadurch das Ergebnis der Subtraktion falsch wäre. Vielen dank für Eure hilfe im Voraus Gruss Gerhard
Davor Interrupts sperren, danach freigeben. Bei fast allen Interrupts wird der Interrupt danach dann ausgelöst, falls er dazwischen auftrat. Eine Ausnahme wäre ein rein level-triggered interrupt, der so kurz war, daß das entsprechende (externe) Signal danach schon wieder weg war. ;-)
Interruptroutinen sollten aber keine Register verändern, die anderweitig benutzt werden, es sei denn, die liefern in diesen irgendwelche Ergebnisse ab, dann wäre der Weg mit cli und sei richtig. Ansonsten lieber mit push und pop arbeiten, alles sichern, was sich während der ISR ändert. Das macht sich spätestens beim update des Programms in einem Jahr bezahlt, wenn du selbst nicht mehr genau weist, was du da früher programmiert hast.
Hi danke für eure rasche hilfe @Joerg scheint so zu funzen obwohl es sich um rein level-triggered Interrupts handelt. Es werden INT0 und INT1 sowie ein Timer der als Zähler konfiguriert ist abgefragt. Kommt es da auch auf die steilheit der Schaltflanke an ?? @ crazy horse wenn ich mit push u. pop arbeite und die werte sichere dann kann ich doch nicht mit den geänderten werten nach der ISR weiterarbeiten. die werden ja durch das "popen" wieder überschrieben. Ist es eigendlich möglich einen bestimmten programmteil so zu definieren als wäre es eine ISR , also dass da kein Interrupt eingreifen kann sondern sich hinten anstellen muss ? Danke, Gruss Gerhard
habe ich ja geschrieben, wenn die ISR Ergebnisse in den Registern abliefert, macht push und pop natürlich keinen Sinn. Und zu deiner 2.Frage: das wird genauso gehandhabt. Am Beginn eines Unterprogramms schreibst du start_up1: cli //alle ints werden gesperrt . . . ende_up1: sei //ints werden wieder freigegeben ret
werde das mal testen. bin gespannt ob das geht, denn es darf auf keinen Fall ein Interrupt "übersehen " werden . Danke , Gerhard
> Kommt es da auch auf die steilheit der Schaltflanke an? Nein, beim pegelgetriggerten Interrupt zählt nur der Pegel. Die AVR-Eingänge haben ja ohnehin Schmitt-Trigger drin. Bei Pegeltriggerung hättest Du damit nur ein Problem, wenn direkt nach dem CLI der zum Interrupt führende Pegel am Eingang eintrifft, dieser Pegel aber bereits beim SEI wieder verschwunden ist. Mit Deinen beiden Befehlen dazwischen wären das also effektiv drei Prozessortakte, die das Signal kurz sein müßte, um keinen Interrupt auszulösen. Wahrscheinlich wäre es ohnehin besser, derart kurze Nadeln zu ignorieren. ;-) Diese Funktionsweise ist dadurch bedingt, daß bei Pegeltriggerung der externe Pegel unmittelbar für die Interruptauslösung genutzt wird, d. h. er wird nicht z. B. in einem Flip-Flop zwischengespeichert. Nur so ist es möglich, daß ein pegelgetriggerter externer Interrupt den Prozessor auch aus dem völligen Tiefschlaf (Takt abgeschaltet) wieder wecken kann. Praktisch alle internen Interrupts jedoch sind flankengetriggert, d. h. beim Eintreffen des Interrupt-Ereignisses wird ein Flip-Flop gesetzt. Wenn in diesem Moment die Interrupts verboten sind, wird der Zustand dennoch gemerkt, und der Interrupt wird ausgelöst, sowie es wieder möglich ist. Irgendwann danach wird dann das Flip-Flop (meist durch die Hardware selbst; Ausnahme: TWI) wieder gelöscht. Ansonsten aber nur Zustimmung: ISRs sollten keine globalen Register zerstören.
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.