Forum: Mikrocontroller und Digitale Elektronik Atmega8 Timer1 OC1A/OC1B: nur A läuft


von Jens N. (midibrain)


Lesenswert?

Hallo,

Atmega8

Möchte die PWM von Timer1 benutzen um auf OC1A und OC1B verschiedene 
Frequenzen auszugeben.
Mit meinem Init vom Timer läuft nur OC1A (mit LEDs getestet).

Warum läuft OC1B nicht mit?

void init_timer1(void)
{
  DDRB |= (1<<PB1);
  DDRB |= (1<<PB2);//OC1A/OC1B als Output
  TCCR1A |= (1<<COM1A1) | (COM1B1);//set at bottom;clear at compare
  TCCR1A |= (1<<WGM10);//phase correct, 8Bit
  TCCR1B |= (1<<CS11);//Prescaler 8: 14745600 / 256 = 57600 / 8 = 7200
  //Test
  OCR1A = 162;
  OCR1B = 100;
}

Jens

von mürrisch (Gast)


Lesenswert?

Jens N. schrieb:
> Warum läuft OC1B nicht mit?

An der initialisierung liegt es nicht. Eventuell steht aber noch etwas 
in den  Timerregister, da du ja nur veroderst. Ansonsten komplettes 
kleinstes Program, das den Fehler enthält, zeigen.

von Thomas E. (thomase)


Lesenswert?

mürrisch schrieb:
> An der initialisierung liegt es nicht.

Aber Hallo:

Jens N. schrieb:
> TCCR1A |= (1<<COM1A1) | (COM1B1);

von mürrisch (Gast)


Lesenswert?

Thomas E. schrieb:
> mürrisch schrieb:
>> An der initialisierung liegt es nicht.
>
> Aber Hallo:
>
> Jens N. schrieb:
>> TCCR1A |= (1<<COM1A1) | (COM1B1);

schäm

von Stefan B. (stefan_b278)


Lesenswert?

Deshalb lieber das Makro _BV() verwenden.

von Jens N. (midibrain)


Lesenswert?

o.k

Habs jetzt mal in zwei Zeilen geschrieben:

TCCR1A |= (1<<COM1A1);//set at bottom;clear at compare
TCCR1A |= (1<<COM1B1);//set at bottom;clear at compare

Das geht!

Wie setzt man richtig mehrere Bits in einem Register gleichzeitig?

Jens

P.S.: Habs gefunden, man muss die Masken wohl klammern:

TCCR1A |= ((1<<COM1A1) | (1<<COM1B1));

von Thomas E. (thomase)


Lesenswert?

Jens N. schrieb:
> Wie setzt man richtig mehrere Bits in einem Register gleichzeitig?

Niemals so:  TCCR1A |= (1<<COM1A1) | (COM1B1);

Sondern so:
1
TCCR1A |= (1 << COM1A1) | (1 << COM1B1);

von leo (Gast)


Lesenswert?

Jens N. schrieb:
> P.S.: Habs gefunden, man muss die Masken wohl klammern:
>
> TCCR1A |= ((1<<COM1A1) | (1<<COM1B1));

Nein, die Klammern sind alle optional. Das Shift von COM1B1 hatte 
gefehlt.

leo

von Jens N. (midibrain)


Lesenswert?

Oh wei...

Böser Tippfehler...

Danke

von c-hater (Gast)


Lesenswert?

Jens N. schrieb:

> Möchte die PWM von Timer1 benutzen um auf OC1A und OC1B verschiedene
> Frequenzen auszugeben.

Tja, dann hast du ein ernsthaftes Problem. Das ist nämlich völlig 
unmöglich. Zwei PWM-Kanäle eines AVR8-Timers haben zwangsläufig 
immer dieselbe PWM-Frequenz.

Bestenfalls (z.B. halt bei Timer1 der Atmegas) ist es wenigstens 
überhaupt möglich, an der Frequenz zu drehen und trotzdem zwei 
PWM-Kanäle zu haben.

Sprich: lies' endlich das verdammte Datenblatt!

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.