Forum: Mikrocontroller und Digitale Elektronik Vorteiler beim Timer 0 berechnen


von Matze (Gast)


Lesenswert?

Hallo,

ich habe ein Frage zum Timer 0 beim ATmega 16.
Ich möchte mit dem Timer 0  im CTC Mode ein 4 KHz Rechtecksignal 
erzeugen.
Der Systemtakt beträgt 8 MHz.

Wie berechne ich hier den entsprechenden Vergleichswert für das Register 
OCR0 und einen entsprechenden Vorteilerwert ?

Vielen Dank.

Grüße
Matthias

von Wolfgang (Gast)


Lesenswert?

Im Datenblatt Kap. 14.7.2 (Clear Timer on Compare Match (CTC) Mode) ist 
beschrieben, wie sich die Dauer des Ausgangspulses zusammen setzt. Der 
Kehrwert ist deine Ausgangsfrequenz. Die Formel für die Frequenz steht 
ziemlich am Ende des Kapitels. Der OCR-Wert muss kleiner als der 
Zählbereich des Timers (also 256 für Timer0) sein.

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Um aus 8.000.000 Hz ein 4.000 Hz Signal zu machen, musst du durch 2000 
teilen.
Praktisch ist also ein Vorteiler von 8 und ein CTC Wert von 249.

von zweifler (Gast)


Lesenswert?

Matthias S. schrieb:
> Um aus 8.000.000 Hz ein 4.000 Hz Signal zu machen, musst du durch 2000
> teilen.
echt?

> Praktisch ist also ein Vorteiler von 8 und ein CTC Wert von 249.
wirklich? und wie müssen dann die COM01 COM00 Bits stehen?

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

zweifler schrieb:
> echt?
Ja. Kannst du nachrechnen oder, wenn dir das zu hoch ist, dein Telefon 
machen lassen. Oder du fragst deinen Mathelehrer, der sich über ein 
wenig Interesse sicher freut.
> wirklich?
Ja, wirklich.
> und wie müssen dann die COM01 COM00 Bits stehen?
Tja, das ist natürlich schwierig, wenn man das Datenblatt des Mega16 
nicht hat, zumal der Vorteiler nichts mit dem COM Bits zu tun hat. Das 
überlasse ich dir als kleine Übung, mit der du evtl. Sonntag abend 
fertig bist - aber nur wenn du dir Mühe gibst.
Kleiner Tipp: die WGM Bits könnten auch nützlich sein.

: Bearbeitet durch User
von S. Landolt (Gast)


Lesenswert?

Der Zweifler wollte vermutlich darauf hinaus, dass man für die Erzeugung 
eines Rechecksignals das Doppelte seiner Frequenz benötigt, hier also 
Vorteiler /8 und OCR0=125-1 (bei 'Toggle OC0 on compare match').

von zweifler (Gast)


Lesenswert?

S. Landolt schrieb:
> Der Zweifler wollte vermutlich darauf hinaus, dass man für die Erzeugung
> eines Rechecksignals das Doppelte seiner Frequenz benötigt, hier also
> Vorteiler /8 und OCR0=125-1 (bei 'Toggle OC0 on compare match').

Genau! Manche glauben aber, daß sie schon so unfehbar sind, daß sie sich 
selber nicht mehr hinterfragen selbst bei Nachfragen nicht :-(

von Wolfgang (Gast)


Lesenswert?

Statt hier groß einen Thread aufzureißen, könnte man einfach einen 
Faktor für den Vorteiler setzen und gucken was raus kommt. Selbst ein 
Faktor 2 fällt einem da schnell auf und weist einen drauf hin, wo man 
noch Verständnissschwierigkeiten bei der Timerprogrammierung hat.

von S. Landolt (Gast)


Lesenswert?

> Statt hier groß ... gucken was raus kommt.
> Selbst ein Faktor 2 fällt einem da schnell auf ...

Schon richtig, aber so mancher Anfänger stolpert zum Beispiel über das 
'-1', der Zählung bei 0 beginnend ungewohnt, und da das je nachdem auch 
mal 4 Promille sein können, fällt es erstmal nicht auf.

von Wolfgang (Gast)


Lesenswert?

S. Landolt schrieb:
> Schon richtig, aber so mancher Anfänger stolpert zum Beispiel über das
> '-1', der Zählung bei 0 beginnend ungewohnt ...

Deswegen hatte ich den TO oben doch explizit auf die betreffende Formel 
im Datenblatt hingewiesen, in der doch ganz klar drin steht: "(1 + 
OCRn)" ;-)

