Timer-Überläufe handeln

Gast #2065823
Lesenswert?

Hallo!

Ich habe mal eine ganz grundlegende Frage zum Thema Timer.
Von einem Zeitpunkt 0 brauche ich mehrere Timer. Bei einem Takt von 1 
Mhz und 16 Bit Timer habe ich also eine Auflösung von 65.535ms. Wenn ich 
jetzt aber z.B. 550ms brauche, muss ich also die Überläufe zählen.

Jetzt weiß ich nicht, wie ich das am besten Implementieren soll.

Könnt hier mir einen Tipp geben?

Viele Grüße
Switch
#2065848
Lesenswert?

Üblicherweise stellt man den Timer so ein, dass er einen Überlauf 
generiert mit einem günstigen Zeitintervall z.B. 1 ms oder 10 ms.
Dann zählt man die Überläufe, z.B. in dem der Timer bei jedem Überlauf 
einen Interrupt auslöst, und in der ISR wird ein Zähler hochgezählt.
Das Hauptprogramm wartet dann, bis der Zähler den gewünschten Stand hat.
Moderator Persönliche Seite #2065851
Lesenswert?

Switch schrieb:

> Wenn ich
> jetzt aber z.B. 550ms brauche, muss ich also die Überläufe zählen.
>
> Jetzt weiß ich nicht, wie ich das am besten Implementieren soll.

Für bspw. einen AVR etwa so:
1
#include <stdint.h>
2

3
volatile uint16_t timer_overflow;
4

5
ISR(TIMER1_OVF_vect)
6
{
7
  timer_overflow++;
8
}

Nicht vergessen, dass Zugriffe auf timer_overflow aus dem main
thread nicht atomar sind!  Du musst also für einen Zugriff dort
die Interrupts blockieren, den Wert der Variablen lesen oder
vergleichen und danach die Interrupts wieder freigeben, andernfalls
ist nicht garantiert, dass low- und high-Byte von timer_overflow in
einem konsistenten Zustand gelesen werden.

Auf einer 32-bit-Architektur hättest du dieses Problem natürlich
nicht, da wäre ein 32bittiger Zugriff noch atomar.
Gast #2065930
Lesenswert?

Hallo!

Bei einem MSP sollte dann auch ein 16bit Zugriff atomat sein.

Das Problem ist, wenn sich Timer-Interrupts überlappen, den beim MSP 
haben die Timer B1 bis B7 den gleichen Interrupt-Vektor...
Wenn alle einen 10ms-Takt hätten würden ja alle zeitgleich kommen. Dann 
brauch ich aber bei einem 5 Überläufe der andere 11. Und was ist, wenn 
ich kein ganzzahliges Vielfaches von dem Timer habe. Z.B. 234ms, das 
wären ja dann 23 Überläufe + 4ms ....
#2065997
Lesenswert?

Switch schrieb:
> Bei einem MSP sollte dann auch ein 16bit Zugriff atomat sein.

Daher sollte man immer als erstes auch den CPU-Typ angeben.


Switch schrieb:
> Das Problem ist, wenn sich Timer-Interrupts überlappen, den beim MSP
> haben die Timer B1 bis B7 den gleichen Interrupt-Vektor...

Das ist ja doof.
Man hat oft Anwendungen mit mehreren Timern, wo einer sauschnell sein 
muß und nur wenig zu tun hat und andere viel machen müssen, aber 
seltener kommen.
Bei verschiedenen Vektoren kriegen beide unterschiedliche Prioritäten 
und kommen sich dann nicht in die Quere.

Aber bei nur einem Vektor - keine Ahnung, wie man das lösen kann.


Peter
Gast #2066011
Lesenswert?

Der Timer B0 hat einen eigenen Vektor mit einer höheren Priorität als B1 
bis B7.
Deswegen habe ich gedacht das ich den als Mastertakt nehme. Also das der 
dann 10ms Zyklus hat.
Aber dann habe ich das Problem, dass wenn ich ein ganzzahliges 
vielfaches habe, das der Timer B0 eher ausgeführt wird, als der 
eigentlich wichtige.

Das ist irgendwie alles nicht so einfach ...
#2066086
Lesenswert?

Switch schrieb:
> Das Problem ist, wenn sich Timer-Interrupts überlappen, den beim MSP
> haben die Timer B1 bis B7 den gleichen Interrupt-Vektor...
> Wenn alle einen 10ms-Takt hätten würden ja alle zeitgleich kommen. Dann
> brauch ich aber bei einem 5 Überläufe der andere 11. Und was ist, wenn
> ich kein ganzzahliges Vielfaches von dem Timer habe. Z.B. 234ms, das
> wären ja dann 23 Überläufe + 4ms ....

Du kannst/solltest nicht für jede Wartezeit einen eigenen Timer 
spendieren!
Ein Timer mit z.B. 1 ms genügt, der zählt meinetwegen verschieden Zähler 
und im Hauptprogramm werden die einzelnen Aufgaben erledigt!

Nur für ganz zeitkritische Aufgaben die sich in kürzester Zeit erledigen 
lassen, kann man Timer mit eigenen ISRs aufsetzen.
Gast #2066698
Lesenswert?

