Ressourcen-Icon

Board 1 - Teil 3 Anwendung und Berechnung von 8 und 16 Bit Timer 2019-01-13

Hallo nochmal,

hier hatte ich mal versucht, etwas Übersicht in die Timer-Betriebsmodi zu bringen (da war's 'n Mega8, aber generell sind die ja alle ähnlich - abgesehen vielleicht von teilbaren Timern, vielleicht den 12bit-Timern, und PWM-6-Mode Timern).
Ein paar Beiträge vorher hatte ich auch die Register des Timers "auseinandergenommen"...

Du läßt (schreibst Du ja selbst) die PWM-Modi außen vor - und damit insbesondere auch die dual-Slope-Modi.

Timer2 kann außerdem asynchron zum Systemtakt mit einem eigenen Quarz an den TOSCs getaktet werden.
 
achim S. aktualisierte Mikrocontroller und I2C Bus Board 1 Teil 3 Timer mit einem neuen Eintrag:

Bord 1 - Teil 3 Timer Berechnung und Anwendung von 8 und 16 Bit Timer

Die Berechnung und Anwendung von Timern mit 8 Bit und 16 Bit ist für viele ein Problem. Leider gibt es keine genaue Erklärung in deutsch mit einer genauen Anleitung zur Berechnung. In diesem Teil erkläre ich es Schritt für Schrit wie ich das mache. Jede Rechnung kann an Hand von Beispielen nachvollzigen werden. Es werden auch die verschiedenen Modi erklärt.

Weitere Informationen zur Aktualisierung...
 
Jetzt hab ich doch mal reingelesen...
Also...

Auf S. 3 schreibst Du:
Bei dem AT1284p sind es 4 Timer.
Da würde ich den Controllernamen korrekt ausschreiben - gerade weil Du Dich ja an Anfänger richten willst.

Auf S. 6:
Wie lange es braucht, bis der Zähler einen Overflow auslöst, ist von der Taktfrequenz des Controllers, dem eingestellten Prescaler-Wert und von der Timerauflösung abhängig.
Der Timer selbst hat immer 'ne Auflösung von eins (einem Schritt). Bezogen auf den Systemtakt (an den der Timer ja hier über den Vorteiler gekoppelt wird) bestimmt der Prescaler die Auflösung. Mit der Frequenz des Systemtaktes (Frequenz bzw Takt = reziproke Zeit) kommt jetzt ein zeitlicher Bezug hinzu: die zeitliche Timerauflösung ist(!) also selbst von der Taktfrequenz und dem Vorteiler abhängig. Das "und" da oben paßt nicht.
Damit hast Du aber noch nicht die Zeit "bis der Zähler einen Overflow auslöst" - da fehlt dann nämlich noch die Reichweite des Timers. Bei einem 8bit-Timer (im normal mode) sind das eben genau 28 Timer-Takte.

Nebenbei finde ich "Overflow auslöst" … ungünstig formuliert. Der Timer läuft schlichtweg über, auch ohne da irgendwas auslösen zu müssen (lediglich ein Überlauf-Flag wird gesetzt) - man könnte also von einer Überlauffrequenz oder einer Überlauf-Periodendauer oder so sprechen.

