Forum: Mikrocontroller und Digitale Elektronik Timer CTC Frage (TL5940 ansteuerung)


von timo91 (Gast)


Lesenswert?

hallo,

Das ist das erste mal das ich Timer verwende die genau miteinander 
arbeiten müssen. Ich nutze den Atmega16 mit einem 8Mhz quarz.

Ich möchte einen Timer im CTC Modus verwenden um den GSCLK Pin eines 
TLC5940 anzusteuern.
Einen zweiten Timer benötige ich, der nach exakt 4096 Takten am 
Output-Compate ausgang des ersten Timers (OC2) einen Interrupt auslöst. 
In diesem interrupt wird dann überprüft ob neue daten (Grayscale-Daten) 
gesendet werden sollen oder nicht.

Also Timer 1 =
- 8 Bit Bit Timer
- CTC modus
- ohne Vorteiler
- OCR0 so dimensioniert das er bei jedem 2-Takt den Output-Compare Pin 
(OC2) toggelt, also 4Mhz da der AVR auf 8Mhz läuft.

Also laut 
http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial/Die_Timer_und_Z%C3%A4hler_des_AVR#CTC-Betriebsart_.28Clear_Timer_on_Compare_Match.29

==

Ergibt also 1.
Richtig?

Doch jetzt bin ich etwas verwirrt bei der berechnung des 2. Timers.
Da nach jedem 2. Takt der Pin OC2 nur getoggelt und nicht gepulsed wird, 
wären das dann nicht nur 2Mhz anstatt 4Mhz?

Noch eine andere frage (Multimeter: Fluke 175): Solche 
Rechteckfrequenzen sollte ich im DC-Frequenz bereich doch messen können? 
Mein Multimeter zeigt nur kram an. Die Spannung ist VCC/2 also wird der 
ausgang getoggelt mit einen 50/50 Tastverhältnis.

mfg
timo

von timo91 (Gast)


Lesenswert?

Also ich habe jetzt auf einer anderen Seite das hier gefunden:
http://www.avr-modelleisenbahn.de/atmega8/13-8-2-clear-timer-compare-timer-2-atmega8.htm

Hier wird auch beschrieben wie mit einem Timer im CTC Modus an einem 
Ausgang eine Frequenz zu erzeugen.
Dort wird genau das beschrieben das ich vermutet hatte, das die 
Ausgangsfrequenz am PIN anderst berechnet wird (prescaler * 2) da ja am 
Pin getoggelt und nicht gepulsed wird.
Damit kann man eine Maximale frequenz von F_CPU/2 erreichen wenn OCR1 = 
0.

http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial/Die_Timer_und_Z%C3%A4hler_des_AVR#CTC-Betriebsart_.28Clear_Timer_on_Compare_Match.29

Sollte vielleicht editiert werden wenn es stimmt.

von Alex S. (thor368)


Lesenswert?

Tach timo,

> - OCR0 so dimensioniert das er bei jedem 2-Takt den Output-Compare Pin
> (OC2) toggelt, also 4Mhz da der AVR auf 8Mhz läuft.
mhhh, in dem Satz sind gleich zwei Unstimmigkeiten drin. Die erste: OCR0 
hat OC0 als output compare. Außerdem (wie du schon unten richtig erkannt 
hast): Es wird zwar mit 4MHz getoggelt aber die Frequenz des erzeugten 
Rechtecksignals beträgt 2MHz.

Mein Ansatz für den zweiten timer wäre recht einfach. Du willst alle 
4096 Takte einen interrupt haben. Also muss der zweite timer 4096 mal 
langsamer laufen als der erste. Am einfachsten geht das, indem du den 
prescaler auf 1024 setzt und das OCR auf 3. Fertig.
Das einzig kniffelige an der Sache ist, dass du die beiden timer auch 
synchron laufen lassen musst. Das geht eigentlich nur zuverlässig auf 
assembler basis. Der Trick ist die TCCRs bis auf die prescaler 
durchzukonfigurieren. Das sorgt dafür, dass die timer nicht loslaufen, 
bis du alle anderen Aufgaben erledigt hast. Dann musst du dir ausrechnen 
wie viele Takte du brauchst, um die prescaler bits eines timers zu 
setzen. Wenn man es klug anstellt schaft man das in ein oder zwei 
Takten. Auf diesen Wert musst du dann den TCNT des zu letzt gestarteten 
timers setzen. Dadruch hat er den passenden Vorsprung und läuft dann 
synchron mit dem ersten timer.

> Noch eine andere frage (Multimeter: Fluke 175): Solche
> Rechteckfrequenzen sollte ich im DC-Frequenz bereich doch messen können?
Nicht mit diesem Multimeter. Der Hersteller gibt eine maximale 
Bandbreite von 100kHz an.

Thor

von Alex S. (thor368)


Lesenswert?

Der Artikel hat schon recht.
Ist halt nur dit toggel Frequenz. Nicht die Rechteckfrequenz.

Thor

von timo91 (Gast)


Lesenswert?

Danke für die Antworten :)

Kann ich die Prescaler dann auch einfach mit inline-asm definieren?

von timo91 (Gast)


Lesenswert?

1
    TCCR0 |= ( (1<<WGM01) | (1<<COM00) | (1<<CS00) );
2
    OCR0 = 0;
3
4
    TCCR2 |= (1<<WGM20) | (1<<CS20) | (1<<CS21) | (1<<CS22);
5
    OCR2 = 7;
6
    TIMSK |=   (1<< OCIE2);

Timer0 Togglefrequenz = 8Mhz, Rechteckfrequenz = 4Mhz (jeden 2. Takt)
Timer2 Interruptfrequenz: Alle 8192 Zyklen

Somit wäre es perfekt dimensioniert wenn ich richtig liege. !! ??

Nur das einschalten der Timer muss ich jetzt über asm lösen.

von Karl H. (kbuchegg)


Lesenswert?

timo91 schrieb:

> Nur das einschalten der Timer muss ich jetzt über asm lösen.

Na ja

recht viele Möglichkeiten gibt es ja für den Compiler nicht, in dieser 
Sequenz
1
    TCCR0 |= ( (1<<WGM01) | (1<<COM00) );
2
    OCR0 = 0;
3
4
    TCCR2 |= (1<<WGM20);
5
    OCR2 = 7;
6
    TIMSK |=   (1<< OCIE2);
7
8
    TCCR2 |= (1<<CS20) | (1<<CS21) | (1<<CS22);
9
    TCCR0 |= (1<<CS00);

etwas anders zu lösen, als du das mittels Assembler auch könntest. Ob du 
in Assembler oder der Compiler das implementiert - ich will mich da 
jetzt nicht auf einen einzelnen Taktzyklus festlegen - ihr werdet beide 
beim gleichen Taktversatz landen.

von timo91 (Gast)


Lesenswert?

Wenn ich es so mache, dann blinken die LEDS mehr oder weniger.
Wo ist hier der fehler? Zu langsam? Reichen 4Mhz GSCLK nicht aus?

von Falk B. (falk)


Lesenswert?

Vielleicht falscher Presclaer?

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.