Forum: Mikrocontroller und Digitale Elektronik Atmega8 Hardware PWM


von ROLF (Gast)


Lesenswert?

Guten Tag,

ich spiele derzeit ein bißchen mit dem Atmega8 rum.

Bin grad dabei mit der Hardware PWM mich zu beschäftigen, mein Problem 
ist derzeit.
Wenn ocr2= 10 ist flackert die Led ein bischen woran könnte das liegen.
OCR1AL = 10 OCR1BL = 10 flackern bei diesen Werten nicht.

vielleivcht könnte mir einer weiterhelfen.
mfg
1
   TCCR2 = (1<<WGM20|1<<COM21|0<<COM20|1<<CS22|0<<CS21|0<<CS20);
2
 
3
   TCCR1A  = (1<<COM1A1|1<<COM1B1|1<<WGM10);    
4
                   
5
   TCCR1B  = (0<<CS12|1<<CS11|1<<CS10);

von S. Landolt (Gast)


Lesenswert?

Erstmal Klammern um jeden Einzelausdruck, danach sieht man weiter.

von ROLF (Gast)


Lesenswert?

ROLF schrieb:
> TCCR2 = (1<<WGM20|1<<COM21|0<<COM20|1<<CS22|0<<CS21|0<<CS20);
>
>    TCCR1A  = (1<<COM1A1|1<<COM1B1|1<<WGM10);
>
>    TCCR1B  = (0<<CS12|1<<CS11|1<<CS10);
1
   TCCR2 = (1<<WGM20)|(1<<COM21)|(0<<COM20)|(1<<CS22)|(0<<CS21)|(0<<CS20);
2
 
3
   TCCR1A  = (1<<COM1A1)|(1<<COM1B1)|(1<<WGM10);    
4
                   
5
   TCCR1B  = (0<<CS12)|(1<<CS11)|(1<<CS10);

von S. Landolt (Gast)


Lesenswert?

?
Okay, und flackert die LED noch immer? Wenn ja, das komplette Programm 
zeigen.

von ROLF (Gast)


Lesenswert?

S. Landolt schrieb:
> ?
> Okay, und flackert die LED noch immer? Wenn ja, das komplette Programm
> zeigen.

Wenn OCR2 = 10 ist ann Flackerts nach wie vor.
1
#define F_CPU 16000000UL
2
uint8_t i;
3
4
 DDRB = (1<<PB1  ) | (1<<PB2  ) | (1<<PB3  );//als ausgang
5
6
   TCCR2 = (1<<WGM20)|(1<<COM21)|(0<<COM20)|(1<<CS22)|(0<<CS21)|(0<<CS20);
7
 
8
   TCCR1A  = (1<<COM1A1)|(1<<COM1B1)|(1<<WGM10);    
9
                   
10
   TCCR1B  = (0<<CS12)|(1<<CS11)|(1<<CS10);
11
12
13
//###################################################################################
14
//Helligkeit Werte setzen 
15
void RGB_Wert ( uint8_t R,uint8_t G,uint8_t B)  
16
//###################################################################################
17
{
18
19
20
   //Rot
21
   if( OCR1AL < R )
22
     OCR1AL++;
23
    
24
   else if( OCR1AL > R )
25
     OCR1AL--;
26
    //Blau
27
   if( OCR1BL < G )
28
     OCR1BL++;
29
  
30
   else if( OCR1BL > G )
31
     OCR1BL--;
32
   //Grün
33
   if( OCR2 < B )
34
     OCR2++;
35
  
36
   else if( OCR2 > B )
37
     OCR2--;
38
  
39
}
40
41
 for (i=0; i<255; i++)
42
  {  
43
   RGB_Wert (i,i,i);
44
  }

von S. Landolt (Gast)


Lesenswert?

Tut mir leid, da muss ich passen. Auf Anhieb sehe ich keinen Unterschied 
zwischen den Timern, und einen ATmega8 zum Ausprobieren habe ich nicht.

von Bud (Gast)


Lesenswert?

Das Ganze kann nicht so funktionieren wie du das Initialisierst.

