C-Programmierung mit AVR-GCC/ Timer

Aus Wikibooks

Was sind Timer und wofür benutzt man diese?[Bearbeiten]

Wie der Name schon andeutet, scheint es hier um Zeit zu gehen.

In einem anderen Kapitel wurde schon das "delay" (C-Programmierung_mit_AVR-GCC/_Warteschleifen) vorgestellt. Bei "delay" geht es um eine recht einfache Art, Zeit zu verplempern. Dies ist jedoch oftmals nicht gewünscht, da man somit kostbare Rechenzeit verliert.

Mit einem Timer kann man ganz elegant Aufgaben parallel abarbeiten. Man muss jedoch aufpassen, denn was sich im letzten Satz so schön anhört, hat so seine Nachteile. Ein Timer unterbricht den aktuellen Programmablauf, um eine andere Aktion zeitgesteuert dazwischenzuschieben.

Somit ist der Timer nichts anderes als ein zeitgesteuerter Interrupt (Unterbrechung).

Welche Timer gibt es?[Bearbeiten]

Bevor man richtig loslegen kann, muss man erst einmal herausfinden, ob, welche und wie viele Timer ein Mikrocontroller hat. Dazu bemüht man am besten das Datenblatt des Herstellers.

Die meisten 8-Bit-Mikrocontroller haben 2 Timer, einen einfachen und einen erweiterteten. Der einfache Timer arbeitet mit einem 8-Bit-Register, welches ein kürzeres Zeitintervall erlaubt als der erweitere Timer, der zwei 8-Bit-Register nutzt.

Die maximale Laufzeit des Timers wird zusätzlich zur Wahl des Timers auch vom Systemtakt und dem Vorteiler beeinflusst. Der Vorteiler ist ein vorgeschalteter schneller Frequenzteiler; auf diesen wird später eingegangen.

Timer aktivieren und deaktivieren[Bearbeiten]

Mit den Befehlen sei() und cli() kann man den Timer starten und stoppen. Während des Abarbeitens eines Interrupts kann kein zweiter Interrupt ausgeführt werden, außer es wird explizit vom Timer erlaubt.

Mit dem Befehl cli() kann man alle Timer und Interrupts daran hindern, eine Unterbrechung zu erzeugen, bis diese mit sei() diese aktiviert werden.

Vorteiler[Bearbeiten]

Der Timer arbeitet mit dem Systemtakt; da dieser bei 8 MHz eine Taktperiode von 0,125 µs hat, wäre diemMaximale Timerdauer bei 32 µs (0,125µs*256).

Um die Maximaldauer zu erhöhen, gibt es die ,Möglichkeit einen Vorteiler zu verwenden, welcher schon fest im Mikrocontroller vorgegeben ist.

Am Beispiel des Timer0 eines ATTiny möchte ich hier die Vorteiler und deren Konfiguration erklären. (Die Informationen finden Sie im Datenblatt Ihres Mikrocontrollers im Kapitel Timer/Counter.) Es werden für die Konfiguration des Vorteilers die drei Bits CS00, CS01, CS02 des Registers TCCR0B verwendet.

CS02 CS01 CS00 Erklärung
0 0 0 Timer/Counter deaktivieren
0 0 1 kein Vorteiler
0 1 0 Takt/8
0 1 1 Takt/64
1 0 0 Takt/256
1 0 1 Takt/1024
1 1 0 Externer Takt am T0 Pin. Bei fallender Spannung
1 1 1 Externer Takt am T0 Pin. Bei steigender Spannung

Beispiel: Vorteiler einstellen[Bearbeiten]

TCCR0B|=(1<<CS02)|(1<<CS00);

In diesem Fall wird ein Vorteiler von 1024 gewählt.

Man kann nun berechnen, in welchen Schritten der Timer hochzählt und welches maximale Intervall dieser zur Verfügung stellen kann:

1/8MHz = 0,125µs
Vorteiler von 1024: 0,125µs * 1024 = 128µs
8-bit Timerregister: 128µs*256= 32,768ms

Interrupt Service Routine[Bearbeiten]

Was soll geschehen, wenn der Timer überläuft?

Bis jetzt haben wir nur besprochen, wie man die Zeit berechnen kann. Wenn diese abgelaufen ist, sollte jedoch etwas passieren.

Eine Möglichkeit wäre, das Register TCNT0 auszulesen, welches die bereits durchlaufenen Timerüberläufe zählt. Dies würde jedoch bedeuten, dass man dieses Register permanent überwachen müsste, was manchmal, aber leider nicht immer Sinn macht.

Die oftmals bessere Möglichkeit besteht darin, dass nach dem Überlauf sofort ein Prozess angestoßen wird. Diesen muss man natürlich in einer eigenen Funktion selbst definieren. Der Funktionsname ist vorgegeben und kann folgendermaßen lauten: ISR(Timer0)

Bitte halten sie den Inhalt dieser Funktion kurz!