von S. Landolt (Gast)


Lesenswert?

Eben, für z.B. einen solchen Hinweis wurde der Thread ja aufgemacht.
Oder meinten Sie mit "Thread aufzureißen" die Folgebeiträge?

Beitrag #5458014 wurde von einem Moderator gelöscht.
von Rolf M. (rmagnus)


Lesenswert?

zweifler schrieb:
> Genau! Manche glauben aber, daß sie schon so unfehbar sind, daß sie sich
> selber nicht mehr hinterfragen selbst bei Nachfragen nicht :-(

Andere wiederum meinen, dass ein "echt?" ganz klar und eindeutig zeigt, 
was sie damit meinen und halten jegliche Erklärung für überflüssig.

von Theor (Gast)


Lesenswert?

Rolf M. schrieb:
> zweifler schrieb:
>> Genau! Manche glauben aber, daß sie schon so unfehbar sind, daß sie sich
>> selber nicht mehr hinterfragen selbst bei Nachfragen nicht :-(
>
> Andere wiederum meinen, dass ein "echt?" ganz klar und eindeutig zeigt,
> was sie damit meinen und halten jegliche Erklärung für überflüssig.

Das sehe ich ähnlich. Die wesentlich kooperativere Antwort hätte 
zunächst das Problem mit der fraglichen Antwort und dann eine Lösung 
enthalten.
Im übrigen hat Matthias keinerlei Anlass gegeben ihn zu "erziehen". 
Seine Antwort war höflich und zweckgerichtet. Bedauerlich, dass sie 
falsch war, aber sie auf jeden Fall helfend gemeint.

von zweifler (Gast)


Lesenswert?

Matthias S. schrieb:
> zweifler schrieb:
>> echt?
> Ja. Kannst du nachrechnen oder, wenn dir das zu hoch ist, dein Telefon
> machen lassen. Oder du fragst deinen Mathelehrer, der sich über ein
> wenig Interesse sicher freut.
>> wirklich?
> Ja, wirklich.
>> und wie müssen dann die COM01 COM00 Bits stehen?
> Tja, das ist natürlich schwierig, wenn man das Datenblatt des Mega16
> nicht hat, zumal der Vorteiler nichts mit dem COM Bits zu tun hat. Das
> überlasse ich dir als kleine Übung, mit der du evtl. Sonntag abend
> fertig bist - aber nur wenn du dir Mühe gibst.
> Kleiner Tipp: die WGM Bits könnten auch nützlich sein.

Gibt es zu den Antworten von Matthias S. auch noch was zu sagen?

von M. K. (sylaina)


Lesenswert?

zweifler schrieb:
> Gibt es zu den Antworten von Matthias S. auch noch was zu sagen?

Was möchtest du denn dazu sagen?

von zweifler (Gast)


Lesenswert?

M. K. schrieb:
> zweifler schrieb:
>> Gibt es zu den Antworten von Matthias S. auch noch was zu sagen?
>
> Was möchtest du denn dazu sagen?

Seine Antwort auf meine, zugegebenermaßen leicht provokativen "echt" und 
"wirklich" waren absolut unangemessen und er hätte sich besser vorher 
selbst an seine Ratschläge und Hinweise gehalten und sich berichtigt.

Und mal ehrlich:
> Um aus 8.000.000 Hz ein 4.000 Hz Signal zu machen, musst du durch 2000
> teilen.
Daraus kann ich keinen Problemlösungsbezug konstruieren. Genau so wenig 
wie aus 1 + 1 = 2.

Aus deiner Frage und ersten Beitrag in diesem thread auch nicht. 
Sozusagen absolut offtopicger Kaperversuch.

von Mike M (Gast)


Lesenswert?

google mal nach 'avrcalc' - gibts glaube bei sourceforge.
Ich finde ist ein recht brauchbares kleines Tool

von Andre R. (ltisystem)


Lesenswert?


von S. Landolt (Gast)


Lesenswert?

> Viel Spaß

Auwei, mit Ironie begibt man sich allgemein schnell aufs Glatteis; 
speziell hier im Forum aber gehört eigentlich ein Grinsgesicht dazu.

von Matze (Gast)


Lesenswert?

Vielen Dank für eure Hilfe :)
Eine kleine Frage habe ich dann doch noch dazu, ich habe jetzt den 
Vorteiler 8 gewählt, mit der Begründung dass der ATmega 16 ein 8 Bit 
Controller ist.

Hab die Lösung mit einer anderen verglichen, bei der kommt aber als OCR0 
der Wert 124 raus???

Grüße
Georg

von Matze (Gast)


Lesenswert?

Vielen Dank für eure Hilfe :)
Eine kleine Frage habe ich dann doch noch dazu, ich habe jetzt den
Vorteiler 8 gewählt, mit der Begründung dass der ATmega 16 ein 8 Bit
Controller ist.

