Logo

Timer der AVR® Mikrocontroller-Familie

Eine der wichtigsten Funktionen, die AVR Mikrocontroller zur Verfügung stellen sind Timer.
Bei einem Timer handelt es sich prinzipiell um einen Zähler, der durch einen einstellbaren, genau definierten Takt gespeist wird. Der Zähler läuft unabhängig vom aktuellen Programm parallel zur CPU. Mit dem Zählerstand und der definierten Länge des Zähltakts kann man auf die verstrichene Zeit zurückschließen.

Häufig stellt ein Mikrocontroller mehrere Timer zur Verfügung, die auch noch unterschiedliche Sonderfunktionen besitzen.

Die Funktionsweise der Timer wird über Sonderregister gesteuert.

Die Zähler des ATmega328p

Am Beispiel des ATmega328p werden die grundlegenden Funktionen von Timern behandelt. Der ATmega328p besitzt 3 Timer mit unterschiedlichen Sonderfunktionen. Zwei der Timer (TC0 und TC2) haben eine Breite von 8 Bit, einer (TC1) hat eine Breite von 16 Bit.

Die Timer/Counter Control Register

Die Funktion der Timer wird für jedem Timer unabhängig von drei Sonderregistern gesteuert. Diese werden im Handbuch als Timer/Counter Control Register (TCCRnA, TCCRnB, TCCRnC) bezeichnet.

Zähler im Normalmodus

Blockdiagramm Timer

Vereinfachtes Blockschaltbild für einen Zähler im Normalmodus

Im Normalmodus fungiert ein Zähler einfach nur als Zähler. D.h. unabhängig von der CPU zählt der Zähler kontinuierlich hoch bis zum Überlauf und fängt dann wieder bei Null an weiter zu zählen.

Prescaler

Der Takt, mit dem der Zähler hoch zählt, wird aus dem Systemtakt gewonnen. Beim ATmega328p auf dem Arduino UNO Board liegt dieser bei 16MHz. Da dies für viele Anwendungen zu schnell ist, kann man mit einem Prescaler einen niedrigeren Zähltakt einstellen.

Der Prescaler dividiert den Systemtakt durch einen festen Wert. Beim ATmega328p sind für TC0 und TC1 folgende Werte möglich: 8, 64, 256, 1024.

Die Einstellungen des Prescalers werden durch die drei Clock Select Bits CSn2:0 gesteuert, die sich im Timer/Counter Control Register B TCCRnB des jeweiligen Timers finden. Dabei unterscheidet sich die Programmierung CS-Bits von TC0 und TC1 geringfügig vom TC2.

Setup der Timer im Normalmodus

Das Setup der Timer für den Normalmodus ist denkbar einfach. Es muss nur das TCCRnB beschrieben werden, die anderen Register werden bei einem Reset standardmäßig auf Null gesetzt. Sobald eines der Clock Select Bits CSn2:0 ungleich Null ist, erhält der Timer ein Taktsignal und läuft los.

PWM

Die Pulsweiten-Modulation (PWM) wird häufig zur Leistungssteuerung von Verbrauchern eingesetzt.

Die Timer des ATmega328p (und natürlich auch vieler anderer AVR-Mikrocontroller) bieten die Möglichkeit an bestimmten Pins ein PWM-Signal zu generieren, unabhängig vom Programmablauf auf der CPU.

Darüberhinaus stehen unterschiedliche PWM-Modi zur Verfügung.

Compare Match

Die Funktionsweise der PWM-Generierung beruht auf einem Vergleich des aktuellen Zählerstands mit zwei unabhängigen Output Compare Registern (OCRnA und OCRnB). Bei einem Compare Match (Gleichheit von Register und Zählerstand) kann der Zustand der PWM-Pins (OCnx) auf unterschiedliche Art verändert werden.

Die Funktionalität ergibt sich wiederum durch das Beschreiben der Register-Bits im Timer/Counter Control Register (TCCRnA, TCCRnB, TCCRnC) Außerdem müssen auch die Output Compare Register (OCRnA und OCRnB) mit den entsprechenden Werten beschrieben und ggf. im Programmablauf geändert werden.

Fast PWM mit fester Periode TC0 (Mode 3)

Ein asymmetrisches PWM-Signal an den Pins OC0A (PD6) und OC0B (PD5) ergibt sich im PWM Mode 3. Dazu werden die Waveform Generation Mode Register-Bits (WGM02:0) wie folgt beschrieben:

WGM02 WGM01 WGM00
0 1 1

Die PWM-Frequenz ergibt sich dann aus der Stellung des Prescalers von TC0, d.h. aus den Clock Select Bits CS02:0.

Das PWM Signal kann invertiert werden oder nicht. Dies ergibt sich aus den Compare Match Output Mode Bits COM0A1:0 und COM0B1:0 für das OCR0A und OCR0B.

Das Tastverhältnis der PWM ergibt sich aus den Output Compare Registern OCR0A und OCR0B. Diese können während des Programmablaufs verändert werden, was zu einer Veränderung des Tastverhältnisses des PWM-Signals an OC0A (PD6) und OC0B (PD5) führt.

Für die Erzeugung eines PWM-Signals mit dem TC0 müssen also folgende Register-Bits beschrieben werden:

  • WGM0[2:0]
  • COM0A[1:0]
  • COM0B[1:0]
  • OCR0A[7:0]
  • OCR0B[7:0]
  • CS0[2:0]

Timer Interrupts

Die Timer des AVR stellen mehrere Möglichkeiten zur Verfügung, einen IRQ auszulösen. Für den ATmega328p werden diese in einem gesonderten Abschnitt beschrieben:

Rechtecksignal mit variabler Frequenz

Die Timer lassen sich auch zur Signalerzeugung nutzen. So lässt sich ein symmetrisches Rechtecksignal mit variabler Frequenz unabhängig von der CPU erzeugen.

CTC-Mode

Für diesen Anwendungsfall eignet sich der CTC-Mode des jeweiligen Timers.
CTC steht für Clear Timer on Compare Match. Der Timer wird bei einem Compare Match rückgesetzt und fängt von Null an zu zählen.

Es muss dazu das Output Compare Register A OCRnA beschrieben werden.

Die Output Compare Pins müssen in den Toggle Mode versetzt werden.

Das Signal liegt dann an den entsprechenden Output Compare Pins OCnA bzw. OCnB an.

TC0 im CTC-Mode

Um den Timer 0 in den CTC-Mode zu setzen, werden die Waveform Generation Mode Register-Bits (WGM02:0) wie folgt beschrieben:

WGM02 WGM01 WGM00
0 1 0

Die Compare Match Output Mode Bits COM0A1:0 und COM0B1:0 für das OCR0A und OCR0B werden in den Toggle Modus versetzt:

COM0A1
COM0B1
COM0A0
COM0B0
0 1

Die Frequenz des Ausgangssignals ergibt sich aus dem Output Compare Register OCR0A und dem Prescaler, der sich aus den drei Clock Select Bits CS0[2:0] im TCCR0B.

Die Ausgangsfrequenz ergibt sich aus folgender Formel:

Das Ausgangssignal liegt an den Pins OC0A (PD6) und (je nach Einstellung der Register) OC0B (PD5) an.