Timer 8051

Bisher wurden Zeitverzögerungen über Zeitschleifen erzeugt. Viele Anwendungen erfordern aber exakte Zeitverzögerungen bzw. Zeitspannen.
Mit Zeitschleifen ist es praktisch unmöglich exakte Zeitverzögerungen zu programmieren. Außerdem kann der Mikrocontroller bei der Abarbeitung einer Schleife keine anderen Aufgaben erfüllen.

Zur Entlastung des Mikrocontrollers und zur Erfüllung exakter Zeitbedingungen werden Timer verwendet.
Ein Timer zählt Taktimpulse und löst bei Überlauf eine Interruptanforderung aus.

Der Timer kann sowohl als Zeitgeber wie auch als Ereigniszähler eingesetzt werden.

 

Übersicht der Timeradressen

(z.B. Timer 0 auf 000B und Timer 1 auf 001B)

Timeradressen Source Vector Address

Timer 0 und Timer 1 bestehen aus jeweils zwei 8-Bit-Zähler.
Je nach gewünschten Modus lassen sich sich als 8-Bit oder 16-Bit Zähler verwenden.

 

Zählregister

Die 8-Bit-Zählregister sind die Spezial-Funktions-Register TL0 (Timer Low 0) und TH0 (Timer High 0) für Timer 0 sowie TL1 (Timer Low 1) und TH1 (Timer High 1) für Timer 1.

Timer Register Zählregister

Werden beide Register hintereinander geschaltet, so ergibt sich ein 16-Bit-Zähler (216 = 65636 Zählschritte)

Die beiden Zählerregister TL0 und TH0 lassen sich auf bestimmte Anfangswerte (00 00 bis FF FF) setzen.
Hier im Beispiel ist der Anfangswert auf 0FAF (4015) gesetzt. Ab diesen Werten zählen sie nach dem Starten des Zähler aufwärts bis FFFF (65636).

Läuft der Zähler über (Ab FF FF mit dem nächsten Takt = Überlauf, wird das Überlauf-Flag TF0 gesetzt.

 

Überlauf-Flag

Das Überlauf-Flag kann vom Programm abgefragt werden oder einen Interrupt auslösen. Wird das Flag vom Programm abgefragt, muss es auch vom Programm wieder gelöscht werden.

Timer Flag

Nach dem Überlauf kann der Zähler wieder auf einen Anfangswert gesetzt werden. Wird kein Anfangswert gesetzt, beginnt der Zähler bei 0000.

 

Einsatz des Timer 0 als Zeitgeber

Wird ein Timer als Zeitgeber verwendet, werden die Zähler vom Systemtakt hochgezählt. Damit wird die Periodendauer des Systemtaktes über den Zähler addiert.
Je nach Anfangswert des Zählers ergibt sich bis zum Überlauf eine bestimmte Zeitverzögerung. Diese Zeitverzögerung ist aber nicht mehr vom laufenden Programm abhängig.

Der Timer, der vom Systemtakt getaktet wird, ist als eigenständige Hardwarebaugruppe zu betrachten.
Die Zeitverzögerung und damit der Systemtakt wird von der jeweiligen Quarzfrequenz bestimmt.

Bei einer Oszillatorfrequenz von 12MHz ergibt sich ein interner Systemtakt von 1MHz.
1MHz entspricht einer Systemzeit von 1us pro Takt.

Timer als Zeitgeber

Beispiel:

Es soll ein Systemtakt von 50ms erzeugt werden. Nach 50ms soll das Timer-Flag gesetzt werden.
a.) Mit welchen Werten muss der Timer (im 16-Bit-Zählermodus) vorgeladen werden?
b.) Was muss verändert werden, um einen Takt von 1s zu erzeugen?

Ein kompletter Durchlauf entspricht 65636 States (65636 us).
50 ms = 50000 us  -->  65636 - 50000 = 15536

a.) Um eine Zeit von 50ms zu generieren, muss der Timer auf die Dezimalzahl 15536 vorgeladen werden.
Das entspricht der HEX-Zahl 3CB0!

TH0 wird also mit 3C und TL0 mit B0 vorgeladen:

Assemblercode

