Hallo habe eine Frage zum Programmablauf. Ich programmiere den µC mit Assembler und nutze einen TimerOverflow-Interrupt zum auslösen verschiedener Ereignisse, wie z.B. Berechnungen, Anzeige aktualisieren etc. z.B. Aktualisieren der Anzeige alle 7 Overflows (7*5ms). etc. Das hat zur Folge, das die Hauptschleife bei mir wie folgt ausschaut. main: nop rjmp main: Ist der Weg richtig, falsch - was kann man besser machen. Prinzipiell funktioniert es so sehr gut - aber ich frage mich, ob das auch so in der Praxis gehandhabt wird.
... wenn's funktioniert... Es kommt halt darauf an, ob manche Sachen zeitkritsch sind, oder nicht. Ein Problem per Interrupts zu lösen kann 1A funktionieren, sich aber auch gerne irgendwo aufhängen. Es geht nicht darum, dass irgendwas in der Main steht, sondern darum, dass das Programm stabil läuft. Mit Interrupts ist man IMHO auf der besseren Seite als wenn man ne Menge Schleifen benutzt, wo der Controller eigentlich auch nichts macht ausser warten...
besser ist das so: void timer_isr () {timer_tic=1; } main () {while (!timer_tic); timer_tic=0; //deine anderen sachen } Scheinbar das gleiche - aber nicht ganz. Der Vorteil ist, dass während der Abarbeitung andere Interrupts aktiv bleiben. Erledigst du alles in der timer_isr ist das nicht der Fall. @ahul: "Ein Problem per Interrupts zu lösen kann 1A funktionieren, sich aber auch gerne irgendwo aufhängen. Es geht nicht darum, dass irgendwas in der Main steht, sondern darum, dass das Programm stabil läuft. Mit Interrupts ist man IMHO auf der besseren Seite als wenn man ne Menge Schleifen benutzt, wo der Controller eigentlich auch nichts macht ausser warten..." - was ist denn das für eine Aussage?
Hi ich würde den INT so kurz wie möglich halten und in der Hauptschleife dann alles was nicht absolut zeitkritisch ist erledigen. Im Timer-INT wird dann nur ein Flag gesetzt oder sogar nur ein Timestamp hochgezählt. Matthias
Der Timestamp hört sich gut an. An die anderen Interrupts habe ich nicht gedacht ;-) Also, Timestamp hochzählen, und in der main schleife Timestamp auswerten und dort die entsprechenden Funktionen aufrufen. Dankeschön
> Scheinbar das gleiche - aber nicht ganz. Der Vorteil ist, dass > während der Abarbeitung andere Interrupts aktiv bleiben. Erledigst > du alles in der timer_isr ist das nicht der Fall. Einfach ein sei am Anfang der ISR hätte das gleiche Ergebnis. @Thomas: Du kannst das nop in main auch durch ein sleep ersetzen, wenn du vorher den passenden Sleepmodus aktiviert hast. Dann braucht der uC weniger Strom. Dafür steigt die Reaktionszeit auf die Interrupts etwas an.
Hi @Thomas P. Genau so. @Rolf Wenn es sich irgendwie verhindern läßt sollte man das nicht machen. Wenn der selbe INT zu schnell kommt ruft er sich selber auf was dann zum Programmabsturz führt (Stacküberlauf). Im INT erledigt man wirklich nur die eiligen Sachen und alles andere in aller Ruhe im main-loop. Matthias
"Einfach ein sei am Anfang der ISR hätte das gleiche Ergebnis." das ist ein Trugschluss - ganz so einfach ist das nicht. 1. müssen normalerweise diverse Sachen gesichert werden, für das sreg z.B. nehme ich gerne ein Register, dass ausschlisslich für diesen Zweck reserviert ist (kann man in allen ISR dasselbe verwenden, solange nicht ein Int einen anderen unterbricht(!). 2. Mehrfach-interrupts können den stack belasten - vielleicht sogar ein wenig zuviel. Kommt natürlich auf das Programm, Stackgrösse und Anzahl der max. gleichzeitig möglichen Ints an. Ist es theoretisch möglich, dass der Stack überläuft, wird es irgendwann auch passieren. Hauptsächliches Problem dabei: scheinbar unwesentliche kleine spätere Änderungen können das Programm instabil machen -da suchst du dir einen Wolf. Ohne Not: niemals.
@Rolf "Einfach ein sei am Anfang der ISR hätte das gleiche Ergebnis." Na dann mach das mal im UART-, EEPROM-, TWI-, externen Level-Interrupt: Sssst und schon ist der Stack übergelaufen. Sachen, die man in der Mainloop machen kann, haben den Vorteil, daß man keinerlei Register sichern muß, sind also codesparend. Interrupthandler müssen dagegen alles sichern, was sie verändern. Man sollte nicht leichtfertig Ausführungsebenen verschenken. Peter
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.