Immer noch auf S. 6 zum CTC:
Dazu wird der Zähler vorgeladen, bevor dieser wieder vom eigentlichen Timer hochgezählt wird.
???
Die primitivsten Timer kannten nur den "normal mode" - über Vorteiler auf den Systemtakt koppelbar, und mit einem interruptfähigen Überlauf. Mit wenigen diskreten Vorteilern sind logischerweise so nur wenige Überlauffrequenzen wählbar - man kann aber nach jedem Überlauf (->Interrupt) den Timer um x Schritte vorstellen, was effektiv die Reichweite des Timers um x Schritte verringert. (Stimmt nicht ganz, da zwischen dem eintreten des Überlaufes und dem setzen des TCNT-Registers weiter Systemtakte verstreichen). Durch das "vorladen" eines Timerwertes (in das Counter Register) nach jedem Überlauf werden salopp gesagt die ersten Timerschritte weggeschnitten. Der Controller wird also bei jedem Überlauf unterbrochen.
Beim CTC (allgemeiner gesagt einem frequenzkorrekten Modus) begrenzt die Timer-Hardware selbst die Reichweite; statt der ersten x Schritte werden hier die letzten weggelassen, weil der Timer vor dem Überlauf auf null zurückgesetzt wird (bzw bei dual-slope-Modi die Richtung ändert). Salopp gesagt werden also die letzten Schritte weggeschnitten, und zwar ohne Interrupt durch die Hardware selbst.
Neben dem Aktivieren des CTC Modus genügt es da-zu, einfach den gewünschten Endwert in ein spezielles Register, das OCR0A, zu laden.
Das muß nicht immer zwingend das OCRnA sein - Timer1 des Mega1284P kann zum Beispiel auch das ICR1 nutzen. Andere Controller besitzen eigene Register zum festlegen der Reichweite - beim ATtiny26 beim Timer0 das OCR0C, beim ATtiny25/45/85 beim Timer1 das OCR1C.
Und natürlich hat auch die ISR dann einen anderen Namen.
Das ist eine Beschränkung, die Du Dir von Deiner Hochsprache auferlegen läßt. Jede (bei einem konkreten Controller mögliche) Interruptquelle hat eine eigene feste (IVT-Remapping durch Bootvektor etc mal außen vor) Adresse im Flash, die beim Eintritt das Interruptes ausgeführt wird. Üblicherweise (aber nicht unbedingt zwingend) wird von dort zur Adresse der Service-Routine weitergesprungen. Welchen Namen Du für diese Adresse jetzt mit Deiner Entwicklungsumgebung vereinbarst (oder Dir von ihr vorschreiben läßt) ist Euer Ding, für den Controller ist nur die Adresse relevant. Insbesondere können auch unterschiedliche Interruptquellen (aus unterschiedlichen IVT-Adressen) dieselbe ISR anhopsen…

Auf S. 7 bist Du irgendwie durcheinandergekommen:
Mit den AVR's können wir direkt PWM-Signale erzeugen. Dazu dient der 16-Bit Zähler, welcher im sogenannten PWM-Modus betrieben werden kann.
Das könnte man jetzt so mißverstehen, daß es nur mit dem 16bit-Timer (wovon der Mega1284P auch noch zwei hat) geht - tatsächlich besitzt beim Mega1284P jeder der vier Timer je zwei PWM-fähige Output Compare Units.
Damit ist das Kapitel PWM bei Dir abgeschlossen, oder wie?

Das folgende Beispiel ist wieder CTC?
Wir wollen mit einem 8-Bit Timer Impulse von 1 ms erzeugen.

Auf S.8 kommst Du rechnerisch auf 250 Schritte, im Codelisting auf S. 9 setzt Du aber das Vergleichsregister (OCR0A) auf 249. Die Erklärung der Differenz hab ich zumindest nicht gefunden. Überlesen?

Nur am Rande: Im konkreten Programm ist es natürlich sinnfrei, im Interrupt ein Flag setzen zu lassen, und dieses dann im Hauptprogramm zu pollen. Man könnte dort auch direkt das Output Compare Flag aus TIFR pollen (und zurücksetzen), ohne den Interrupt zu nutzen.
Da C6 nicht direkt durch den Timer angesteuert werden kann, fällt direkte Manipulation über ein Output Compare Unit raus. Aber elegant geht auch folgendes:
AVR mit so viel Flash besitzen zwingend eine zwei-Word-breite IVT (weil der nötige Sprungbefehl für so große Distanzen zwei Words breit ist). In diese zwei Words passen aber statt des einen Sprungbefehls auch zwei ein-Word-Instruktionen.
Eine zum toggeln von C6 (SBI PINC, C6).
Und eine zur Rückkehr aus der IVT (RETI).
Der CTC muß dann natürlich mit 2Hz triggern.

Auf S. 13:
Der 8-Bit Timer ist so ziemlich am Ende, da ich den Prescaler 1024 verwende. Beim 16-Bit Timer kann ich noch andere Prescaler einsetzen und somit noch grössere Zeiten erreichen.
Bei allen vorhandenen Timern (des 1284P) ist 1024 der größte Prescaler. Längere Zeiten erreicht der Timer insbesondere, weil er eben acht Bit weiter zählen kann, also 256mal so weit. Durch einen höheren Vorteiler verliert man immer an Auflösung.
Übrigens kann man das ganze noch etwas strecken, indem man statt single-slope dual-slope-Modi verwendet. Die entsprechende Berechnung unterstützt aber weder Dirks Programm, noch meine App...