MOV    TL0,#B0h      ;Vorladen des Timer 0 (Low Byte) mit B0
MOV    TH0,#3Ch     ;Vorladen des Timer 0 (High Byte) mit 3C

b.) Da der Timer max. 65,636ms pro Durchlauf erzeugen kann, muss z.B. ein zusätzliches Register bei jedem Durchlauf um 1 inkrementiert werden, solange bis 20 Durchläufe (50ms x 20 = 1s) erreicht werden.

Läuft der Zähler bei 65636 über, wird sein Überlauf-Flag (TF0) auf 1 gesetzt.

Hier gibt es zwei Möglichkeiten:

  1. Das Flag löst einen Interrupt aus. Das laufende Programm wird unterbrochen und eine Interupt-Service-Routine ausgeführt.
  2. Das Flag wird vom Programm abgefragt. Ist es gesetzt, wird eine entsprechende Aktion ausgeführt und das Flag zurückgesetzt.


Einstellen der Zeit und starten des Timers 0

  1. Taktsignal stoppen
    CLR    TR0
  2. Timer Low Byte mit AF vorladen
    MOV   TL0,#0AFh
  3. Timer High Byte mit 0F vorladen
    MOV   TH0,#0Fh
  4. Überlauf-Flag zurücksetzen
    CLR    TF0
  5. Taktsignal starten
    SETB   TR0

 

Einstellen der Timer-Funktion mit TMOD

Das Timer-Modus-Register TMOD ist ein 8-Bit-Register.
Die oberen 4 Bits werden für den Timer 1 und die unteren 4 Bits für den Timer 0 verwendet.

Timer Modus Register TMOD

Einstellen des Arbeitsmodus M0 und M1: (Für die beiden gebräuchlichsten Arbeitsmodi)

Einstellung 16-Bit-Zähler: M0 = 1 und M1 = 0
Beide 8-Bit-Zählregister sind hier in Reihe und bilden 216 (65536) Stacks.

Einstellung 8-Bit-Autoreload-Zähler: M0 = 0 und M1 = 1
Bei einem Überlauf wird der Wert vom High-Byte (TH0 bzw. TH1) in das Low-Byte kopiert.
Das High-Byte bleibt in diesem Fall unverändert.

 

Übersicht aller Betriebsarten

Timer Betriebsarten

 

Blockschaltbild des Timers in Modus 1

Mit C/T wird zwischen dem Ereigniszähler (für externen Zähler) und Timer-Betrieb gewählt.
C/T = 0 --> Funktion als Timer
C/T = 1 --> Funktion als Zähler


Mit GATE wählt man zwischen der internen- oder externen Freigabe des Zählers/Timers aus.
GATE = 0 --> Interne Freigabe über TR0 bzw. TR1
GATE = 1 --> Externe Freigabe erfolgt über die Portpins P3.2 bzw. P3.3 und interne Freigabe über TR0 bzw. TR1.

Timer Blockschaltbild

 

Timer Blockschaltbild Gate C/T

 

Blockschaltbild des Timers in Modus 2

Timer Blockschaltbild Modus 2

 

 

Übersicht der Adressen und Funktionen des Timer Control Register TCON

Timer Control Register TCON

Spezial-Funktions-Register TCON

 

Beschreibung in Assembler
  1. Initialisierung des Timers

    MOV    TMOD,#01h     (Timer 0 als 16-Bit-Zähler M0=1)

    01h = 00000001 binär

    MOV    TMOD,#10h     (Timer 1 als 16-Bit-Zähler M0=1)

    10h = 00010000 binär


  2. Vorladen des Timers

    MOV    TL0,#B0h      ;Vorladen des Timer 0 (Low Byte) mit B0
    MOV    TH0,#3Ch    
    ;Vorladen des Timer 0 (High Byte) mit 3C

  3. Starten und stoppen des Timers

    SETB    TR0      (Timer0 start: run-bit setzen)

    SETB    TR1      (Timer1 start: run-bit setzen)

    CLR      TR0     (Stop Timer 0)

    CLR      TR1     (Stop Timer 1)


  4. Auslesen des Timerwertes

    MOV     R7,TH0     (Timerwert High-Byte von Timer 0 in das Register 7 laden)

    MOV     R6,TL0     (Timerwert Low-Byte von Timer 0 in das Register 6 laden)