Hab die Lösung mit einer anderen verglichen, bei der kommt aber als OCR0
der Wert 124 raus???

Grüße
Georg

von S. Landolt (Gast)


Lesenswert?

> Vorteiler 8 gewählt, mit der Begründung dass der ATmega 16
> ein 8 Bit Controller ist.

?
Der Timer0 ist ein 8-bit-Timer, deshalb wird ein Vorteiler benötigt, 
z.B. mit Timer1 und dessen 16-bit ginge es ohne, d.h. /1.

> bei der kommt aber als OCR0 der Wert 124 raus???

Ja klar:
S. Landolt schrieb:
> hier also Vorteiler /8 und OCR0=125-1 (bei 'Toggle OC0 on compare match')

Was hatten Sie denn für OCR0 herausbekommen, Matthias/Georg?

von S. Landolt (Gast)


Lesenswert?

PS:
Es wird ein Gesamtteiler von 1000 benötigt, der Timer0 mit seinen 8 bit 
kann aber nur bis maximal 256 (0...255) zählen, also muss noch sein 
Vorteiler hinzugezogen werden.
  (Timer1 hat 16 bit, er kommt also bis 65536, damit könnte man auf den 
Vorteiler verzichten.)

von Matze (Gast)


Lesenswert?

Ich blicke bei der Berechnung noch nicht ganz durch.

 Machen wir ein anderes Beispiel :

Gegebener Systemtakt: 1MHz
gefordert Recktecksignal 1kHz
Gesucht wird der Teiler und der Wert für OCRN?

Formel : Focn = Fclk/2*N*(1+OCRN)

Umgestellt nach OCRN :

OCRN = (Fclk/2*n*focn)-1

focn = 1000000HZ/1000Hz = 1000 HZ

in die umgestellte Formel einsetzen ergibt :

1000000Hz/(2*8*1000Hz) = 62,5

OCRN = 63, Teiler = 8,

Stimmt das so ?

von S. Landolt (Gast)


Lesenswert?

Fast - bis auf die Tatsache, dass 62,5 ungleich 63 (oder 62) ist.
  Das Beispiel ist schlecht gewählt, es wird ein Gesamtteiler von 500 
benötigt, der Timer0 mit seinen 8 bit schafft das nicht direkt, also 
muss noch sein Vorteiler ran, der aber hat beim ATmega16 leider nur die 
Stufung /1, /8, /64 usw. Und 500/8 gibt leider diesen nichtganzzahligen 
Wert von 62,5.

von Matze (Gast)


Lesenswert?

Ich glaub einen kleinen Denkfehler hab ich noch.

Geg: Systemtakt 8 MHz
     Gewünschtes Rechtecksignal : 244Hz

  Wieder der Vorteiler 8

Laut meiner oberen Berechnung komme ich auf einen Wert für OCRN von 
14,25 ???

Danke

von spess53 (Gast)


Lesenswert?

Hi

>Laut meiner oberen Berechnung komme ich auf einen Wert für OCRN von
>14,25 ???

Ich komme auf Prescaler 64 und OCR=255

MfG Spess

von S. Landolt (Gast)


Lesenswert?

?
Gesamtteiler = 8 MHz / 244 Hz  *2 = 65573,77 (keine ganze Zahl, schon 
mal schlecht)

Mit Vorteiler /1024 kommen wir auf rund 64, also OCR0 = 63. Aber wie 
gesagt, rund, nicht ganz genau: es werden 244,1406 Hz.

von Matze (Gast)


Lesenswert?