(P.S.: Dein Mega1284P besitzt übrigens einen interruptfähigen Watchdog, Der läßt sich auch (sehr eingeschränkt) wie ein Timer verwenden. Also zumindest zum generieren einer Zeitbasis (mit der Genauigkeit des 128kHz-Oszillators).)
 
Hallo achim S.

Dann aktualisiere bitte auch die Versionshistorie und nimm auch die verwendeten Quellen (vollständiger & korrekter link) in Deinem Pamphlet auf ;)

mfg

Hero_123
 
Hallo achim S.

Dann aktualisiere bitte auch die Versionshistorie und nimm auch die verwendeten Quellen (vollständiger & korrekter link) in Deinem Pamphlet auf ;)

mfg

Hero_123

Es gibt nur 2 Quellen dazu. Beim Datenblatt des Herstellers kann man geteilter Meinung sein und das Programm von Dirk habe ich angegeben. Das Wort Pamphlet hat einen sehr schlechten Beigeschmack. Es geht hierbei um die Technik und die Funktion und nicht die Verbreitung von irgendwelchen Theorien.
achim
 
Dennoch fehlt eine genaue Angabe der Quellen - ich habe in Deinem PDF ( ;)) keinen Hinweis gefunden, dass der Timer Calculator von Dirk ist.
Normalerweise erwähnt man am Ende einer schriftlichen Arbeit die verwendeten Quellen und markiert im Text die den Quellen entnommenen Zitate.
Zumindest kenne ich das so vom Studium.

Es geht hierbei um die Technik und die Funktion und nicht die Verbreitung von irgendwelchen Theorien.

Habe ich nie in Frage gestellt - nix für ungut ;)

mfg

Hero_123
 
Habe angefangen das ganze zu überarbeiten.

Auf S.8 kommst Du rechnerisch auf 250 Schritte, im Codelisting auf S. 9 setzt Du aber das Vergleichsregister (OCR0A) auf 249. Die Erklärung der Differenz hab ich zumindest nicht gefunden. Überlesen?

Wie ich angefangen mit Timern zu arbeiten habe ich eine längere Diskussion im Netz zu führen. Hatte es mit 250 angegeben. Wurde dann hingewisen das es 249 sind. Sollte an der Auflösung mit 0 beinnend liegen bzw. steht im Datenblatt in einer Formel -1 drin. Habe es danach so weiter gemacht.

Auf PWM bin ich nicht eingegangen. Finde das es ein extra Bereich ist und besser ein eigenes Teil bekommt. Auch das
single-slope dual-slope-Modi
habe ich nicht weiter angegeben.
Wenn ich alles berücksichtige was im Datenblatt steht wird es wohl ein Buch werden.
Die Software habe ich damals so verwendet. Werde meine aktuellen Sachen angeben.

Sicher werde ich noch mit einigen Fragen kommen.

achim
 
Sollte an der Auflösung mit 0 beinnend liegen bzw. steht im Datenblatt in einer Formel -1 drin. Habe es danach so weiter gemacht.
Gehen wir erstmal von einem einfachen 8bit-Timer aus. Der Zähler selbst kann 28=256 Werte annehmen. 0..255
Der erste Schritt (wenn man sowas bei einem durchlaufenden Zähler überhaupt sagen kann) ist also der Schritt 0→1, der 255ste ist der Schritt 254→255. Und der zweihundertsechsundfünfzigste ist dann der Schritt danach, 255→0 - der Überlauf eben, wo auch das Überlauf-Flag gesetzt wird.
Und genau dasselbe hast Du konsequenterweise auch bei den Output Compare Units. Der Timer läuft, bis das Vergleichsregister (hier OCRnA) gleich dem Zählerstand (TCNTn) ist, und dann im nächsten Timerschritt auf "0" über. Wenn Du 249 als Vergleichswert festlegst, macht der Timer also 249 Schritte 0→...→249 und einen Schritt 249→0. Zusammen 250. Zitat aus dem Mega1284P-Datenblatt - Timer0 - Output Compare Unit:
The 8-bit comparator continuously compares TCNT0 with the Output Compare Registers (OCR0A and OCR0B). Whenever TCNT0 equals OCR0A or OCR0B, the comparator signals a match. A match will set the Output Compare Flag (OCF0A or OCF0B) at the next timer clock cycle.
Das Compare Flag selbst wird erst einen Schritt nach dem Match gesetzt, triggert erst dann einen IRQ. Also beim CTC exakt im Überlauf/Reset des Zählers.


