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 2
8 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).)