S. Landolt schrieb:
> Gesamtteiler = 8 MHz / 244 Hz  *2 = 65573,77

Warum nimmst du hier das ganze *2 ?

von Matze (Gast)


Lesenswert?

spess53 schrieb:
> Ich komme auf Prescaler 64 und OCR=255

Könntest du mir das ganze nachvollziehbar erklären ? :-))

Danke

von S. Landolt (Gast)


Lesenswert?

> Warum nimmst du hier das ganze *2 ?

Die 2 steht in Ihrer Formel doch auch. Außerdem hatte ich ja gestern 
geschrieben:
> für die Erzeugung eines Rechecksignals das Doppelte
> seiner Frequenz benötigt ... (bei 'Toggle OC0 on compare match')

von S. Landolt (Gast)


Lesenswert?

Oh, war schon vorgestern.

von S. Landolt (Gast)


Lesenswert?

Ja, Sie haben Recht, das war falsch: die 2 gehört in den Nenner, also 
OCR0=15.

von S. Landolt (Gast)


Lesenswert?

... und damit deckt sich das Ergebnis im Resultat mit dem von spess53 - 
pardon, spess.

von Matze (Gast)


Lesenswert?

S. Landolt schrieb:
> Ja, Sie haben Recht, das war falsch: die 2 gehört in den Nenner, also
> OCR0=15.
Kein Problem.
Ich bin froh über jede Antwort.

Wie komme ich dann mit OCR0 15 auf 0CR0 255 ?

von S. Landolt (Gast)


Lesenswert?

Habe ich jetzt Verwirrung angerichtet? Pardon!
1
Spess:   Vorteiler 64 und OCR0=255:  Gesamtteiler  64*256= 16384.
2
Landolt: Vorteiler 1024 und OCR0=15: Gesamtteiler 1024*16= 16384.
3
4
8 MHz / 16384 = 488,28 Hz, dann noch geteilt durch unsere nun bekannte 2 ergibt die verlangten rund 244 Hz.

von Matze (Gast)


Lesenswert?

S. Landolt schrieb:
> Spess:   Vorteiler 64 und OCR0=255:  Gesamtteiler  64*256= 16384.
> Landolt: Vorteiler 1024 und OCR0=15: Gesamtteiler 1024*16= 16384

Nein, ganz im Gegenteil.

Welche von den beiden Antworten, wäre jetzt den die bessere, und warum 
kann ich hier zwischen 64 und 1024 auswählen ?

von Gerhard O. (gerhard_)


Lesenswert?

Würde das einen Versuch wert sein?

Mit Prescaler CLK/8 bei 8MHz, komme ich auf einen TIMER0 N Wert von 125. 
Dazu muss Timer0 bei jedem Interrupt auf 256-125 = 131 gestellt werden. 
Die TIMER0 Taktfrequenz = 1Mhz.

Das soll so funktionieren, dass T0 als N / 125 Zaehler agiert, also mit 
8kHz Interrupt Rate funktioniert. OC0 bekommt wird also beim Rücksetzen 
von T0 halb so schnell bei jeden T0 Overflow einen OC0 match produzieren 
und folglich einen 4kHz Rechteck produzieren.
1
TCCR0 = 0; // WGM01=WGM00=0 - Normal Wave Generation mode
2
TCCR0 |= (1<< CS01);  // Choose Prescale by eight
3
TCCR0 |= (1<< COM00); // Toggle OC0 on compare match 
4
TIMSK |= 1<<0; // Timer/Counter0 Overflow Interrupt Enable  
5
TCNT0 = 131; // TIMER0 N is now 125 
6
OCR0 = 0; // Bei jeden Rücksetzen von T0 wird ein OC0 Match produziert
7
8
// Forces TIMER0 to cycle in 125 clock pulses
9
ISR(TIMER0_OVF_vect)
10
{
11
    TCNT0 = 131;  // Re-load TIMER0 to produce N=125
12
}
Wenn ich mich nicht irre, sollte OC0 nun 4kHz produzieren:-)

: Bearbeitet durch User
von S. Landolt (Gast)


Lesenswert?

Besser? Keine Ahnung, ist wohl eher Geschmackssache. Sie könnten auch 
Vorteiler /256 und OCR0=63 wählen, ergibt auch den Gesamtteiler 16384.
  Man hat eben beim ATmega16 und dessen Timer0 für den Vorteiler die 
Werte 1, 8, 64, 256 und 1024 zur Verfügung, in meiner Datenblattversion 
ist das 'Table 14-6. Clock Select Bit Description'.

von Gerhard O. (gerhard_)


Lesenswert?

Bei 244 Hz würde es auch eine ISR mit T0 im 7.8kHz Takt tun 
(PRE=1024)und ein einfacher ISR Zähler auf 16 der bei jeden Durchlauf 
einen Pin toggelt. Das ergibt dann 244.14Hz. der Fehler von nur 0.57%. 
Da die ISR nur alle 128us aufgerufen wird ist der CPU overhead oft 
tragbar da der ISR code in ein paar us abgearbeitet sein sollte.

Nachtrag:
Oder wie vorher vorgeschlagen mit abgeänderten Werten, mit OC0 wenn 
PRE=1024 und reload Wert ist, 256-16=240. Sollte auch 244.14 Hz 
produzieren.

: Bearbeitet durch User
von S. Landolt (Gast)


Lesenswert?

> Das ergibt dann 244.14Hz. der Fehler von nur 0.57%.

Es sind nur 0.057 %.


(Gruß nach Edmonton)

von Gerhard O. (gerhard_)


Lesenswert?

S. Landolt schrieb:
>> Das ergibt dann 244.14Hz. der Fehler von nur 0.57%.
>
> Es sind nur 0.057 %.
>
> (Gruß nach Edmonton)

Danke! In der Hitze des Gefechts...

Nachtrag:

Es gibt uC wo der Timer reload automatisch ohne Einsatz einer ISR von 
statten geht. Wie z.B der Timer2 bei vielen PICs. Das eliminiert dann 
noch den kleinen ISR overhead. Also, wenn ein uC einen Auto Reload hat, 
sollte man solch einen Timer verwenden.
Der OC Vergleichswert muß nicht unbedingt bei Null liegen; er muß nur 
zwischen dem Reload Wert und unter der oder gleich Null sein. Bei Null 
könnte es möglicherweise ein Problem geben (Siehe Datenblatt). Habe das 
beim AVR noch nicht so verwendet.

: Bearbeitet durch User
von Matze (Gast)


Lesenswert?

Ich will nun mit meinen berechneten Vorteiler mit Hilfe des CTC-Mode und 
dem Timer 0 eine Rechteckfrequenz erzeugen. ( Ausgansfrequens 244Hz, 
Systemtakt 8 MHz ]

Stimmt dieser Gedankengang:

#include <avr/io.h>
void main(void)
{
DDRB =(1<<PB3);   //OCO ist Ausgang
PORTB=(1<<PB);    //High Startzustand
OCR0 =255;        //Vergleichswert
while (1)
{

//Aktion

}

}


Danke :))

von S. Landolt (Gast)


Lesenswert?

Das scheint wohl irgendwie untergegangen zu sein, durch Setzen von bit 
COM00 in TCCR0 ('Toggle OC0 on compare match').
  Alternativ die Lösung von Gerhard O., diese verlangt allerdings eine 
Interruptroutine.

von Gerhard O. (gerhard_)


Lesenswert?

Versuch das mal:
1
// Test program for 244.14 Hz output on OC0 (PB3)
2
// It uses the prescaler to divide 8MHZ down by 256 and the T0 counter to 
3
// overflow at 64 clock pulses. It needs to be preset at 192 to do this.
4
5
// 8MHZ / 256 = 31250 Hz / 64 = 488.2813 Hz / 2 = 244.12Hz
6
7
void init_OC_toggle(void)
8
{
9
    DDRB =(1<<PB3);   //OCO ist Ausgang
10
//  PORTB=(1<<PB);    // No - OC HW is in control 
11
12
    TCCR0 = 0;            // WGM01=WGM00=0 - Normal Wave Generation mode
13
    TCCR0 |= (1<< CS02);  // Choose Prescale by 256
14
    TCCR0 |= (1<< COM00); // Toggle OC0 on compare match 
15
    TIMSK |= (1<<0);      // Timer/Counter0 Overflow Interrupt Enable  
16
    TCNT0 = 192;          // TIMER0 N: 256-64=192
17
    OCR0 = 2;             // CO MATCH value. 0 might work.
18
)
19
20
21
22
// Forces TIMER0 to overflow every 64 clock pulses, generating a 288Hz 
23
// clock period. Since output match toggles it has to compare at twice the 
24
// output frequency. 488.2813 Hz. The o/p frequency error is 0.057%.
25
26
ISR(TIMER0_OVF_vect)
27
{
28
    TCNT0 = 192;  // Re-load TIMER0 for overflow every 64 counts.
29
}
30
31
32
33
void main(void)
34
{
35
    init_OC_toggle();  // configure HW
36
37
    while(1);          // Nothing to do,
38
}