Du setzt TCCR2, das ist ein Register vom 8-Bit Zähler 2.
Dann setzt du aber TCCR1A & TCCR1B, das sind aber Register vom 16-Bit 
Zähler 1.
Dann schreibst du von OCR2 = 10 was wiederum zu den 8-Bit Zähler gehört.
Dann schreibst du auf einmal wieder von den Registern OCR1AL und OCR1BL. 
Das sind dann wieder Register vom 16-Bit Zähler.

Die Registernamen mit 2 haben nichts mit den Registernamen mit 1 zu tun!

Im Datenblatt vom ATmega8 ist PWM sehr gut beschrieben. Einfach mal 
nachlesen!

Und vor allem erst mal sich einig sein, ob man eine 8-Bit PWM (Zähler2) 
oder 16-Bit PWM (Zähler1) haben möchte. Dann die entsprechenden zu den 
Zähler dazugehörigen Register anhand der Tabelle und 
Registerbeschreibungen im Datenblatt setzen und herumprobieren was 
passiert, wenn man z.B. die WGM-Bits verändert...

von S. Landolt (Gast)


Lesenswert?

Eigentlich sollte das schon funktionieren; auch war mein erster Einwand 
mit den Klammern falsch (ich kann mir nie die Hierarchie merken).
  Wenn ich versuche, das Programm lauffähig zu ergänzen und die Ausgänge 
auf einen ATmega16 anpasse, dann flackert da zumindest nichts und schon 
gar nicht unterschiedlich. Es muss an etwas liegen, was hier nicht 
gezeigt wurde.

von Stefan K. (stefan64)


Lesenswert?

Was soll das sein, die main()?
1
 for (i=0; i<255; i++)
2
  {  
3
   RGB_Wert (i,i,i);
4
  }

Dass das flakert, wundert mich nicht. Du änderst die Werte ja im 
us-Takt.

Gruß, Stefan

von S. Landolt (Gast)


Lesenswert?

Also da hatte ich ein _delay_ms eingefügt, und außen herum ein while(1) 
gesetzt. Dann läuft die Helligkeit erst langsam hoch und pendelt dann im 
oberen Bereich, für alle drei LEDs gleichmäßig. Die Aussage, nur die LED 
an Timer2 flackere, kann ich nicht nachvollziehen, schließlich ist die 
Initialisierung für beide Timer ja auch gleich.

von Felix F. (wiesel8)


Lesenswert?

ROLF schrieb:
> Wenn ocr2= 10 ist flackert die Led ein bischen woran könnte das liegen.
> OCR1AL = 10 OCR1BL = 10 flackern bei diesen Werten nicht.

10 von 2^16 sind 0% (Timer1)
10 von 2^8 sind 4% (Timer2)

Deine Frage:
Ich setze 2 UNTERSCHIEDLICHE Timer auf GLEICHE Werte. Wieso habe ich 
NICHT das GLEICHE verhalten?

mfg

von S. Landolt (Gast)


Lesenswert?

> 10 von 2^16 sind 0% (Timer1)
> 10 von 2^8 sind 4% (Timer2)

Auch bei Timer1 ist es nur 2^8, schließlich ist WGM10 gesetzt, das heißt 
"PWM, Phase Correct, 8-bit", mit TOP=0x00FF.

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


Lesenswert?

Bud schrieb:
> Und vor allem erst mal sich einig sein, ob man eine 8-Bit PWM (Zähler2)
> oder 16-Bit PWM (Zähler1) haben möchte.

Hat der TE doch gemacht. Sobald WGM10 beim Timer 1 gesetzt ist, ist das 
ein 8-bit PWM Timer mit TOP = 0x00FF im 'Phase Correct PWM' Modus. Siehe 
Table 39 im Datenblatt. Vorteiler hier ist 64.

Timer 2 wird genauso als 'Phase Correct' initialisiert und genauso mit 
Vorteiler 64.
Die beiden sollten also das gleiche Verhalten zeigen.
Wenn sie es nicht tun, ist mögl. die externe Beschaltung des MC schuld.
Allerdings ist 244Hz PWM bei LEDs wirklich sehr langsam und führt immer 
zu deutlichem Flimmern. Ich nehme deswegen gerne >3kHz.

von S. Landolt (Gast)


