Hallo. Ich spiele im Moment mit den Timer/counter optionen eines Atmega
2560.
hier ist die Code:
1
#include<avr/io.h>
2
#include<avr/interrupt.h>
3
4
// initialize timer
5
6
voidtimer1_init(){
7
8
// Set up timer to toggle OC1A on match of OCR1A in CTC mode
9
TCCR1A|=(1<<COM1A0);
10
11
// set up timer with prescaler = 1024 and CTC mode
12
TCCR1B|=(1<<WGM12)|(1<<CS11)|(1<<CS10);
13
14
// Set CTC compare value to 1Hz at 16MHz AVR clock, with a prescaler of 1024
15
// whenever a match occurs OC1A toggles
16
17
OCR1A=15624;
18
19
}
20
voidtimer4_init(){
21
TCCR4A|=(1<<COM4C0);
22
TCCR4B|=(1<<WGM42)|(1<<CS41)|(1<<CS40);
23
OCR4C=15000;
24
}
25
intmain(void){
26
27
// connect led to pin PB5
28
DDRB=(1<<PB5);// OC1A output is on PB5
29
DDRH=1<<PH5;
30
// initialize timer
31
timer1_init();
32
timer4_init();
33
// loop forever
34
while(1){
35
// do whatever
36
}
37
}
timer1_init() habe ich aus einem Forum geklaut.
Mir ist eigentlich klar, was welches Bit bedeutet, deswegen habe ich mal
versucht für einen besseren Lerneffekt einen fast identischen
timer4_init() mit TC4 zu schreiben.
Doch hier funktioniert irgendwas nicht!:(
Die LED an "OC4C" ist permanent AN.
Ich vermute, es liegt einfach daran, dass das Bit "COM4C0" nicht auf
Eins gesetzt wird. Dies sehe ich , wenn ich die Code in Simulationsmodus
debugge.
In Atmega2560 Datasheet wird über den TC4 nichts besoderes gesagt, also
solte das Register ähnlich funktionieren.
Was mache ich falsch?
Hier ist nochmal Atmega2560 Datasheet:
http://www.atmel.com/Images/doc2549.pdf
Hi
>Darf ich mal fragen, wo diese Info steht?:)
Sieh mal unter 'Modes of Operation' nach. Als Topwert für CTC kann
entweder OCRnA (Mode 4) oder ICRn (Mode 12) fungieren.
MfG Spess
Hallo,
will am Handy nicht ins Datenblatt schauen, hab keine Lupe dabei, aber
mal folgende Überlegung:
Du setzt das COM4C0. Also toggeln bei Treffer. Aber wo ist der Treffer?
Du kannst PIN A nicht sinnvoll benutzen, weil Du OCR4A als top-Wert
brauchst, ich meine PIN A toggelt dann eben immer bei TOP. OCR4A setzt
Du ja auch.
Aber wo ist der compare-Wert für C? Du musst OCR4C auch noch setzen und
zwar auf einen Wert OCR4C < OCR4A ?
Vlg
Timm
Hi
>OCR4A setzt Du ja auch.
Nein, setzt er nicht. Der Timer läuft bei CTC immer bis OCRnA+1. Da der
Initialwert von OCR4A nach Reset Null ist läuft der Timer also bis 1 und
fängt dann von Null wieder an.
MfG Spess
Hallo,
spess53 schrieb:> Hi>>>OCR4A setzt Du ja auch.>> Nein, setzt er nicht.
uaahh! Hab ich doch glatt gelesen, was ich lesen wollte! Recht hast Du!
Habe einfach OCR4A gelesen, wo OCR4C steht.
Also Anton: Setze OCR4A auf einen Wert größer als OCR4C, sonst passiert
auf dem Pin C nichts.
Vlg
Timm
Danke für ihre schnelle Antworten.
Ich bin jetzt einwenig durcheinander:)
Nach dem ich die AVR tutorials und Datasheet gelesen habe, habe ich es
so verstanden, dass:
TCCR4A |=(1<<COM4C0) <<<-- Hier wird gesagt, toggle Ausgang OC4C beim
Treffer mit dem gewünschtem Wert (Für den C Ausgang wird der OCR4C
genommen).
TCCR4B |= (1 << WGM42)| (1<<CS41)| (1<<CS40) ;<<<---Prescaler und Modus
auswählen.
Und jetzt dachte ich mir, ich muss nur noch OCR4C definieren, und das
wars. Wäre ja logisch, dass PIN C mit dem dazugehörigen Wert verglichen
wird. So wie bei "timer1_init()" oben.
Doch jetzt sehe ich, dass ich doch "OCR4A" brauche, obwochl ich den PIN
A nich benötige.
Die Funktion
1
voidtimer4_init(){
2
TCCR4A|=(1<<COM4C0);
3
TCCR4B|=(1<<WGM42)|(1<<CS41)|(1<<CS40);
4
OCR4C=10000;
5
OCR4A=10001;
6
}
get in der tat.
Kann mich hier jemand bitte aufklären, wo mein denkfehler ist?:)
Hallo,
Anton R. schrieb:> Nach dem ich die AVR tutorials und Datasheet gelesen habe, habe ich es> so verstanden, dass:>> TCCR4A |=(1<<COM4C0) <<<-- Hier wird gesagt, toggle Ausgang OC4C beim> Treffer mit dem gewünschtem Wert (Für den C Ausgang wird der OCR4C> genommen).
Ja, richtig.
> TCCR4B |= (1 << WGM42)| (1<<CS41)| (1<<CS40) ;<<<---Prescaler und Modus> auswählen.
Perfekt.
> Wäre ja logisch, dass PIN C mit dem dazugehörigen Wert verglichen> wird.
Ist ja auch so. Toggle bei match mit OCR4C.
> So wie bei "timer1_init()" oben.
Das Beispiel funktioniert, ist aber irreführend.
> Doch jetzt sehe ich, dass ich doch "OCR4A" brauche, obwochl ich den PIN> A nich benötige.
Der Timer zählt bis zu einer Obergrenze. Im CTC Modus wird die
Obergrenze immer, ohne Ausnahme durch OCRnA gestgelegt. Du brauchst aber
wie in den anderen Modi immer noch einen Compare-Match Wert für den PIN.
Bei A natürlich nicht, da sind in diesem Modus TOP und Compare-Wert
identisch.
Du kannst also mit OCRnA sozusagen die Auflösung (oder Frequenz)
einstellen und mit OCRnB und C für diese Pins den Duty-Cycle. So ist das
gedacht.
Vlg
Timm
Hi
>Und jetzt dachte ich mir, ich muss nur noch OCR4C definieren, und das>wars.>Kann mich hier jemand bitte aufklären, wo mein denkfehler ist?:)
Du hast CTC mit dem Top-wert in OCR4A eingestellt. Damit bestimmt OCR4A
den Wert, bis zu dem der Timer zählt bis er wieder von Null anfängt.
Wenn du OCR4A nicht initialisierst hat das den Default-Wert (nach Reset)
von Null. Bei CTC zählt der Timer immer bis OCR-Wert+1. In dem Fall also
bis 1. Der Wert in OCR4C von 15000 wird also nie erreicht und das Pin
kann auch nicht wackeln.
MfG Spess
Hmm,
vielleicht noch nicht?
Die OCR Register bestimmen normalerweise ob der Zustand des Pins
geändert wird. Deswegen auch Output Compare Register.
Also normalerweise passiert etwas an Pin C (die restliche Konfiguration
passend vorausgesetzt), wenn der entsprechende Timer den Wert von OCRnC
annimmt.
Das besondere am CTC Modus ist nur, dass der Timer nicht bis 0xFF (oder
analog) hochzählt, sondern bis zu einem von Dir einstellbaren Top-Wert.
Dadurch ist die Auflösung nicht mehr auf 1/256 festgelegt, sondern du
kannst sie beliebig über den Top-Wert konfigurieren.
Dieser Top-Wert kann in dem von Dir gewählten Modus durch OCRnA
festgelegt werden, alternativ ginge noch ICRn. Das ist immer so. Die
normale Funktion steht also nur noch an den Pins B und C zur Verfügung:
Hochzählen bis Top (hier OCRnA) Pin-Zustand ändern bei Match mit OCRnx.
Da bei Pin A logisch zwingend Compare-Wert und Top-Wert identisch sind.
Vlg
Timm
spess53 schrieb:> Wenn du OCR4A nicht initialisierst hat das den Default-Wert (nach Reset)> von Null. Bei CTC zählt der Timer immer bis OCR-Wert+1. In dem Fall also> bis 1.
Nein, er zählt genau bis zum OCR-Wert. Bei 0 zählt er
0 - 0 - 0 - 0 - 0 ...
Wenn da z.B. eine 3 drin steht, zählt er
0 - 1 - 2 - 3 - 0 - 1 - 2 - 3 - 0 ...
Das +1 kommt ins Spiel, wenn man das als Takt-Teilung betrachtet. Bei 0
wird der Takt durch 1 (0+1) geteilt. Bei 3 wird durch 4 (3+1) geteilt.