Wenn ich nichts übersehen habe, müsste das test program funktionieren:-)

von S. Landolt (Gast)


Lesenswert?

Also auf den ersten Blick vermisse ich ein sei.

von S. Landolt (Gast)


Lesenswert?

>     OCR0 = 2;             // CO MATCH value. 0 might work.

Da TCNT0 zwischen 192 und 255 läuft, wäre OCR0=193 o.ä. wohl besser.

von Gerhard O. (gerhard_)


Lesenswert?

S. Landolt schrieb:
> Also auf den ersten Blick vermisse ich ein sei.

Hast recht. Danke:-)

von Gerhard O. (gerhard_)


Lesenswert?

S. Landolt schrieb:
>>     OCR0 = 2;             // CO MATCH value. 0 might work.
>
> Da TCNT0 zwischen 192 und 255 läuft, wäre OCR0=193 o.ä. wohl besser.

Hmm. Das sehe ich auch. Das ist mir jetzt peinlich. Das hätte so nie 
funktionieren können.

von S. Landolt (Gast)


Lesenswert?

Wieso peinlich? Ganz normaler Fehler.

(wenn ich daran denke, was mir vorgestern hier und an anderer Stelle 
unterlaufen ist ...)

von Gerhard O. (gerhard_)


Lesenswert?

Hier die berichtigte Version:
1
// Test program for 244.14 Hz output on OC0 (PB3)
2
// It uses the prescaler to divide 8MHZ down by 256 and the T0 counter to 
3
// overflow at 64 clock pulses. It needs to be preset at 192 to do this.
4
5
// 8MHZ / 256 = 31250 Hz / 64 = 488.2813 Hz / 2 = 244.12Hz
6
7
void init_OC_toggle(void)
8
{
9
    DDRB =(1<<PB3);   //OCO ist Ausgang
10
//  PORTB=(1<<PB);    // No - OC HW is in control 
11
12
    TCCR0 = 0;            // WGM01=WGM00=0 - Normal Wave Generation mode
13
    TCCR0 |= (1<< CS02);  // Choose Prescale by 256
14
    TCCR0 |= (1<< COM00); // Toggle OC0 on compare match 
15
    TIMSK |= (1<<0);      // Timer/Counter0 Overflow Interrupt Enable  
16
    TCNT0 = 192;          // TIMER0 N: 256-64=192
17
    OCR0 = 193;           // CO MATCH value. 
18
    sei();                // Enable global interrupts 
19
)
20
21
22
23
// Forces TIMER0 to overflow every 64 clock pulses, generating a 288Hz 
24
// clock period. Since output match toggles it has to compare at twice the 
25
// output frequency. 488.2813 Hz. The o/p frequency error is 0.057%.
26
27
ISR(TIMER0_OVF_vect)
28
{
29
    TCNT0 = 192;  // Re-load TIMER0 for overflow every 64 counts.
30
}
31
32
33
34
void main(void)
35
{
36
    init_OC_toggle();  // configure HW
37
38
    while(1);          // Nothing to do,
39
}

von Gerhard O. (gerhard_)


Lesenswert?

S. Landolt schrieb:
> Wieso peinlich? Ganz normaler Fehler.
>
> (wenn ich daran denke, was mir vorgestern hier und an anderer Stelle
> unterlaufen ist ...)

Naja, wir sitzen meist im Glashaus und da gehört es sich nicht Steine zu 
werfen:-)

von S. Landolt (Gast)


Lesenswert?

> ... mit Hilfe des CTC-Mode ...
> Stimmt dieser Gedankengang:
> ...