IMHO keine optimale Lösung. Da der zeitliche Ablauf von der Main-Loop 
abhängt. Wenn ein Timer "anschlägt" sollen auch gleich die Pins 
getoggelt werden. Am Besten mit Verzögerung t=0. Da das ja nicht geht, 
werde ich die Zeit messen, die der Controller vom Timer-Tick bis toggeln 
Pin benötigt und diese beim Setzen des Timers als Offset abziehen...
#2066922
Lesenswert?

switch schrieb:
> IMHO keine optimale Lösung.

'Optimal' gibt es in der Kirche.
Da darf man sich was wünschen.

> getoggelt werden. Am Besten mit Verzögerung t=0. Da das ja nicht geht,
> werde ich die Zeit messen, die der Controller vom Timer-Tick bis toggeln
> Pin benötigt und diese beim Setzen des Timers als Offset abziehen...

Welche Zeitvorgaben musst du denn einhalten?

PS: Wenns wirklich nur Pin-Toggeln ist ... das darf auch gerne in der 
ISR erledigt werden. Aber die meisten wollen ja erst mal 200 
quadratische Gleichungen lösen, das erste Buch Genesis über die UART 
ausgeben und auf dem Grafik-LCD soll ein Packman die Punkte wegfressen. 
Das ist dann schon zuviel, als das man es in der ISR erledigen kann.

Ändert nichts daran, dass man nur 1 Timer braucht.
Gast #2067047
Lesenswert?

Karl heinz Buchegger schrieb:
> 'Optimal' gibt es in der Kirche.
>
> Da darf man sich was wünschen.

SWR nicht vergessen! - "Sie wünschen, wir spielen!" ;)

Karl heinz Buchegger schrieb:
> Welche Zeitvorgaben musst du denn einhalten?

Eine 1µs maximal 3µs Jitter.

Karl heinz Buchegger schrieb:
> PS: Wenns wirklich nur Pin-Toggeln ist ... das darf auch gerne in der
>
> ISR erledigt werden. Aber die meisten wollen ja erst mal 200
>
> quadratische Gleichungen lösen, das erste Buch Genesis über die UART
>
> ausgeben und auf dem Grafik-LCD soll ein Packman die Punkte wegfressen.
>
> Das ist dann schon zuviel, als das man es in der ISR erledigen kann.

Bin für die Bibel über den UART. Ok, die Bibel ist etwas stark 
komprimiert. Reden wir mal von 255 Bytes. Das begrenzt natürlich die 
Zeitspanne zwischen zwei Ticks. Mindestabstand 255 Bytes * 11 
Bits/Bytes/Datenrate + ein wenig Latenzzeit zum Betreten und Verlassen 
der ISR.

Damit ist aber auch das Thema "Zählen" der Überläufe und abhandeln der 
Timerzeiten mit einem Timer hinfällig...
#2067086
Lesenswert?

switch schrieb:
> Am Besten mit Verzögerung t=0. Da das ja nicht geht,

Warum geht das nicht?
Hat denn der MSP keine Output-Compare Funktion?

Bei den AVRs kann man die Compare-Ausgänge zyklusgenau (50ns) setzen, 
löschen oder togglen.


switch schrieb:
> werde ich die Zeit messen, die der Controller vom Timer-Tick bis toggeln
> Pin benötigt und diese beim Setzen des Timers als Offset abziehen...

Die Interruptlatenz kann man nicht so einfach abziehen, da sie nicht 
konstant ist (laufende Operation, andere Interrupts).


Peter
#2067094
Lesenswert?

switch schrieb:
> Wenn ein Timer "anschlägt" sollen auch gleich die Pins
> getoggelt werden. Am Besten mit Verzögerung t=0.

So etwas geht manchmal schon.
Manche Timer haben dazu einen dedizierten Ausgang, der von der Hardware 
gleichzeitig gesetzt wird, wenn der Timer überläuft.
Bei längeren Zeiten muss man dann halt tricksen.
z.B. Wartezeit 250 ms:
Der Timer wird auf 10 ms Überlauf eingestellt.
In der ISR wird bis 24 gezählt, und beim 24. Mal wird der Ausgang 
aktiviert.
Beim 25. Mal Überlauf knallts dann.
Vorteil auch: Die Reaktionszeit der ISR ist nicht kritisch, man muss nur 
in den 10 ms zwischen 24. und 25. Überlauf den Pin aktivieren.
Aber das alles hängt von Deiner Hardware ab und man kann eben nur 
bestimmte Pins dazu verwenden.
Gast #2067315
Lesenswert?

Wie soll ich das Verstehen.
Wenn mein Timer Tick eintritt, dann werden die Daten in den UART 
Sendepuffer verschoben.
Beim MSP befindet sich die UART Statemachine im IDLE-Mode. D.h. wenn ich 
mit meinem ersten Byte komme, wird es ausgetaktet.

Die Baudrate soll mindestens 500kBaud betragen. Je schneller, desto 
besser. ;)
#2067326
Lesenswert?

Switch schrieb:
> Wie soll ich das Verstehen.

Z.B. beim 8051 ist der Baudratenteiler durchlaufend.
Man schreibt in den Sendepuffer und dann kommt das Startbit mit der 
nächsten Flanke des Baudratenteilers. Wo der Baudratenteiler gerade 
steht, weiß man nicht.
Nach dem Senden eines Bytes folgt das nächste Byte also immer nach n * 
Bitzeit.

Ob das beim MSP auch so ist, sollte in dessen Datenblatt stehen.


Peter

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren