Go Down

Topic: Welcher Timer für was? (Read 14668 times) previous topic - next topic

Chris72622

Mar 30, 2014, 10:01 pm Last Edit: Mar 30, 2014, 11:01 pm by Chris72622 Reason: 1
Hallo,

ich lese immer wieder von Timern. Mittlerweile habe ich ein Projekt am laufen, in dem dies Sinn macht und zudem auch gut funktioniert.

Warum ich mich jedoch gerade diesen Timer (Timer1) und nicht für einen Anderen entschieden habe, konnte ich zum Start des Projekts mangels Wissen nicht sagen.

Gibt es irgendwo eine Übersicht/Tabelle über die unterschiedlichen Timer-Varianten aus der hervorgeht wo deren Vor- und Nachteile sind, bzw. was deren "gängige Einsatzgebiete" wären?

Gruß Chris
Bilnk wtiohut daley.

Serenifly

#1
Mar 30, 2014, 10:22 pm Last Edit: Mar 30, 2014, 10:27 pm by Serenifly Reason: 1
Auf Timer0 läuft millis() und delay(). Daher scheidet der aus, wenn man das verwenden will.

Timer2 ist ein 8 Bit Timer (wie Timer0), aber er hat mehr Prescaler Einstellungen als Timer1. Für schnelle Sachen wird er daher gerne genommen, da er sehr flexibel ist was das Einstellen der Zeiten betrifft.

Timer1 und Timer3 aufwärts (auf dem Mega) sind 16 Bit Timer. Wenn man also lange Zeiten zählen will kann das Vorteile haben, da die nicht so schnell überlaufen. Bei den Timern gibt es noch den Input Capture Modus, aber das braucht man auf dem Arduino eher selten bis gar nicht, da man Signale auch recht gut mit millis() und micros() messen kann. Und es gibt mehr PWM Modi als auf Timer2, was aber in der Praxis auch nicht weiter relevant ist.

Ansonsten funktionieren die aber alle grob gleich. Wenn man einen versteht, versteht man auch die meisten Funktionen der anderen Timer.


Hier ist ein gutes Tutorial:
http://maxembedded.com/2011/06/22/introduction-to-avr-timers/
Wobei es da ein, zwei Stellen gibt bei denen die Register nicht mit den größeren Atmegas übereinstimmen (vor allem hat jeder Timer ein eigenes TIMSK Register! TIMSK0, TIMSK1, TIMSK2. Die Teilen sich nicht ein Register wie bei dem Prozessor im Tutorial). Es lohnt sich daher auch mal die Registerbeschreibung im Datenblatt des Prozessors zu lesen.

Chris72622

+Karma *klick*  ;)

1000 Dank.

Gruß Chris
Bilnk wtiohut daley.

Serenifly

#3
Mar 30, 2014, 10:35 pm Last Edit: Mar 30, 2014, 10:40 pm by Serenifly Reason: 1
Hier ist noch eine brauchbare Einstiegs-Anleitung auf Deutsch:
http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial/Die_Timer_und_Z%C3%A4hler_des_AVR
Und teilweise noch das:
http://www.mikrocontroller.net/articles/AVR-Tutorial:_Timer

Gerade für den Anfang ist das da gut erklärt. Auch hier gilt dass die Register auf dem Atmega328 und Atmega2560 an ein, zwei Stellen anders sind! Vor allem TIMSK - das Timer Interrupt Masken Register. Und das TIFR Register, wobei man letzteres nicht per Hand anfassen muss.

Da ist auch erklärt wie man Timer2 mit einem Uhrenquarz als RTC verwenden kann. Das ist wieder eine Anwendung die auf dem Arduino nicht relevant ist, da man leicht eine externe RTC verwenden kann.


Was C Code betrifft, bist du aber bei MaxEmbedded besser beraten


EDIT:
Und auf den ATinys sind die Register noch mal ganz anders aufgebaut. Da muss man dann wirklich das Datenblatt lesen. Wobei das da im Datenblatt viel besser beschrieben ist. Auf den ATinys gibt es z.B. sehr hohe Prescaler Einstellungen und PWM ist benutzerfreundlicher gemacht und erklärt.

Doc_Arduino

#4
Mar 31, 2014, 12:00 am Last Edit: Mar 31, 2014, 12:04 am by Doc_Arduino Reason: 1
Hallo,

eine Ergänzung zu den ausführlichen Links von Serenifly, eine Zusammenfassung aus einem englischen Buch, weil die Möglichkeiten doch sehr vielfältig sind. Standardmäßig arbeiten die Timer an Pin 5, 6 mit 1kHz und an Pin 3, 9, 10, 11 mit 500Hz. Änderungen an Timer0 haben Auswirkungen auf die Funktionen delay, millis und micros.

