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
Ü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.
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.
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 ....
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
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 ...
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.
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...
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.
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...
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
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.
Dei HW ist ein MSP430F2410. Das Problem ist glaub ich nicht den Pin zu toggeln, sondern -was ich zu Beginn etwas in den Hintergrund gelassen habe- die Daten über den UART zu versenden.
Switch schrieb: > Dei HW ist ein MSP430F2410. Das Problem ist glaub ich nicht den Pin zu > toggeln, sondern -was ich zu Beginn etwas in den Hintergrund gelassen > habe- die Daten über den UART zu versenden. Die Daten mit 1us genau über UART verschicken?
Genau. Timer Tick (t= x), Daten versenden (t = x +/- 3µs), Pin Toggeln (t = x +/- 3µs). x = Zeit in ms.
Das ist die zulässige Genauigkeit. Besser ist natürlich +/- 0. Und ob ein "-" Eintritt ist eine andere Sache.
Welche Baudrate benutzt Du denn? Kann Deine UART überhaupt auf 3µs genau starten? Manche UARTs haben einen durchlaufenden Baudratenteiler und können nur auf ganze Bitzeiten starten, d.h. alle 104µs bei 9600Baud. Peter
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. ;)
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
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.