Forum: Mikrocontroller und Digitale Elektronik Timer_Tick()


von hubert (Gast)


Lesenswert?

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

von Sebastian K. (sek)


Lesenswert?

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.

von B. P. (skorpionx)


Angehängte Dateien:

Lesenswert?

In dieser  Funktion (sehe das C Programm)generiere ich Zeit Flanken:
void InterruptLow(void) __interrupt 2

von A. S. (Gast)


Lesenswert?

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++,

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

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
von Pandur S. (jetztnicht)


Lesenswert?

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;
    }

von Thomas E. (picalic)


Lesenswert?

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
von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

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.

von A. S. (Gast)


Lesenswert?

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
Noch kein Account? Hier anmelden.