In keiner Weise - ich sehe weder CTC noch Vorteiler. So allmählich 
gewinne ich den Eindruck, dass wir hier vergeblichen Nachhilfeunterricht 
geben; auch hatte ich gestern noch mit einer Rückmeldung gerechnet. Als 
mein letzter Versuch eine fertige Lösung (aber ob das was hilft?):
1
// ATmega16: 8.00 MHz -> 244.14 Hz
2
#include <avr/io.h>
3
4
void main(void) {
5
    DDRB  = (1<<3); // OC0 auf Ausgang
6
    TCCR0 = (1<<WGM01) | (1<<CS02) | (1<<CS00) | (1<<COM00); // CTC, Vorteiler 1024, toggle OC0 on compare match
7
    OCR0  = 16-1;
8
9
    while(1);
10
}

von Gerhard O. (gerhard_)


Lesenswert?

S. Landolt schrieb:
>> ... mit Hilfe des CTC-Mode ...
>> Stimmt dieser Gedankengang:
>> ...
>
> In keiner Weise - ich sehe weder CTC noch Vorteiler. So allmählich
> gewinne ich den Eindruck, dass wir hier vergeblichen Nachhilfeunterricht
> geben; auch hatte ich gestern noch mit einer Rückmeldung gerechnet. Als
> mein letzter Versuch eine fertige Lösung (aber ob das was hilft?)://
> ATmega16: 8.00 MHz -> 244.14 Hz
> #include <avr/io.h>
>
> void main(void) {
>     DDRB  = (1<<3); // OC0 auf Ausgang
>     TCCR0 = (1<<WGM01) | (1<<CS02) | (1<<CS00) | (1<<COM00); // CTC,
> Vorteiler 1024, toggle OC0 on compare match
>     OCR0  = 16-1;
>
>     while(1);
> }

Hallo S,

ich muß zugeben, daß ich momentan auf dem Schlauch stehe. Also, T0 wird 
mit 7812.5 Hz getaktet. Aber wie da 244.14 Hz erzeugt werden sollen, 
verstehe ich noch nicht. Die T0 Periode würde dann 30.5Hz sein und die 
OCR0 match Wiederholrate dann auch nur dieselbe wie T0. Was übersehe ich 
hier? Es sollte eigentlich nicht funktionieren, außer T0 würde beim 
Match auch zurückgestellt werden und was bedeutet Deine Schreibweise 
"OCR0=16-1;"? Einfach "OCR0=15"?

Dein Vorschlag würde nur funktionieren wenn T0 bei jeden Match auch 
jedesmal zurückgesetzt werden würde. Dann hätte ich wieder mal nicht die 
Bäume im Wald gesehen. Aber geht das denn?

Gruß,
Gerhard

Zeit nochmals das Datenblatt zu lesen:-)

P.S. Erst gehe ich frühstücken. Auf dem iPad ist das auch kein "fun"

Nachtrag:

Hat sich geklärt. Datenblatt lesen hilft ungemein. Der OCR0 Wert von Dir 
ist auch das T0 Zähl Maximum. Jetzt verstehe wie Du Dir das gedacht 
hattest weil Mode 2 eingestellt und T0 nun nur noch bis 15 zählt und 
dann beim Match zurückgestellt wird. Dann ist die Wiederholrate 
natürlich um 488Hz und OC toggelt halb so schnell mit 244.14 Hz.

Noch etwas: Stimmt das mit den COM bits? COM00=1 und COM01=0 ist 
"reserved". Hier würden doch nur die letzten beiden Kombinationen in 
Table 41 richtig sein. Oder vermisse ich was hier?

: Bearbeitet durch User
von Sven K. (quotschmacher)


Lesenswert?

Gerhard O. schrieb:
> außer T0 würde beim
> Match auch zurückgestellt werden

quasi genau so, wie es im datenblatt steht?
> In Clear Timer on Compare or CTC mode (WGM01:0 = 2), the OCR0 Register is
> used to manipulate
> the counter resolution. In CTC mode the counter is cleared to zero when the
> counter value
> (TCNT0) matches the OCR0. The OCR0 defines the top value for the counter,
> hence also its
> resolution. This mode allows greater control of the compare match output
> frequency. It also simplifies
> the operation of counting external events."

: Bearbeitet durch User
von spess53 (Gast)


Lesenswert?

Hi

Der ATMEga16 kann mit jedem Timer CTC. Warum dann auf einmal diese 
vorsintflutliche Vorladen+Interrupt?

MfG Spess

von Gerhard O. (gerhard_)


