Forum: Compiler & IDEs PWM Mode mit Mega168


von Werner A. (homebrew)


Lesenswert?

Hallo Leute,
ich glaube ich habe ein Verständnis Problem bei Nutzung des PWM Modus.
Eigentlich würde ich nach der Initialisierung erwarten, dass der Pin 
OC2A mit 50% PWM blinkt. Tut er aber nicht (ist nur auf high level)
1
void init_timer2(void)
2
{
3
// Timer im PWM Modus. Zählt von 0 - 255 und zurück  
4
  TCCR2A = (1<<WGM20)|(1<<WGM21);      
5
  TCCR2B = (1<<WGM22);      //Toggle OC2A on Compare match
6
          //between TCNT2 and OCR2A
7
8
  TCCR2A |= (1<<COM2A0);     //Fast PWM Mode
9
  TCCR2B |= (1<<CS20) | (1<<CS21);  //Timer Prescaler 32 
10
11
  OCR2A = 125;
12
}

Kann mir jemand nen Tip geben wie das funktioniert?

Später will ich die PWM für 2 LED's benutzen und dann das ganze ein und 
ausschalten um die Helligkeit der Umgebungshelligkeit anzupassen. Ich 
hab schon überlegt, zwischem dem LED Ausgang und dem PWM Ausgang nen UND 
Glied zu schalten um das hinzubekommen. Oder gibts da nen intelligenten 
Weg?

Werner

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Werner A. wrote:

> ich glaube ich habe ein Verständnis Problem bei Nutzung des PWM Modus.
> Eigentlich würde ich nach der Initialisierung erwarten, dass der Pin
> OC2A mit 50% PWM blinkt. Tut er aber nicht (ist nur auf high level)

>   TCCR2A = (1<<WGM20)|(1<<WGM21);
>   TCCR2B = (1<<WGM22);

Nun, damit wählst du einen fast PWM aus, der OCR2A als TOP value des
Zählers benutzt.  Damit kannst du OC2A nicht auch noch (sinnvoll) als
PWM-Ausgang benutzen.  (Nur OC2B ist in dieser Konfiguration
sinnvoll.)

Vermutlich willst du den fast PWM mit TOP = 0xFF benutzen, der hat
WGM20 und WGM21 gesetzt, WGM22 aber nicht.

>   TCCR2A |= (1<<COM2A0);

Hmm, das sollte aber in der Tat 50 % Tastverhältnis ergeben, jetzt
hab' ich dich verstanden.

Ist das auf dem Simulator oder auf Silizium?

>   TCCR2B |= (1<<CS20) | (1<<CS21);

Btw., ich würde beide Steuerregister jeweils komplett beschreiben.  Da
die Register "volatile" markiert sind, kann der Compiler diese
Operationen nicht ineinander vereinigen.

> Später will ich die PWM für 2 LED's benutzen und dann das ganze ein
> und ausschalten um die Helligkeit der Umgebungshelligkeit
> anzupassen.

Wenn's nur um die Ansteuerung von 2 LEDs geht, sollte die PWM-Frequenz
ja relativ egal sein.  Damit müsste die Variante mit TOP = 0xFF eher
deinen Wünschen entsprechen.  Wäre trotzdem noch die Frage, warum das
"toggle on compare match" hier nicht funktioniert.  Kannst du ggf. ja
noch bei Atmel nachfragen.

von Ingo E. (ogni42)


Lesenswert?

Und dann bitte noch das Datenrichtungsregister auf Ausgang setzen!

von Werner A. (homebrew)


Lesenswert?

Eigentlich sollte TCCR2A = (1<<WGM20)|(1<<WGM21); die FastPWM bis 0xFF 
einschalten (Tablelle 16-8) und TCCR2B = (1<<WGM22); zusammen mit TCCR2A 
|= (1<<COM2A0); das toggle von OC2A aktivieren (Tabelle 16-3)

Den Pin hatte ich bisher nicht als Ausgang gesetzt, da im Datenblatt 
beschrieben wird, das der OC2A Ausgang die bestehende funktionalität 
überschreibt. Werde es aber heut abend nochmal ausprobieren.

@Jörg
>>   TCCR2B |= (1<<CS20) | (1<<CS21);
>Btw., ich würde beide Steuerregister jeweils komplett beschreiben.  Da
>die Register "volatile" markiert sind, kann der Compiler diese
>Operationen nicht ineinander vereinigen.
Das verstehe ich nicht. Heißt dass, ich soll das Register mit 0x?? 
beschreiben anstelle der seperaten Schreibweise?

Generell werde ich glaub ich doch den CTC Modus verwenden. Scheint mir 
irgendwie einfacher zu verstehen zu sein ;-)

Danke
  Werner

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Werner A. wrote:

> Eigentlich sollte TCCR2A = (1<<WGM20)|(1<<WGM21); die FastPWM bis
> 0xFF einschalten (Tablelle 16-8) und TCCR2B = (1<<WGM22);

Nö, die WGMs musst du zusammen als Index in Tabelle 16-8 betrachten.
Damit hast du Mode 7 ausgewählt.

> zusammen mit TCCR2A |= (1<<COM2A0); das toggle von OC2A aktivieren
> (Tabelle 16-3)

Ich denke, die Fußnote 1 von Tabelle 16-4 trifft hier zu: "..., the
Compare Match is ignored, ...".  Ich hab's aber im entsprechenden
Abschnitt nicht bis zu Ende verstanden, was in diesem Fall genau
ablaufen soll.

> Den Pin hatte ich bisher nicht als Ausgang gesetzt, da im Datenblatt
> beschrieben wird, das der OC2A Ausgang die bestehende funktionalität
> überschreibt.

Einen Satz später:

"However, note that the Data Direction Register (DDR) bit
corresponding to the OC2A pin must be set in order to enable the
output driver."

> Das verstehe ich nicht. Heißt dass, ich soll das Register mit 0x??
> beschreiben anstelle der seperaten Schreibweise?

Nein, aber die initiale Zuweisung für TCCR2x mit den nachfolgenden |=
Operationen vereinen.

> Generell werde ich glaub ich doch den CTC Modus verwenden. Scheint
> mir irgendwie einfacher zu verstehen zu sein ;-)

Nö, PWM mit TOP = 0xFF ist ziemlich Standard.  Siehe auch das einfache
demo.c bei der avr-libc.

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.