Wenn ich alles berücksichtige was im Datenblatt steht wird es wohl ein Buch werden.
Das Datenblatt selbst ist quasi ein Buch - zumindest bei einigen Controllern. Timer0 kommt im Datenblatt auf 14 Seiten. Ohne Rechenbeispielen und Beispielprogrammen, dafür aber mit allen Registererklärungen usw.

Was willst Du mit dieser PDF denn eigentlich erklären? Du beginnst mit "Was ist ein Timer?", bringst Erklärungen zu Vorteiler uns Systemtakt.
Danach dann kurz was zum normal Mode und zum CTC (Deinem eigentlichen Ziel - nebenbei mit diesem komischen "vorladen"). Dabei wird aber nirgends auf die Output Compare Units eingegangen (die Du nebenbei auch im Normal Mode nutzen kannst).
Genau solche Comperatoren ermöglichen Dir aber erst den (selbständigen) CTC.

Ich würde, wenn ich einen Timer erklären sollte, wie auch im Datenblatt anfangen - mit einem Blockdiagramm, und dieses dann gedanklich auseinandernehmen.
 
Ob es 249 oder 250 sei erst mal nicht weiter geklärt. Muss noch mal nachschauen was die für einen Grund haben.
Leider versteh ich dein Gedanken nicht so ganz. Findest du es besser wenn man keine Erklärung mit Beispielen zu den einzelnen Funktionen eines Prozessors macht? Soll man den Anfängern das Datenblatt vorlegen und einfach denken friss oder stirb? Wenn ich mit dem Blockschema anfange stirbt jeder Neuuser über kurz oder lang. Die wenigsten wollen sich erst mit dem Aufbau eines Prozessors auseinander setzen und einige Zeit später sein erstes Programm schreiben.
Das Anliegen bei meinen Tuts ist es zu erklären in kurzen Worten, ein paar Beispiel und ein bischen Code für die erste Anwendung. Dabei muss ich Kompromisse eingehen. Erklärungen muss man verstehen können.
Habe leider feststellen müssen, das es viele Leute mit Wissen gibt aber nur wenige es auch so erklären können das man es versteht. Habe so eine blöde Eigenart an mir, ich Frage so lange bis ich auch die Erklärungen zum Thema verstanden habe. Mein Ziel ist es Anfängern bei den ersten Schritten zu helfen, ein bischen Spass an den ersten Programmen und Hardware zu bringen. Frust hilft nicht.
Ist es besser alle Tuts zu löschen und eine Empfehlung auf die Datenblätter zu machen?
achim
 
Ob es 249 oder 250 sei erst mal nicht weiter geklärt. Muss noch mal nachschauen was die für einen Grund haben.
Du berechnest die nötigen 250 Schritte pro Periode ja auch völlig korrekt. Und weist dann im Programm dem Vergleichsregister den - völlig korrekten - Wert 249 zu. Aber WARUM es bei 249 eben 250 Schritte sind, erklärst Du nicht. Wenn Du das mit Beispielen erklären willst, gehört das mit rein - ansonsten kannst Du Deinen Lesern ja auch gleich die fertige Formel (wo das "-1" bereits drin ist) um die Ohren knallen.
Der Grund ist, daß der CTC-Mode zwar Clear Timer on Compare Match heißt, aber der Timer eben nicht beim "erreichen" der Gleichheit (TCNT=OCR) zurückgesetzt wird, sondern einen Schritt später (quasi beim "verlassen"). So wie eben auch ein 8bit-Zähler nicht beim erreichen der 255 überläuft, sondern einen Schritt später. Deswegen kommt ein (normal Mode) 8bit-Timer eben auf 'ne Überlauffrequenz von clktn/256, und nicht auf clktn/255. Der Top-Wert ist da 255. Und wenn der Top-Wert (wie auch immer) auf 249 reduziert wird, läuft der Timer eben mit clktn/250 über.

