erstellt 10.11.2011
Timer
Der Timer ist wohl einer der wichtigsten und damit auch der am meist verwendete Baustein innerhalb eines Mikroprozessor darum sollte man sich auf
jeden Fall sehr intensiv mit diesem Baustein befassen.
Die Möglichkeiten die sich einen mit diesem Baustein bietet sind sehr komplex und auch individuell.

Was wird beim Atmega oder besser allgemein gesagt beim Mikroprozessor eigentlich als Timer bezeichnet ?
Timer sind selbständige Zähler im Prozessor, man braucht sie dort, wo Zeitkritische und genaue Aufgaben gefordert sind.
Programme laufen ja Sequentiell ab , also werden Befehl für Befehl meist nacheinander abgearbeitet oft in einer Schleife die wenn das Programm
am Ende angekommen ist, wieder von vorne anfängt .
Der Ablauf dieser Schleifen würde ja mit zunehmender Anzahl der Befehle eine längere Zeit benötigen, und so je nach Aufgabe unregelmäßig sein
so das man präzise Zeitinformationen damit nicht bewerkstelligen kann.
Mann denke z.B an einer Uhr die möglicherweise auch genau läuft , wenn aber einige Befehle zur Programmschleife hinzukommen würden ,
würde die Uhr immer etwas langsamer laufen.
Also befinden sich in den Mikroprozessoren  Timer die unabhängig vom übrigen Programm parallel ihren Dienst verrichten.
Im Atmega 8  und auch im Atmega 32 befinden sich gleich je 3 Timer .
Diese Timer sind unterschiedlich in ihrer Art und  Auflösung .
Alle Timer besitzen einen Internen 10 Bit Prescaler (Vorteiler) , mit dem die Takt-Frequenz in bestimmten Stufen und zwar meist durch den Faktor
 1,8,64,256 oder 1024 herunter geteilt werden kann .
Timer sind also nichts weiter als Zähler die anfangend von Null an hochzählen bis der Zähler seinen Höchstwert erreicht hat.
Dieser Höchstwert ist abhängig von der Menge der sogenannten Bits, die stellvertreten für die Anzahl der Speicherstellen stehen.

Also bei ein Bit ( Ein Bit kann  aus 0 oder 1 bestehen also zwei Werte) ,  könnte der Zähler bis zwei zählen. Bei zwei Bit bis 4 usw.
Die Timer im Atmega sind unterschiedlich und können in der Regel einen 8 oder 16 Bit Wert verarbeiten, also bis  256 oder 65536 zählen.
Bei jedem Überschreiten des Höchstwertes hat man die Möglichkeit einen sogenannten Interrupt auszulösen, also den Timer anzuweisen
in ein Unterprogramm zu springen und dieses abzuarbeiten.
nach oben
Das wäre der Normalfall, die Timer haben aber noch andere Fähigkeiten so können sie z.B auch zwei Werte vergleichen,
oder auch aufwärts zählen bis zu einem bestimmten Wert und dann wieder rückwärts zählen usw.
Die Art (Mode ) wie der Timer zählen soll kann man zum einen als Bascom Befehl eingeben oder es gibt auch die Möglichkeit als Bitwert
im sogenannten TimerControlRegister diese Einstellungen vorzunehmen .

Wie man die Daten nun eingibt muss man selbst entscheiden, beide Methoden haben so ihre Vorteile oder auch ihre Tücken,
aber das kann man später noch entscheiden , wichtig ist es davon gehört zu haben, das es diese Möglichkeiten gibt.

Damit nun beispielsweise bei einer Taktfrequenz von 1 MHz der Timer nicht so schnell überläuft , haben die Timer sogenannte "Prescaler" ,
das sind Vorteiler die den Systemtakt, durch festgelegt Werte teilen und so den Timer in bestimmten Schritten langsamer laufen lassen.
Und dann gibt es noch die Einstellung "Compare Output Mode "in denen die Funktion  der Ausgangspin's   festgelegt werden.
Und es gibt noch die Möglichkeit außer den Systemtakt auch einen Externen Takt als Taktquelle zu benutzen , in diesem Fall wird dann der
Externe Takt an Anschluss Tx angelegt, wobei das X für den jeweiligen Timer steht z.B. Timer 0 , Timer 1, Timer 2.
nach oben

Bascom Instruktion oder Register ?
 nach obenUm den Timer mitzuteilen was sie genau wann zu machen haben, gibt es grundsätzlich zwei Möglichkeiten, zum einen als Bascom Instruktionen  oder die Einstellungen direkt ins Register.
Die Bascom Instruktionen sind für den einen oder anderen geläufiger oder erscheint Übersichtlicher , die Registeranweisung hingegen besitzt den Vorteil  komplexe Einstellungen innerhalb von nur wenigen meist 8 oder 16 Bit Werte einzugeben, was am Anfang aber etwas komplexer ist, weil erst in den Datenblätter aus den  Tabellen für die dazugehörigen Werte beschafft  werden müssen., aber sich meist später dann als übersichtlicher  herausstellt, und es auch im Programm schneller verarbeitet werden kann. 
Beispiel
als Bascom Instruktion als Registereinstellung Beschreibung
Config Timer2 = Timer , Clear Timer = 1 , Compare =
Toggle , Prescale = 256
Tccr2 = &B0001101  Konfiguriert Timer2 als Timer, der bei übereinstimmung des Timerwert mit dem Comparewert den Timer auf Null zurücksetzt
config Timer0=Timer,Prescale=8 TCCR0 = &B00000010
Enable Timer0 TIMSK.TOIE0=1 Timer0 Interrupt freigeben
Enable Interrupts SREG.7=1 Interrupts Global freigeben



Beide Möglichkeiten haben die gleiche Bedeutung, man kann das eine oder andere Schreiben, aber was einem am Ende leichter fällt muss jeder für sich entscheiden.
nach oben
Timer Modus
Wie folgt gibt es mehrere Möglichkeiten in den der Timer konfiguriert werden kann:
nach obenMode Funktion Beschreibung
0 (Normal) Hier zählt der Timer immer von Null an aufwärts bis 256 beim 8 Bit Timer , oder 65535 beim 16 Bit Timer, nachdem er seinen Höchstwert erreicht hat fängt er wieder bei Null an.
Bei Bedarf kann bei jedem Überlauf ein Interrupt ausgelöst werden.Das heißt dem Timer kann gesagt werden das er bei jedem Überlauf  eine Routine anspringen soll um diese dann abzuarbeiten. Das alles hat Priorität vor dem Ablauf der eigentlichen Programmschleife.
Der aktuelle Zählwert des Timers ist im Register TCNTx gespeichert. ( X ist die Nr. des benutzten Timers z.B 1.2 oder 3).
Berechnung der Ausgangsfrequenz
Arbeitsfrequenz = 1 Mhz
Vorteiler = 8
Timerauflösung= 256
Erzeugte Frequenz = Arbeitsfrequenz  / Vorteiler / Auflösung/2
Erzeugte Frequenz = 1000000 MHz / 8 / 256/2
= 244 Hz

Um die Timer genauer anzupassen also die Zeiten bis zum Überlauf zu verkürzen gibt es die Möglichkeit die Timer schon mit bestimmten Werte vorzuladen, das heißt wir lassen die Timer nicht von 0 an zählen sonder geben schon einen bestimmten Startwert vor so das er beispielsweise bei 100 anfängt zu zählen , somit hat er dann früher seinen Höchstwert erreicht. die Zeitintervalle werden also kürzer.
Timer die im Normal Modus arbeiten haben je nach eingestellten Vorteiler ( Prescaler) eine nicht immer konstante Zeitliche Verzögerung zwischen Timerschritt und Interrupt Ausführung die man gegebenenfalls durch verändern der Vorgabewerte ausgleichen kann.
 
Berechnung  des Comparewertes bei Timer 1
Arbeitsfrequenz = 1000000
Vorteiler = 64
Timerauflösung =65536 bei Timer 1 oder 256 bei Timer 0
Gewünschte Frequenz= 1Hz
(1000000 /64) / 15625 Hz
65535-15625 = 49910    
49910  = Vorgabewert

Beispielprogramm
Programmzeile
Beschreibung
Config Timer1 = Timer , Prescale = 1024
Bestimmt das Timer 1 als  Timer verwendet wird und teilt den Arbeitstakt  durch 1024
Enable Timer1
startet Timer 1
On Timer1 Test Hier wird dem Timer gesagt das er zum Programmpunkt "Test"  springen soll wenn der Timer einen Überlauf meldet
Enable Interrupts
Hier wird der Interruptus aktiviert
Timer1 = 61935 
Voreinstellung des Timers kann hier vorgenommen werden
Programm ..............
Hier kommt das eigentliche Programm rein
Test: Hier ist der Anfang der Unterroutine zu der gesprungen wird
Timer1 = 61935  
Hier wird wieder die Voreinstellung vorgenommen
Return

Von Hier wird zurückgesprungen zum

nach oben
CTC-Modus
Hier zählt der Timer von Null an aufwärts, es besteht die Möglichkeit einen Vergleichswert vorzugeben bis zu dem der Timer zählen soll dann stellt er sich selbständig wieder auf Null und dann wider bis zum Vergleichswert, also er muss nicht zwangsläufig bis 256 oder 65535 zählen.Der Vergleichswert ist im Register OCRx abgelegt.

Berechnung  des Vergleichswertes (Compare)
Systemtakt / Vorteiler /2 / Gewünschte Frequenz


Beispielprogramm
Crystal = 1000000
Systemtakt ( Quarz)
TCCR1A=&B01000000
Toggelt Pin OC1A
TCCR1B=&B00001010
Timer Reset beim erreichen des Vergleichswertes und Systemtakt durch 8 teilen
Compare1A= 625
Vergleichswert 100 bis zum dem gezählt werden soll





In diesem Beispiel werden  nicht die Bascom Direktiven angegeben sondern es wird direkt ins Register geschrieben.
Bei einer gewünschten Frequenz von 100 Hz ergibt sich folgende Rechnung:
1MHz/8/2/100 = 625
PWM Modus


 nach oben