Code: [Select]

TCCR0B = TCCR0B & 0b11111000 | <setting>; //Timer 0 (PWM pins 5 & 6)
TCCR1B = TCCR1B & 0b11111000 | <setting>; //Timer 1 (PWM pins 9 & 10)
TCCR2B = TCCR2B & 0b11111000 | <setting>; //Timer 2 (PWM pins 3 & 11)

Available PWM Frequency Settings for Each Arduino System Timer
Arduino Timer   <setting>   Divisor   Frequency (Hertz)
0 (pins 5 and 6)   0x01   1   62500
0 (pins 5 and 6)   0x02   8   7812.5
0 (pins 5 and 6)   0x03   64   976.56
0 (pins 5 and 6)   0x04   256 244.14
0 (pins 5 and 6)   0x05   1024        61.04
1 (pins 9 and 10)   0x01   1   31250
1 (pins 9 and 10)   0x02   8   3906.25
1 (pins 9 and 10)   0x03   64   488.28
1 (pins 9 and 10)   0x04   256   122.07
1 (pins 9 and 10)   0x05   1024   30.52
2 (pins 3 and 11)   0x01   1   31250
2 (pins 3 and 11)   0x02   8   3906.25
2 (pins 3 and 11)   0x03   32   976.56
2 (pins 3 and 11)   0x04   64   488.28
2 (pins 3 and 11)   0x05   128   244.14
2 (pins 3 and 11)   0x06   256   122.07
2 (pins 3 and 11)   0x07   1024   30.52
Tschau
Doc Arduino '\0'

Messschieber auslesen: http://forum.arduino.cc/index.php?topic=273445
EA-DOGM Display - Demos: http://forum.arduino.cc/index.php?topic=378279

Serenifly

Genauer gesagt ist das eine Tabelle für die Frequenz an den PWM Pins. Es kann ratsam sein diese auf ihr Maximum zu erhöhen wenn man die Frequenz am Verbraucher hört.

Doc_Arduino

Hallo,

sind das nicht eher die einstellbaren Frequenzen der Timer, nur das diese an die "PWM Pins" herausgeführt werden?
Tschau
Doc Arduino '\0'

Messschieber auslesen: http://forum.arduino.cc/index.php?topic=273445
EA-DOGM Display - Demos: http://forum.arduino.cc/index.php?topic=378279

Serenifly

Die Frequenz der Timer ergibt sich aus der Kombination von Prescaler und Compare Match Register. Hier ist der Vergleichs-Wert fest und man ändert nur den Prescaler.

Wenn man noch mit dem Vergleichs-Wert herumspielt, kann man je nach PWM Modus glaube ich auch noch andere Frequenzen einstellen. z.B. die 38kHz bei IR-Sendern. Das kann man auch mit PWM machen.

Spexx

Hab zwar noch nicht alles verstanden, aber dein Posting hört sich interessant an @Serenifly.
Dafür muss man wohl den CTC-Modus aktivieren, oder? Auf welchen festen Wert steht der Vergleichs-Wert ansonsten?
Hat jemand ein (Arduino-)Beispiel hierfür?

Also letztendlich würde mich es interessieren, ob man auch eine Frequenz von 25 kHz erzeugen kann. Dieser Wert wird üblicherweise von PWM-Lüftern verwendet. Der nächste Wert der ansonsten in der Nähe liegen würde wäre 31,25 kHz...

Serenifly

#9
Mar 31, 2014, 03:47 pm Last Edit: Mar 31, 2014, 03:51 pm by Serenifly Reason: 1
Das hängt vom PWM Modus ab. Da gibt es zig verschiedene. Auf dem Arduino läuft Timer0 auf Fast PWM und Timer1 und Timer2 in phase-correct PWM

Schau ins Datenblatt
http://www.atmel.com/Images/doc8161.pdf

Den Teil verstehe ich aber auch nicht komplett. Bei MaxEmbedded gibt es auch zwei Tutorials zu PWM:
http://maxembedded.com/2011/08/07/avr-timers-pwm-mode-part-i/
http://maxembedded.com/2012/01/07/avr-timers-pwm-mode-part-ii/

Da steht z.B.:
Quote

The following code discusses how to create a PWM signal of a desired duty cycle. If you wish to change its frequency, you need to alter the TOP value, which can be done using the ICRx register (which is not supported by 8-bit timers). For 16-bit Timer1, it can be varied using ICR1A. I will discuss about this soon when we discuss about servo control.

Ok, das mit dem Compare Register war dann falsch. Das ändert den Duty Cycle. Aber es geht auch anders.


Ob das jetzt Arduino Code oder AVR C ist, ist egal. Der Code da lässt sich sehr leicht anpassen. Reinen Arduino Code auf der Ebene ist eher selten, da das kein Anfänger Thema ist.

