Guten Tag, ich bin noch relativ neu in der Mikrocontroller Welt, und habe einen Frage. Ich habe bis jetzt bei Zeitgeschichten in meiner Interrupt Routine (Zeitbasis von 1ms) immer Globale Variablen hoch oder runtergezählt und dann in der main bei erreichen der Zeit die entsprechende Aktion ausgeführt. Nun habe ich in einem Programm gesehen das dort in der Interrupt Routine die Funktion Timer_Tick aufgerufen wird. In dieser "Magischen Funktion" werden dann die Zeitsachen gemacht. Ist dies die sauberer Lösung? Wie sieht diese Funktion aller Wahrscheinlichkeit aus? Durfte diese Funktion nicht sehen:-( Ist das eine Gängige Methode? Lg Hubert
Das kann man so nicht sagen, ob das die sauberere Lösung ist. Da du den Sourcecode von Timer_Tick() nicht gesehen hast, vermute ich mal das die Funktion Bestandteil einer fertig compilierten Fremdbibliothek ist, vielleicht eines OS. Die Interrupt Routine fungiert in diesem Fall nur als Wrapper für Timer_Tick(). Eigene Zeitaufgaben kannst du natürlich direkt in die Interrupt Routine setzen. Das ist völlig egal. Da Timer_Tick() sowieso in den meisten Programmen nur einmal referenziert wird, wird der Compiler ohnehin den Code aus Timer_Tick() direkt in den Interrupt Handler einsetzen. Worauf du achten solltest falls du den Systick Interrupt als Zeitgeber verwendest: Dieser hat in der Regel ein sehr hohe Priorität. Langer rechenintensiver Code ist hier tabu. Im Idealfall zählst du wirklich nur eine Timervariable hoch und machst den Rest dann außerhalb des Interrupt Handlers.
In dieser Funktion (sehe das C Programm)generiere ich Zeit Flanken: void InterruptLow(void) __interrupt 2
hubert schrieb: > Ich habe bis jetzt bei Zeitgeschichten in meiner Interrupt Routine > (Zeitbasis von 1ms) immer Globale Variablen hoch oder runtergezählt Das ist ein No-Go. Stattdessen eine Variable (z.B. int SysTicker) hochzählen. Das gibt es teilweise sogar in der Hardware des Prozessors. > Nun habe ich in einem Programm gesehen das dort in der > Interrupt Routine die Funktion Timer_Tick aufgerufen wird. In dieser > "Magischen Funktion" werden dann die Zeitsachen gemacht. In einem preemptiven RTOS ist sowas z.B. ganz normal. > Ist dies die sauberer Lösung? dort noch mehr Variablen zu zählen eher nicht. Aber z.B. mit einem RTOS (das dieses Händling relativ effizient und allgemein umsetzt) oder für Dinge, die wirklch (fast) jede ms getan werden müssen (z.B. ADCs, Tasten oder Messages Pollen) > Wie sieht diese Funktion aller Wahrscheinlichkeit aus? Bei einem RTOS: Scheduler aufrufen, Alle häufig zyklischen Dinge aufrufen (Tastatur, ADC, ...), SysTicker++,
Achim S. schrieb: > hubert schrieb: >> Ich habe bis jetzt bei Zeitgeschichten in meiner Interrupt Routine >> (Zeitbasis von 1ms) immer Globale Variablen hoch oder runtergezählt > Das ist ein No-Go. Stattdessen eine Variable (z.B. int SysTicker) > hochzählen. Und nur mit Zeitdifferenzen arbeiten. Dann ist auch der Überlauf kein Problem mehr (siehe z.B. millis() beim Arduino: http://playground.arduino.cc/Learning/BlinkWithoutDelayDe) > für Dinge, die wirklch (fast) jede ms getan werden müssen (z.B. ADCs, > Tasten oder Messages Pollen) Lustigerweise sind genau diese Beispiele Sachen, die nicht unbedingt exakt im ms Zeitraster passieren müssen und deshalb locker auch über ein Flag oder den ms-Zähler in der Haupschleife abgearbeitet werden könnten. Wir packen das nur deshalb so gern in den Timerinterrupt, weil wir selber dieses "Uhrendenken" haben: Mittags um 12 geht es in die Kantine zum Essen. Dabei wäre es doch sinnvoller, dann zum Essen zu gehen, wenn wir Hunger haben...
:
Bearbeitet durch Moderator
Ich verwende jeweils einen timer Interrupt, der einiz reloadet, und das Timer-Came flag setzt. In der Main wird mit dem Timer-Came verzweigt und Sekundaere Zaehler gezaehlt. Etwa : interrupt timer { timercount= 192; // fuer 1ms oder so. timercame=1; } main () { .. loop if timercame==1 { .. timercame=0; }
Sapperlot W. schrieb: > Ich verwende jeweils einen timer Interrupt, der einiz reloadet, und das > Timer-Came flag setzt. In der Main wird mit dem Timer-Came verzweigt und > Sekundaere Zaehler gezaehlt. Halte ich allgemein für keine gute Idee. 1. ist die ISR auch nicht komplizierter, wenn sie bloß eine Variable hochzählt 2. Falls in der Main mal eine Aktion länger, als z.B. 1 ms dauert, geht die Uhr nach. 3. Da kannst Du Dir die ISR auch gleich sparen und in der Main das Hardware-Timerflag direkt auswerten und ggf. rücksetzen, statt ein Software-Timerflag einzuführen.
:
Bearbeitet durch User
Thomas E. schrieb: > Halte ich allgemein für keine gute Idee. Korrekt: wenn die Hauptschleife mal länger als 1ms dauert, dann geht auf diese Weise Zeit verloren. Ein Flag setzen und wieder zurücksetzen ist so ähnlich wie ein sättigender 1-Bit-Zähler, der in der ISR hoch- und in der Hauptschleife heruntergezählt wird. Durch das explizite Setzen und Zurücksetzen ist lediglich das Semaphorenproblem umgangen... Fazit: die sicherste Methode ist, nur in der ISR hochzuzählen, und in der Hauptschleife nur zu lesen.
Lothar M. schrieb: > Lustigerweise sind genau diese Beispiele Sachen, die nicht unbedingt > exakt im ms Zeitraster passieren müssen und deshalb locker auch über ein > Flag oder den ms-Zähler in der Haupschleife abgearbeitet werden könnten. Stimmt. Meine Beispiele machen nur dann Sinn, wenn die hauptschleife (manchmal) deutlich über 10ms liegt. Und die Kosten separater Interrupts hoch sind.
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.