Bascom Befehlssatz für  Timer
Also hier sind alle aufgelisteten Bascom Instruktionen die Im Bezug zum Timer stehen das Zeichen X steht immer für den jeweiligen verwendeten Timer also 0.1 oder 2
Befehl
Beschreibung
Config TimerX=Counter
Benutze Timer X als Zähler
Config TimerX= Timer Benutze Timer X als Timer
Edge=Falling
Zähle bei fallender Flanke nur wenn Timer als Counter arbeitet
Noice Cancel=1
Störunterdrückung einschalten ( Das Signal wird dreimal hintereinander Abgetastet und wird nur als Signal erkannt wenn es immer identisch war.
Capture Edge=Rising

Enable Timer X startet Timer X
On TimerX Timer_null Bei einem Überlauf von TimerX , soll in die entsprechende Unterroutine Timer_null gesprungen werden.
nach oben

Timer Möglichkeiten im Vergleich



Atmega 8
Atmega 16
Atmega 32
Eigenschaften
Timer0
Timer1
Timer2
Timer0
Timer1
Timer2



Anzahl der Bits
8
16
8
8
16
8
8
16
8
Zählen von externen Taktflanken



T0 ( PB0 )
T1 ( PB1 )
Nein

Ja

CTC möglich



Ja
Ja
Ja



Frequenzgenerator



Ja
Ja
Ja



PWM

Ja
Ja
Ja
Ja
Ja



PWM mit variabler Periode



Nein
Ja
Nein



zusätzliches unabhängiges Vergleichsregister



Nein
Ja
Nein



Input Capture Unit



Nein
Ja
Nein



Erlaubt 32Khz Uhrenquarz als Taktquelle


Ja
Nein
Nein
Ja



Prescaler 10 Bit
Ja
Ja
Ja
8-64-256-1024
8-64-256-1024
32-64-128-256-1024
Ja
Ja
Ja
nach oben








Timer1
"Timer 1" ist ein 16 Bit Timer mit den gleichen Funktionen wie "Timer0" kann aber nicht wie "Timer 0" bis 255 sondern bis 65535 zählen.
Darüber hinaus verfügt er über ein zusätzliches unabhängiges Vergleichsregister. Des weiteren beherrscht der Timer1 PWM (Pulsweitenmodulation).
Er besitzt eine Input Capture Unit um externe Ereignisse zu zählen oder um auf sie zu reagieren.
In "Timer 1" ist das Timer Control Register nicht 8 Bit breit wie beim "Timer 0" sondern 16 Bit breit, diese 16 Bit sind aber aufgeteilt in 2 mal 8 Pseudo Bits und heißen dann
TCCR1A  und  TCCR1B .
Im Register TCNTx wird der aktueller Registerwert gespeichert.
Und dann gibt es noch das Vergleichsregister OCR1AH+OCR1AL  und OCR1BH+OCR1BL (Output Compare Register A und B).
In Bascom greift man auf  diese beiden Register mit Hilfe der 16 Bit Pseudoregister ( COMPARE1A und COMPARE1B) zu.

Register TCCR1A

Bit 7
Bit 6
Bit 5
Bit 4
Bit 3
Bit 2
Bit 1
Bit 0

COM1A1
COM1A0
COM1B1
COM1B0
FOC1A
FOC1B
WGM11
WGM10
Über BIT 6 + 7 wird der OC1A  Ausgang  konfiguriert ob er mit dem Ausgang Pin intern  verbunden wird oder nicht
(00= nicht verbunden) 01= OC1A verbunden.
Beim Atmega 8 ist Ausgang OC1A gleich Portb.1 und der muss als Ausgang deklariert werden, wenn diese Funktion genutzt wird.
0
0






Über Bit 4 + 5 wird der OC1B Ausgang konfiguriert ob er mit  dem Ausgang Pin intern verbunden wird (00=nicht verbunden) 01=verbunden


0
0




Der Ausgang OC1A ist beim hochzählen 0 bis Vergleichswert erreicht wird , dann wird Ausgang auf 1 gesetzt. 1
0






Resetiert OC1B wenn Vergleichswert erreicht wird

1
0




Der Ausgang OC1A ist beim hochzählen 1 bis Vergleichswert erreicht wird , dann wird Ausgang auf 0 gesetzt. 1
1









1
1




Timer 1 wird bei einem Gleichstand des Zählers mit dem Vergleichsregister ( Compare1A) den Status des Ausgang OC1A ändern. Wobei Compare 1 A nur ein 16 Bit Pseudoregister für zwei tatsächliche 8 Bit Register ( OCR1AH + OCR1AL) ist. 0
1






Bei Gleichstand des Zählers und des Vergleichsregister Status am Ausgangpin  OC1B ändern

0
1




COM1A1
(Compare Match Output Mode) diese Register steuern den Output Compare Funktionen damit wird entschieden ob der OCR Ausgang aktiviert ist oder nicht








Force Output Compare (FOC) Modus
Der Force Output Compare Modus ist in alle Timer/Counter integriert.
Der FOC Modus kann nur bei nicht-PWM Modi genutzt werden. Beim Schreiben einer
logischen 1 auf FOCx wird ein sofortiger Compare Match des Funktionsgenerators
erzwungen. Der OCx Ausgang wird auf den Status des COMx1 Bits gesetzt. Deshalb
bestimmt der Wert aus COMx1 den Wert des OCx Pins beim Vergleich.








TCNTx - Timer/Counter Register In diesem Register wird der aktuelle Zählwert gespeichert. 







OCRx[A | B][H | L] - Output Compare Register (A oder B und H oder L nur
Timer1)Wenn TCNTx den Wert dieses Registers erreicht, wird ein Output Compare
Interrupt Request ausgelöst.








FOCx (Force Output Compare) Beim Schreiben einer logischen 1 auf FOCx wird ein sofortiger compare match des Funktionsgenerators erzwungen.







Der Zählwert des Timers also die gezählten Takte werden im Zähl-Register TCNT0 abgelegt mit jedem Takt wird der Wert im Register CNT0 um eins erhöht.
Es gibt zwei Möglichkeiten den Timern zu sagen was sie machen sollen, zum einen funktioniert das mit Bascom Befehle, und zum anderen gibt es die Möglichkeit Registereinstellungen direkt zu ändern.








TIMSK - Timer/Counter Interrupt Mask RegisterZur Auswahl, welche Interrupts aktiviert werden sollen.








ICR1[H | L] - Input Capture Register 1 Hi oder Low (nur Timer1)Wird bei jedem Input Capture Event mit TCNT abgeglichen. Kann zur
Festlegung des Maximalwertes genutzt werden.








TIFR - Timer/Counter Interrupt Flag RegisterHier werden bestimmte Bits gesetzt, wenn ein Interrupt ausgeführt werden soll.








ASSR - Asynchronous Status Register (nur Timer2)Register zur Steuerung des asynchronen Modus








SFIOR - Special Function IO RegisterPSR2 Bit setzt den Prescaler des Timer2 zurück








 nach oben


WGM10,WGM11,WGM12,WGM13
Waveform Generation Mode (WGM)
Im TCCRx Register gibt es einige Bits, die WGMxx heißen. Damit kann man die PWM-Modi und den CTC-Modus steuern. Für die PWM Modi gilt: Die Funktionen können am Pin OCx ausgegeben werden. Dafür muss das entsprechende Bit COMxx gesetzt sein. Der Pin muss als Output konfiguriert sein (PullUps).
Um den WGM Modus überschaubarer zu halten , hier eine Tabelle indem TCCR1A und TCCR1B zusammengefasst nur die Werte für WGM 10 bis WGM 13 enthalten
Register TCCR1A
TCCR1A Bit 4
Bit 3
Bit 1
Bit 0
Beschreibung



WGM11
WGM10

TCCR1B
WGM13
WGM12



Mode 0
0
0
0
0
Normal Modus Timer zählt von 0 bis 65535 läuft dann über und beginnt erneut bei 0 Der normale Modus ist in alle Timer/Counter integriert.
Das TCNTx Register wird nicht gelöscht, nach einem Überlauf startet das Register wieder von 0.
Bei aktiviertem Timer/Counter Overflow Interrupt wird dieser ausgelöst. Man kann den Wert, bei dem ein Interrupt ausgelöst werden soll, auch durch das Vergleichsregister OCRx einstellen. Dafür aktiviert man den Compare Match Interrupt, der ausgelöst wird, sobald TCNTx = OCRx ist. In diesem Modus kann man einen Timer Overflow Interrupt periodisch auslösen. Zusätzlich kann bei einem bestimmten Wert des Zählregisters ein Output Compare Match Interrupt ausgelöst werden.
Mode 1
0
0
0
1
PWM Phasen Correkt 8 Bit
Mode 2
0
0
1
0
PWM Phasen Correkt 9 Bit - Es wird von 0 bis zur Obergrenze und wieder zurück gezählt, Auf/Ab Zähler ( 9 Bit heiß er kann bis 512 zählen)
Mode 3
0
0
1
1
PWM Phasen Correct 10 Bit
Mode 4
0
1
0
0
CTC Modus (Clear Timer on Compare Match) Timer zählt von Null bis zum  Vergleichswert ,der im Vergleichsegister (Compare1A ) abgelegt werden muß ändert dann den Status von Pin  OCR1A und fängt wieder bei Null an.
Mode 5
0
1
0
1
Fast-PWM-Modus  8 Bit zählt Timer vom Vergleichswert A aufwärts bis Vergleichswert B , fängt dann wieder bei A an. Fast PWM Modus
Alle Timer/Counter sind mit dem Fast PWM Mode ausgestattet.
Der Counter zählt immer vom minimalen aufwärts zum maximalen Wert und beginnt wieder beim minimalen Wert. Dies ermöglicht einen schnellen Funktionsgenerator. Der Ausgang wird beim Starten auf 1 gesetzt und beim maximalen Wert auf 0.
Mode 6
0
1
1
0
Fast-PWM-Modus  9 Bit zählt Timer vom Vergleichswert A aufwärts bis Vergleichswert B , fängt dann wieder bei A an
Mode 7
0
1
1
1
Fast-PWM-Modus  10 Bit zählt Timer vom Vergleichswert A aufwärts bis Vergleichswert B , fängt dann wieder bei A an
Mode 8




Fast-PWM-Modus zählt Timer vom Vergleichswert A aufwärts bis Vergleichswert B , fängt dann wieder bei A an
Mode 9




Phasenkorreekten PWM Modus Timer zählt von 0 aufwärts bis zum Vergleichswert dann wieder zurück bis 0 (Ausgang OCR1A)
Mode 10
1
0
1
0
PWM Phase Correct - Phase Correct PWM Modus
Alle Timer/Counter beherschen diesen Modus.
Der Phasenkorrekte PWM Modus ermöglicht genaue Funktionsgeneratoren. Hier wird
erst hochgezählt und danach wieder herunter, wobei der Ausgang OC beim
Hochzählen auf 0 und beim Herunterzählen auf 1 gesetzt ist. Da das Vergleichsregister
OCR1A (bzw. ICR1) den maximalen Zählwert bestimmt, kann so
Pulsfrequenzmodulation implementiert werden
Mode 11
1
0
1
1
PWM Phase Correct (Ausgang OCR1A)
Mode 12
1
1
0
0
CTC- Modus = Clear Timer on Compare
Alle Timer/Counter des ATMega32  besitzen diesen Modus.
Stimmt das TCNTx Register mit dem Vergleichsregister OCRx überein, wird das TCNTx Register auf 0 gesetzt und bei aktiviertem Timer/Counter Overflow Interrupt wird dieser ausgelöst. Zum aktivieren des CTC-Modus müssen die WGM-Bits (Waveform Generation Mode) im TCCRx Register entsprechend gesetzt sein. Dieser Modus ermöglicht es periodisch einen Timer Overflow Interrupt auszulösen, wobei die Zeit zwischen 2 Interrupts verändert werden kann
Mode 13
1
1
0
1
Reserved
Mode 14
1
1
1
0
Fast PWM (ICR1 )
Mode 15
1
1
1
1
Fast PWM (Ausgang OCR1A)
 nach oben
Register TCCR1B Bit 7
Bit 6
Bit 5
Bit 4
Bit 3
Bit 2
Bit 1
Bit 0

ICNC1
ICES1

WGM13
WGM12
CS12
CS11
CS10
Bei 1 wird steigende Flanke registriert bei 0 die fallende
1






CSxx (Clock Select) konfiguriert den Prescaler
CS10,CS11,Cs12.
Mit den Bits 0-1-2 (CS10,CS11,CS12) wird  der Prescaler ( Vorteiler ) eingestellt also in wie weit der Tackt des Atmegas herunter geteilt soll , oder aber wenn der Takt von Außerhalb angelegt wird , an welcher Flanke der Takt registriert werden soll bei abfallender oder Steigender Flanke.(000 =Timer / Counter hält an)





0
0
0
Voller Takt wird genutzt




0
0
1
Takt durch 8




0
1
0
Takt durch 64




0
1
1
Takt durch 256




1
0
0
Takt durch 1024




1
0
1
Externer Takt an Pin T1 bei fallender Flanke




1
1
0
Externer Takt an Pin T1 bei steigender Flanke




1
1
1
Register (ICES1) wird festgelegt ob bei aufsteigender Flanke ( ICES1=1) oder fallender Flanke (ICES1=0 )der Eingangspin ausgewertet werden soll.
ICES1
 (Input Capture Edge Select) Bestimmt, welche Flanke ein Capture Ereignis auslöst. Bei 0 löst eine fallende Flanke ein Capture Ereignis aus, bei 1 eine steigende Flanke 1 = Triggert bei steigender Flanke 0 Triggert bei fallender Flanke1

1






ICNC1 (Input Capture Noice Canceler) Ist die Störunterdrückung (ICNC1=1) eingeschaltet, wird der Eingangspin viermal hintereinander abgetastet und muss auch 4 mal den gleichen Wert aufweisen also 4 mal 0 oder 4 mal 1 je nach welche Flanke er erkannt werden soll damit der Eingangsimpuls als solcher gewertet wird.
Bei ausgeschalteter Störunterdrückung (ICNC1=0) wird jede Flanke als Eingangsimpuls erkannt, so kann es beispielsweise bei nicht entprellten Signale zu Störungen durch mehrfach Erkennung kommen.
Störunterdrückung eingeschaltet 0 ist ausgeschaltet
1







nach oben









SREG
Bit
7
6
5
4
3
2
1
0


I
T
H
S
V
N
Z
C

Read/Write
R/W
R/W
R/W
R/W
R/W
R/W
R/W
R/W


1







Globalen Interrupt Freigeben (SREG.7=1)
nach oben
TIMSK
Bit
7
6
5
4
3
2
1
0


OCIE2
TOIE2
TICIE1
OCIE1A
OCIE1B
TOIE1
-------
TOIE0

Read/Write
R/W
R/W
R/W
R/W
R/W
R/W
R
R/W




1





Timer Counter1 , Input Capture Interrupt Enable
Wenn dieses Bit eine 1 hat und der Interrupt Flag im Status Register gesetzt ist ( Globale Interrupt freigegeben) dann ist der Interrupt für Timer 1 Vergelichsregister freigegeben




1




Timer/Counter1,Output Compare A Match  Interrupt Enable





1



Timer/Counter1,Output Compare B Match  Interrupt Enable






1


Timer/Counter1,Overfow Interrupt Enable








1
Timer0 Overflow-Interrupt ein Beispiel (TIMSK.TOIE0=1)

Timer 0                     (Atmega 8 + Atmega 32)
Timer 0 ist ein 8 Bit Timer und kann deshalb von 0 bis 255 zählen
Um Timer 0 einzustellen bedienen wir uns der sogenannten Register, das sind Speicherplätze in denen wir die Art und Funktionen der Timer konfigurieren können .

Beim Timer 0 gibt es das sogenannte TimerControlRegister  TCCR0 das wiederum aus 8 Bit besteht mit denen wir die Konfiguration vornehmen können
nach oben
Register TCCR0
Bit 7
Bit 6
Bit 5
Bit 4
Bit 3
Bit 2
Bit 1
Bit 0
Betriebsart

FOC0
WGM00
COM01
COM00
WGM01
CS02
CS01
CS00

Mode 0

0


0



Normal - In diesem Modus zählt der Timer pro Tick des Systemtaktes von 0 beginnend hoch bis 255 .
Bei jedem Überlauf , also bei 255 kann ein Interrupt ( OVF0 ) ausgelöst werden.
Wird der Systemtakt zuvor aber durch den Prescaler heruntergeteilt, z.B durch 8 , dann würde der Timer nur nach jedem 8. Tick den Wert um 1 erhöhen. Nachdem der Timer überläuft also bis 255 gezählt hat fängt er wieder bei 0 an.

Wenn mein Prozessor also mit einem Systemtakt von 1 MHz arbeitet und der Systemtakt mit Hilfe des Prescalers durch 8 heruntergeteilt wird, würde der Timerwert alle (1000000 /8)   125000 Takte um 1 erhöht.  Also würde alle  (125000 / 255 = ) 490 Takte ein Interrupt ausgelöst.
Wenn ich mit diesem Interrupt eine Led Toggeln würde, würde sich dieser Takt noch einmal halbieren , und man kommt auf 245 Hz

Mode 1

1


0



PWM, Phase Correkt
Mode 2

0


1



CTC - Clear Timer on Compare (CTC) Modus
Alle Timer/Counter des ATMega32  besitzen diesen Modus.
Stimmt das TCNTx Register mit dem Vergleichsregister OCRx überein, wird das TCNTx Register auf 0 gesetzt und bei aktiviertem Timer/Counter Overflow Interrupt wird dieser ausgelöst. Zum aktivieren des CTC-Modus müssen die WGM-Bits
(Waveform Generation Mode) im TCCRx Register entsprechend gesetzt sein. Dieser Modus ermöglicht es periodisch einen Timer Overflow Interrupt auszulösen, wobei die Zeit zwischen 2 Interrupts verändert werden kann
Mode 3

1


1



Fast PWM
Prescaler





0
0
0
Timer Anhalten
Prescaler




0
0
1
Timer Takt durch 1
Prescaler




0
1
0
Timer Takt durch 8
Prescaler




0
1
1
Timer Takt durch 64
Prescaler




1
0
0
Timer Takt durch256
Prescaler




1
0
1
Timer Takt durch1024
Prescaler




1
1
0
Externer Takt an T0 (Pin 6 beim Atmega 8)
Prescaler




1
1
1
Externer Takt an T0 steigende Flanke
Compare Output Mode

0
0




Timer Pin OC0 ist nicht verbunden mit Ausgangspin
Compare Output Mode

0
1




Ausgangspin schaltet um beim Überlauf
Compare Output Mode

1
0




Setzt Ausgangspin OC0 auf 0 beim Überlauf
Compare Output Mode

1
1




Setzt Ausgangspin OC0 auf 1 beim Überlauf
nach oben









Beispiel mit Timer0 beim Atmega 32
$regfile "m32def.dat Definiert den Atmega als Atmega 32
$crystal = 16000000 Gibt die Quarzfrequenz an in Herz
On Timer0 Timer_null Routine die bei Timerüberlauf ausgeführt wird
Ddra.7 = 1 
Port A.7 als Ausgang setzen
Ddra.6 = 1 Port A.6 als Ausgang setzen
Tccr0 = 00000101
Teilerfaktor setzen ( teilt durch 1024)
Timsk.toie0 = 1
Interrupt für Timer0 einschalten
Sreg.7 = 1 Interrupts Gloabal setzen
Do Anfang Programmschleife
Waitms 500 
Pause
Toggle Porta.6 Zustand einer Led wechseln
Waitms 500 Pause
Loop
Schleifenende
Timer_null:
Timer Routine
Toggle Porta.7
Ausgangspin A.7 wechseln ( Led)
Return
Routine beenden

Achtung: Timer0 funktioniert nicht wenn Analogeingänge genutzt werden, weil dann Timer für die Analogeingänge benutzt wird.

Timer 2
ist ein 8 Bit Timer ( 0-255 ), der alle Funktionen des Timer0 besitzt, außer dem Zählen von Taktflanken. Dafür verfügt er über die Möglichkeit einen 32Khz Uhrenquarz als Taktquelle für den Timer zu nutzen. Damit wird ein asynchroner Timer möglich, der unabhängig vom Takt ist. Dieser ist mindestens 4 mal langsamer und ermöglicht so auch das Messen weitaus längerer Zeitabstände.
Ausgabe Pin für Timer 2 = OC2
Ausgabe Pin für Timer 2 = OC2
Anzahl der Bits Die Anzahl der Bits gibt an bis zu welchen Wert der Timer zählen kann, bevor ein Überlauf statt findet und er wieder von vorne anfängt zu zählen.Ein 8 Bit Timer kann bis 255 zählen, das wäre als Binärzahl ( 11111111) oder als Hex Zahl ( FF ).
Ein 16 Bit Timer zählt demnach bis 65535 , das wäre als Binärzahl ( 1111111111111111 ) oder als Hex Zahl ( FFFF )
Taktflanken zählen
Einige Timer besitzen die Möglichkeit von außen angelegte Signale zu zählen , beim Atmega 16 ist das der Anschluß T0 (PinPB0) für Timer 0, und beim Timer 1 am Anschluß T1(Pin PB1) dabei kann gewählt werden ob die Negative oder die Positive Flanke zum zählen herangezogen wird.
CTC=
Clear Timer on Compare (CTC) Modus Alle Timer/Counter des ATMega32 besitzen diesen Modus.
Stimmt das TCNTx Register mit dem Vergleichsregister OCRx ¨ uberein, wird das TCNTx Register auf 0 gesetzt und bei aktiviertem Timer/Counter Overflow Interrupt wird dieser ausgelöst. Zum aktivieren des CTC-Modus müssen die WGM-Bits (Waveform Generation Mode) im TCCRx Register entsprechend gesetzt sein. Dieser Modus ermöglicht es periodisch einen Timer Overflow Interrupt auszulösen, wobei die Zeit zwischen 2 Interrupts verändert werden kann


PMW
Pulsweitenmodulation
PWM mit variabler Periode

zus. unabhängiges Verglkeichsregister

Input Capture Unit

Erlaubt 32 Khz Uhrenquraz
Asynchronen Betrieb , nur für Uhren Quarz
Prescaler
Der Prescaler ( Vorteiler ) hat eine Größe von 10 Bit = Dezimal 1023 , der es den Timern erlaubt die Taktfrequenz durch festgelegt Werte zu teilen
nach oben
Beispiel mit Timer 2 am Atmega 32
$regfile "m32def.dat" Definiert den Atmega als Atmega 32
$crystal = 16000000
Gibt die Quarzfrequenz an in Herz
Ddra.7 = 1
Ddra.6 = 1
On Timer2 Timer_zwei
Routine die bei Überlauf angesprungen wird
Tccr2 = &B00000101
Timsk = &B01000000 Interrupt für Timerüberlauf von Timer2 einschalten
Sreg.7 = 1 Globale Interrups freigeben
Do
Toggle Porta.6
Waitms 300
Loop
Timer_zwei:
Toggle Porta.7
Return

 nach oben

Die Berechnung des Comparewert geht folgendermaßen
Compare1A= Osszilatorfrequenz / Prescaler/Gewünschte Frequenz / 2








Bascom Instruktionen oder Register Anweisungen
Timer können mit Bascom Instruktionen  konfiguriert werden oder über direkte Register-Anweisungen beim 16 Bit Timer1  im Atmega 32 haben wir zwei Pseudoregister in denen die Konfiguration vorgenommen werden kann eigentlich ist es nur 1Register mit 16 Bit was aber in zwei Pseudoregister a 8 Bit aufgeteilt wurde.
Einmal das Register TCCR1A und das Register TCCR1B wobei die Register folgende Bedeutung haben:

Die Möglichkeit die Timer über den Weg der Register einzustellen und zu konfigurieren bietet einige Vorteile gegenüber der Eingabe in Bascom Befehle.
 Zum einen ist die Eingabe in weniger Zeilen zu programmieren , und das  Compilieren geht schneller auch wird  weniger Platz im Flash beansprucht, und nicht zuletzt , das die Register eine Menge von Möglichkeiten bietet die alle auch im Datenblatt beschrieben sind
.
z.B. kann man  folgenden Befehl eingeben um die Interrups Global freizugeben:
Enable Interrups
oder über das Register folgendes :
SREG.7=1
beides hat die gleiche Bedeutung und beides führt zum Ziel.

 nach oben

Mögliche Timer Konfigurationsmöglichkeiten 
Achtung Timer Instruktionen müssen alle in einer Zeile geschrieben werden, wobei jede der Anweisung durch ein Komma voneinander gernnt wird.
Config Timer1 = Counter ( Timer, PWM )
Timer als Zähler oder Timer
Edfge=Rising (Falling)
Externes Signal bei fallender Flanke erkennen
Prescaler= 1 (8,64,256,1024)
Vorteiler einstellen
Noise Cancel=1 (0)
Bei 1 muss externes Siganl innerhalb einer gewissen Zeit drei mal hintereinader  unverändert bleiben um als Signal erkannt zu werden.
Capture Edge = Rising ( Falling)


Clear Timer = 1 (0)

Compare A=Clear Set Toggle Disconnect

Compare B=Clear Set Toggle Disconnect
PWM=8 (9,10)
Auflösung in 8,9 oder 10 Bit
Compare A  PWM = Clear Up ; Clear Down, Disconnect

Compare B PWM = Clear Up ; Clear Down, Disconnect
Stop Timer 0  oder Start Timer 0 Timer 0  anhalten  oder Timer 0 starten
nach oben

Beispiel Timer 0
z.B Timer 0 in Bascom Anweisúngen
Programmzeile
Beschreibung
Config Timer0 = Timer , Prescale = 256
bestimmt das Timer 0 verwendet wird , und teilt den Timertakt durch 256
Enable Timer0 startet Timer 0
On Timer0 Timer_null Bei einem Überlauf von Timer 0 , soll in die entsprechende Unterroutine Timer_null gesprungen werden.








Timer_null:
nach hier soll gesprungen werden wenn Timer 0 einen Überlauf verzeichnet
toggle Porta.1
Wechselt Ausgang von Hig auf Low dann von Low auf High usw  ( z.B. Led)




Return
zurück springen



nach oben
Timer0 beim Atmega 32
Timer0 beim Atmega 32 als Registeranweisungen
$regfile "m32def.dat" 
Definiert den Atmega als Atmega 32
$crystal= 16000000  Gibt die Quarzfrequenz an in Herz
On Timer0 Timer_null
Routine die bei Timerüberlauf ausgeführt wird
Ddra.7 = 1
Port als Ausgang setzen
Ddra.6 = 1 Port A.6 als Ausgang setzen
Tccr0 = 00000101 Teilkerfaktor setzen
Timsk.toie0 = 1
Interrupt für Timer0 einschalten
Sreg.7 = 1
Interrupts Gloabal setzen
Do Anfang Programmschleife
Waitms 500
Toggle Porta.6
Waitms 500
Loop
Schleifenende
Timer_null:
Timer Routine
Toggle Porta.7 
Ausgangspin A.7 wechseln
Return
Routine beenden




nach oben
Timer als Counter
Timer0 beim Atmega 8  benutzt man auch als Counter, wenn zum Beispiel  externe Ereignisse gezählt werden sollen, in diesem Fall hat der Prescaler ( Vorteiler) keine Funktion.
Bei der Erfassung externer Impulse für den Counter kann man nur bestimmte Eingänge des Atmega's nutzen, nämlich den Eingang mit der Bezeichnung T0 für Timer 0 oder T1 ( nicht beim Atmega 8) für Timer 1 .
Beim Atmega 8 ist der Eingang T0 für Timer Null gleich mit Pin PD4. Bei der Konfiguration als externer Zähler gibt es die Möglichkeit die externen Impuls mit der ansteigender oder
abfallender Flanke zu zählen .Beim Counter wird das eigentliche Programm zeitlich nicht vom Counter beinflusst.
Die zu erfassende Frequenz beim Eingang T0 ist abhängig der eingesetzter Taktfrequenz des Atmega's und beträgt etwa 40% des Systemtaktes
Um den Timer voreinzustellen , also den  Comparewert einzugeben kann man Timerx gleich 65363 eingeben oder  auch den Befehl Load benutzen, damit rechnet der Compiler selber die Vorgabe Werte aus. Also z.B.   Load TimerX,200
Hier einige Beispiele für die Verwendung von Timer


Atmega 32 und Atmega 8 als Sekundentaktgeber mit Timer 1
$regfile "m32def.dat"    'Definiert den Atmega als Atmega 32
$crystal = 16000000      'Gibt die Quarzfrequenz an in Herz
$hwstack = 32            ' default use 32 for the hardware stack
$swstack = 10            ' default use 10 for the SW stack
$framesize = 40
Timer 1 konfigurieren
On Timer1 Routine_timer_1       ' Routine die bei Überlauf angesprungen wird
Tccr1a = &B00000000
Tccr1b = &B00000101      'Takt durch 1024 teilen
Timsk = &B00000100       ' Interrupt für Timerüberlauf von Timer1 einschalten
Timer1 = 49911           ' Timer Vorgabewert um auf 1 Sekunde zu kommen
SREG.7=1 ' Interrupt Global freischalten
Programm
Do
Loop
Timer 1 Routine
Routine_timer_1:

Timer1 = 49911
 Porta.1 = 1
 Waitms 10
 Porta.1 = 0
         
Return

nach oben
Atmega 32 als Zähler mit Timer0

Als Messeingang wird Pin1 benutzt
Ein Ausgänge definieren
Config Porta = Output
Ddrd = &B10110000        ' Port D4 ,D.5 und D.7 als Ausgang setzen
Ddrb = &B00000000        ' Port B als Eingänge setzen
Portb = &B11111111       ' PullUp von Port B aktivieren
Variablen
Dim Timerwert As Long
Dim Timerwert_neu As Long
Konfiguration fürs Display
Config Lcd = 20 * 4      'definiert das LCD Display in Art und Größe
Config Lcdpin = Pin , Db4 = Portc.2 , Db5 = Portc.3 , Db6 = Portc.6 , Db7 = Portc.7 , Rs = Portc.5 , E = Portc.4
Portd.7 = 0
Cls
Timer0 konfigurieren für Zähler Eingang
Sreg = &B10000000      ' Allgemeine Interrupt Freigabe
Timsk = &B00000001     ' interrupt für Timer Null freigeben
On Timer0 Routine_timer_0       ' Routine die bei Überlauf angesprungen wird

Tccr0 = &B00000111     ' Zählt externen Takt mit steigender Flanke
' TCCR0=&B00000110 'zählt externen Takt mit fallender Flanke
Programmschleife Anfang
Do
Toggle Porta.7
Waitms 200

Gosub Anzeige

Timerwert = Timer0       ' Timero inhalt in Timerwert zwischen speichen
Timerwert = Timerwert + Timerwert_neu

Loop
Timer 0 Routine
Routine_timer_0:
Timerwert_neu = Timerwert_neu + 255
' Weil Timer nur bis 255 zählt wird nach jedem überlauf 255 hinzuaddiert

Toggle Porta.0           ' Erste grüne Led blinkt

Return
Display Anzeige
Anzeige:
Cls
Locate 1 , 1
Lcd "Impulse=" ; Timerwert
Locate 4 , 1
Waitms 100
Return
nach oben
Und so berechnen wir beim Timer 1 den Startwert, wenn wir eine gewünschte Frequenz haben wollen.
Als angenommen die Ausgabe Frequenz soll 4500 Hz sein, dann rechnen wir folgendermaßen:
Startwert= 65536 - ( Aktueller Controllerfrequenz/ Vorteiler/gewünschte Frequenz)
Startwert = 65536 -( 1 Mhz / 1/4500)
Startwert = 65536- 222
Startwert= 65313


50 Hz mit Timer 1 (Atmega 8)
' 50 Hz

$regfile "m8def.dat"                                                                                                    ' Definiert den Atmega als Atmega8
$crystal = 16000000                                                                                                     'Gibt die Quarzfrequenz an in Herz
$hwstack = 32                                                                                                           'Default use 32 Hardware reservierte Speicher
$swstack = 10                                                                                                           'Default Software resvierung Speicher
Config Lcd = 16 * 2                                                                                                     ' Display Bezeichnung
Config Lcdpin = Pin , Db4 = Portc.3 , Db5 = Portc.2 , Db6 = Portc.1 , Db7 = Portc.0 , Rs = Portc.5 , E = Portc.4        ' Konfiguration fürs Display

'------------------------------ I/O ----------------------------------------------------------------------
Ddrd.0 = 1
Ddrb.2 = 1
Ddrb.0 = 1
                                                                                                            ' Led rot
'-------------------------------------- Variable --------------------------------------------------------
'-------------------------------------- Timer 1 --------------------------------------------------------
On Timer1 Routine_timer_1                                                                                               ' Routine die bei Überlauf angesprungen wird
Tccr1a = &B00000000
Tccr1b = &B00000101                                                                                                     'Takt durch 1024 teilen
Timsk = &B00000100                                                                                                      ' Interrupt für Timerüberlauf von Timer1 einschalten
Timer1 = 65378                                                                                                          ' Timer Vorgabewert um auf 1 Sekunde zu kommen
Sreg.7 = 1                                                                                                              ' Interrupt Global freischalten

Do
Waitms 500                                                                                                              ' Anfang Programmschleife
Toggle Portd.0
Waitms 500
Loop

 '--------------------------------- Timer 1 Routine --------------------------------------------------
 Routine_timer_1:
 Timer1 = 65378
 Toggle Portb.2
Return



Timer1 Vorgabe wird wie folgt berechnet:
65536-((Cotrollerfrequenz / Vorteiler/gewünschte Frequenz) /2)
65536 - (( 16 000 000 : 1024 : 50) : 2
= 65378
nach oben
Aktualisiert 17.04.2021
Copyright by Ms 2009