Mein Ziel ist es Anfängern bei den ersten Schritten zu helfen, ein bischen Spass an den ersten Programmen und Hardware zu bringen. Frust hilft nicht.
Ist es besser alle Tuts zu löschen und eine Empfehlung auf die Datenblätter zu machen?
Dann wäre es vielleicht sinniger, erstmal nur den normal mode durchzuspielen - mit Berechnung und Beispielcode.
Bei 16Mhz Systemtakt würde ein 8bitter mit 62,5kHz überlaufen. Als erstes Programm könnte man also den Timer mit Prescaler=1 durchlaufen lassen, und im Hauptprogramm das TOV-Flag pollen. Ist es gesetzt, wird es zurückgesetzt und 'ne Variable hochgezählt. Erreicht diese Variable dabei 62500, setzt Du sie auf 0 zurück (das entspricht dann übrigens dem Schritt 62499->0, auch hier hast Du bereits die Überlaufs"-1") und toggelst irgendein Bein mit'ner LED dran -> 0,5Hz wegen dem toggeln. Halbierst Du die 62500, hast Du 'n 1Hz-Blinker...
Da der Timer währenddessen weiterläuft, und nur 256 Schritte macht, darf im Hauptprogramm nicht viel weiterer Code stehen. wäre ein geeigneter Punkt, den TOV-Interrupt einzuführen. Und/Oder den Prescaler, der außerdem die Variable kleiner bekommt. Auch hier wäre Platz für Beispielrechnungen.
Mit wenigen möglichen diskreten Vorteiler-Werten kann man natürlich nur wenige diskrete Überlauffrequenzen vorgeben -> Grobtuning.
Ums feiner einzustellen, kannst Du durch Preload nach jedem Überlauf Schritte überspringen lassen. Beispielrechnungen+Code...
Als nächstes könntest Du dann das/die Output Compare Units einführen, also den automatischen Vergleich, mit den entsprechenden Match-Flags. Inwifern man hier bereits auf die automatische Manipulation der Compare-Pins eingeht ist 'ne andere Frage (Compare Output Mode).

Denkbar wäre jetzt aber sogar als Zwischenschritt, den Zähler nach einem Match (Flag-Polling oder Interrupt) manuell zurückzusetzen - zumindest anschließend wäre dann der CTC dran. Also daß der Timer das in Hardware selbst kann usw.

Spätestens jetzt wären die Compare Output Modes dran - also einerseits im Normal Mode und CTC, und andererseits im FastPWM.
Damit wäre die Single-Slope-Seite fertig - fehlt "nur noch" der Dual-Slope...

Natürlich könnte man so'n "Tutorial" in mehrere Teile zerlegen - aber dann sollte zumindest die Reihenfolge eingehalten werden, und jeder Teil auf den letzten und den nächsten Teil verweisen. Möglicherweise auch mit Gesamt-Gliederung aller Teile.

P.S.: Ich hab auf dem Tablet hier Android 4.0.3, das auf dem Funktelefon ist nicht nennenswert aktueller. Bei beiden werden die Zertifikate schon lange nicht mehr geliefert. Meiner Meinung nach ist das ein Grund, warum ich hier keine Ressourcen runterladen kann. Wenn ich also mal nebenbei auf'm Sofa im Forum schmökere, kann ich Deine Ressourcen nicht lesen.
 

Über uns

  • Makerconnect ist ein Forum, welches wir ausschließlich für einen Gedankenaustausch und als Diskussionsplattform für Interessierte bereitstellen, welche sich privat, durch das Studium oder beruflich mit Mikrocontroller- und Kleinstrechnersystemen beschäftigen wollen oder müssen ;-)
  • Dirk
  • Du bist noch kein Mitglied in unserer freundlichen Community? Werde Teil von uns und registriere dich in unserem Forum.
  •  Registriere dich

User Menu

 Kaffeezeit

  • Wir arbeiten hart daran sicherzustellen, dass unser Forum permanent online und schnell erreichbar ist, unsere Forensoftware auf dem aktuellsten Stand ist und der Server regelmäßig gewartet wird. Auch die Themen Datensicherheit und Datenschutz sind uns wichtig und hier sind wir auch ständig aktiv. Alles in allem, sorgen wir uns darum, dass alles Drumherum stimmt :-)

    Dir gefällt das Forum und unsere Arbeit und du möchtest uns unterstützen? Unterstütze uns durch deine Premium-Mitgliedschaft!
    Wir freuen uns auch über eine Spende für unsere Kaffeekasse :-)
    Vielen Dank! :ciao:


     Spende uns! (Paypal)