Lesenswert?

Sven A. schrieb:
> Gerhard O. schrieb:
>> außer T0 würde beim
>> Match auch zurückgestellt werden
>
> quasi genau so, wie es im datenblatt steht?
>> In Clear Timer on Compare or CTC mode (WGM01:0 = 2), the OCR0 Register is
>> used to manipulate
>> the counter resolution. In CTC mode the counter is cleared to zero when the
>> counter value
>> (TCNT0) matches the OCR0. The OCR0 defines the top value for the counter,
>> hence also its
>> resolution. This mode allows greater control of the compare match output
>> frequency. It also simplifies
>> the operation of counting external events."

Hallo Sven,

danke fuer den Hinweis.

Hab's mal schnell auf einem 16MHz Pro-Mini ausprobiert und es 
funktionierte auf Anhieb:
1
void setup() {
2
3
    DDRD  = (1<<6); // OC0 auf Ausgang
4
    TCCR0A = (1<<WGM01) | (1<<COM0A0); // CTC, toggle OC0 on compare match
5
    TCCR0B = (1<<CS02); // Prescaler is set to divide by 256
6
    OCR0A  = 128-1;
7
    while(1);
8
}
9
10
void loop() {
11
  // put your main code here, to run repeatedly:
12
13
}

Gruss,
Gerhard

: Bearbeitet durch User
von Gerhard O. (gerhard_)


Lesenswert?

spess53 schrieb:
> Hi
>
> Der ATMEga16 kann mit jedem Timer CTC. Warum dann auf einmal diese
> vorsintflutliche Vorladen+Interrupt?
>
> MfG Spess

Ganz einfach weil ich bis jetzt noch keinen Bedarf hatte so einen 
Ausgang in die Praxis umzusetzen und mir war das Studieren dieser 
Sektion im Detail bis auf das was ich bis jetzt nutzte zu viel Arbeit. 
Das rächte sich jetzt natürlich.

Bis jetzt nutzte ich die Timer nur als ISR Zeitbasis in meinen 
Projekten. Ich brauchte OC bis jetzt noch nie bei den AVRs. Mit PIC 
Timer HW kenne ich mich da besser aus.

Mit CTC ist das beim AVR auf alle Fälle am zweckmäßigsten. Das ist jetzt 
klar.
Jedenfalls ist es ganz gut ab und zu mal mit dem Zaunpfahl über den 
Tellerrand "geschaut zu werden":-)

: Bearbeitet durch User
von Matze (Gast)


Lesenswert?

> void main(void) {
>     DDRB  = (1<<3); // OC0 auf Ausgang
>     TCCR0 = (1<<WGM01) | (1<<CS02) | (1<<CS00) | (1<<COM00); // CTC,
> Vorteiler 1024, toggle OC0 on compare match
>     OCR0  = 16-1;
>
>     while(1);
> }

Muss ich das TIMSK Register auch mit einbeziehen ?

von Gerhard O. (gerhard_)


Lesenswert?

Matze schrieb:
>> void main(void) {
>>     DDRB  = (1<<3); // OC0 auf Ausgang
>>     TCCR0 = (1<<WGM01) | (1<<CS02) | (1<<CS00) | (1<<COM00); // CTC,
>> Vorteiler 1024, toggle OC0 on compare match
>>     OCR0  = 16-1;
>>
>>     while(1);
>> }
>
> Muss ich das TIMSK Register auch mit einbeziehen ?

Nein. Dieses Register wird nur für die Konfigurierung einer ISR 
gebraucht sofern man diese Route gehen will um den Interrupt für Den T0 
Überlauf zu aktivieren. Da alle Timer CTC Modi können, ist das aber nun 
ganz überflüssig.

Das Beispiel von Sven funktioniert genauso wie er es Dir gezeigt hatte 
ohne ISR. Meine ISR beruhte auf das unzureichende Verständnis der Timer0 
Einstellungsmöglichkeiten, insbesonders der CTC Modus wo der Wert des 
OCR0 Register den TOP Wert des Timer0 bestimmt und aus diesem Grund die 
ISR nicht mehr notwendig ist. Mein lauffähiges Beispiel ist für einen 
Arduino Pro-Mini oder ähnlich gedacht.

Mein Rat: lade Svens Programm Beispiel und teste es.

: Bearbeitet durch User
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.