Doc_Arduino

Hallo,

Quote

Also letztendlich würde mich es interessieren, ob man auch eine Frequenz von 25 kHz erzeugen kann. Dieser Wert wird üblicherweise von PWM-Lüftern verwendet. Der nächste Wert der ansonsten in der Nähe liegen würde wäre 31,25 kHz...


Die Tabelle zeigt alle möglichen Kombinationen. Deine Wunschfrequenz von 25kHz ist nicht dabei. Man muß sich dann mit der nächst passenden begnügen. Was noch möglich wäre, den Takt der CPU von 16 auf 8 oder 4MHz runterzunehmen und damit die möglichen Frequenzen zu halbieren oder zu vierteln. Ob das Sinn macht kommt darauf an was der µC sonst noch so machen muß. Oder man muß einen externen "PMW IC anbauen" der mehr Optionen bietet.



Tschau
Doc Arduino '\0'

Messschieber auslesen: http://forum.arduino.cc/index.php?topic=273445
EA-DOGM Display - Demos: http://forum.arduino.cc/index.php?topic=378279

Serenifly

Je nach Timer und Modus sollte man die Frequenz auch frei einstellen können. Wenn man auf den Arduino Kram verzichtet und das per Hand macht.

Schau dir mal die Tabelle auf Seite 136 des Atmega328 Datenblatts an. Auf Timer1 läuft auf dem Arduino glaube ich PWM in Modus 1. Phase correct aber mit einem festem TOP von 0xFF. Das heißt der Timer läuft immer von 0 bis 0xFF und wieder zurück und schaltet beim Wert des Compare Match Registers einen Ausgang am.

Es gibt aber unten auch Modi mit variablem TOP Register! z.B Modus 10

Doc_Arduino

Hallo,

okay, wenn man Hardware nah programmiert stehen einem sämtliche Optionen offen. Da muß man erstmal durchblicken. Ich überblicke das nicht. Habe noch ein Bsp. Code von meinem R8C13 angeschaut, ja da konnte man alles machen. Falls man durchblickt.   :smiley-mr-green:
Tschau
Doc Arduino '\0'

Messschieber auslesen: http://forum.arduino.cc/index.php?topic=273445
EA-DOGM Display - Demos: http://forum.arduino.cc/index.php?topic=378279

Spexx

#13
Apr 01, 2014, 12:51 pm Last Edit: Apr 01, 2014, 02:43 pm by Spexx Reason: 1
Also alles verstanden habe ich auch nicht, aber habe beim Recherchieren noch paar Informationen gefunden  :)

Wenn ich das richtig gesehen habe, kann man mit dem CTC Modus ein Interrupt auslösen. Damit könnte man z.B. auch einen digitalen Pin toggeln, also ein- und ausschalten. In der Frequenz ist man glaube ich ziemlich variabel und könnte somit auch ein PWM-Signal erzeugen, jedoch mit festem Verhältnis von 50%.

Das 'richtige' gefunden habe ich dann aber auf der Seite von Nick Gammon. Hier ist ziemlich viel erklärt, wovon ich das meiste aber auch nicht so richtig verstanden habe  :D
http://www.gammon.com.au/forum/?id=11504

Interessant ist der Abschnitt "Simple timer output" oder der Nachfolgende "Frequencies and periods for various counter values". Dort sind Beispiele und auch eine Tabelle aufgeführt. Eine Frequenz von zum Beispiel 25 kHz kann mit folgendem Code erzeugt werden:
Code: [Select]
const byte OUTPUT_PIN = 3;  // Timer 2 "B" output: OC2B

const byte n = 79;

void setup()
{
 pinMode (OUTPUT_PIN, OUTPUT);

 TCCR2A = bit (WGM20) | bit (WGM21) | bit (COM2B1); // fast PWM, clear OC2A on compare
 TCCR2B = bit (WGM22) | bit (CS21);         // fast PWM, no prescaler
 OCR2A =  n;                                // from table  
 OCR2B = ((n + 1) / 2) - 1;                 // 50% duty cycle
 }  // end of setup

void loop() { }


Hierbei wird ein Prescaler von 8 verwendet. Das Tastverhältnis kann über OCR2B verändert werden, kann auch in der loop() geschehen.

Doc_Arduino

Hallo,

Danke für den Link, ist erstmal gespeichert. Ist ganz schön viel Stoff. Ich glaube das beackert man nur wenn man es wirklich braucht.   ;)

Tschau
Doc Arduino '\0'

Messschieber auslesen: http://forum.arduino.cc/index.php?topic=273445
EA-DOGM Display - Demos: http://forum.arduino.cc/index.php?topic=378279

Go Up