Lesenswert?

> 244Hz PWM

ROLF gibt als Systemtakt 16 MHz an, das wären dann 488 Hz.

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


Lesenswert?

S. Landolt schrieb:
> ren dann 488 Hz.

Ok, schon besser. Wäre mir aber immer noch zu kribbelig.

von Rene (Gast)


Lesenswert?

Matthias S. schrieb:
> S. Landolt schrieb:
> ren dann 488 Hz.
>
> Ok, schon besser. Wäre mir aber immer noch zu kribbelig.


Sind nicht 16000000/256=62500

62500/256=244,14

Liege ich hier verkehrt?

von S. Landolt (Gast)


Lesenswert?

16.00 MHz /64 /256 /2 = 488 Hz

/64: Vorteiler
/256: 2^8
/2: phase correct

von S. Landolt (Gast)


Lesenswert?

Pardon, sind wegen 'phase-correct' wohl doch nur 255, also
16.00 MHz /64 /510 = 490 Hz.

von M. K. (sylaina)


Lesenswert?

S. Landolt schrieb:
> Pardon, sind wegen 'phase-correct' wohl doch nur 255, also

nö, 256 war schon richtig. Die 0 musste ja auch mit zählen. Du 
dividierst ja nicht durch den größten  Wert sondern durch die Zahl der 
möglichen Werte und das sind 256 ;)

von Dieter F. (Gast)


Lesenswert?

M. K. schrieb:
> nö, 256 war schon richtig. Die 0 musste ja auch mit zählen. Du
> dividierst ja nicht durch den größten  Wert sondern durch die Zahl der
> möglichen Werte und das sind 256 ;)

Ja, wenn dann die Fuse noch der Angabe entspricht - und nicht auf 1 
MHz-Standard steht - ansonsten kann es schon unangenehm sein ...

Code-Fragmente sind immer wieder toll :-)

von S. Landolt (Gast)


Lesenswert?

> nö, 256 war schon richtig.

Ich denke nicht, im Datenblatt steht 510 (wegen der Umkehrung der 
Zählrichtung), und das messe ich hier auch.

von c-hater (Gast)


Lesenswert?

S. Landolt schrieb:
>> nö, 256 war schon richtig.
>
> Ich denke nicht, im Datenblatt steht 510 (wegen der Umkehrung der
> Zählrichtung), und das messe ich hier auch.

Und das ist auch korrekt. In einem kompletten Zyklus kommen alle Werte 
zwei mal vor (einmal beim Hochzählen, einmal beim Runterzählen), nur der 
Wert für TOP und 0 kommen nur jeweils einmal vor. Wie du vollkommen 
korrekt sagtest, wegen der Umkehrung der Zählrichtung.

Gezählt wird eben bei jedem Timertakt genau ein Schritt, bei Erreichen 
von TOP oder Null wird aber nebenbei noch die Zählrichtung umgekehrt, 
was dazu führt, dass gleich der nächste Takt den Zähler wieder einen 
Schritt in die entgegengesetzte Richtung bewegt. Und innerhalb eines 
Zyklus kommt man nie wieder zu diesem Endwert. Damit kommt er eben nur 
einmal pro Zyklus vor.

Die Grafiken bei der Erklärung des PhaseCorrect-Modus zeigen das 
eigentlich auch ziemlich deutlich. Man muss sie sich halt einfach nur 
mal wirklich angesehen haben...

von S. Landolt (Gast)


Lesenswert?

... und sich nach Jahren spontan noch daran erinnern können.

von M. K. (sylaina)


Lesenswert?

c-hater schrieb:
> Und das ist auch korrekt. In einem kompletten Zyklus kommen alle Werte
> zwei mal vor (einmal beim Hochzählen, einmal beim Runterzählen), nur der
> Wert für TOP und 0 kommen nur jeweils einmal vor. Wie du vollkommen
> korrekt sagtest, wegen der Umkehrung der Zählrichtung.

S. Landolt schrieb:
> Ich denke nicht, im Datenblatt steht 510 (wegen der Umkehrung der
> Zählrichtung), und das messe ich hier auch

Ach ja, stimmt ja. Daran hab ich gar nicht gedacht.

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.