AtMega8 und PWM - Erste Schritte

OP #535489
Lesenswert?

Hallo,

nachdem ich das AVR-Tutorial und das Datenblatt vom ATmega8 dreimal 
gelesen habe, schaffe ich es immer noch nicht eine einfachste PWM auf 
den OC1A zu bringen. Nach dem Tutorial ist folgendes zu tun:

TCCR1A = (1<<WGM11)|(1<<WGM10)|(1<<COM1A1);
TCCR1B = (1<<CS12) | (1<<CS10);
OCR1A = xxx;

Hier habe ich jetzt - für die Profis in diesem Forum wahrscheinlich 
lachhafte - Anfängerfragen:

1. Frage:
Als Anfänger versuche ich noch möglichst viel einzeln aufzuschlüsseln, 
dass heißt Zusammenfassungen zu vermeiden. Könnte man die erste Zeile 
TCCR1A = (1<<WGM11)|(1<<WGM10)|(1<<COM1A1) nicht auch wie folgt 
schreiben:

TCCR1A = TCCR1A | (1WGM11);
TCCR1A = TCCR1A | (1WGM10);
TCCR1A = TCCR1A | (1COM1A1);

2. Frage:
Mit der zweiten Zeile TCCR1B = (1<<CS12) | (1<<CS10) wird anscheinend 
die Zählgeschwindigkeit festgelegt, die laut Tutorial dann ein Teil von 
CK ist. Ist mit CK die Taktrate vom Mikrocontroller gemeint oder muss 
ich hier irgendwo noch einen Wert setzen?

3. Frage:
Ich habe obigen Tutorial-Code in ein Program eingebunden. Nach dem 
Datenblatt von meinem ATmega8 müssten die Bezeichnungen auch 
übereinstimmen. Jedoch ist im ATmega8-Datenblatt noch von einem WGM13 
die Rede. Ich vermute, dieser muss auf 0 gesetzt werden (was er 
wahrscheinlich schon ist). Um sicher zu gehen habe dennoch in mein 
Programm TCCR1B = TCCR1B & ~(1 << WGM13); eingefügt:

#include <avr/io.h>
void main(void)
{
TCCR1B = TCCR1B & ~(1 << WGM13);
TCCR1A = (1<<WGM11)|(1<<WGM10)|(1<<COM1A1);
TCCR1B = (1<<CS12) | (1<<CS10);
OCR1A = 10; //schon mit allen möglichen Werten experiementiert
while(1);
}

Ich glaube jedoch, es mir zu einfach zu machen. In vielen Forenbeiträgen 
werden irgendwelche Interrupts gesetzt oder Taktfrequenzen definiert 
etc. Eigentlich will ich nur eine LED an PB1 zum blinken bringen oder 
dimmen. Im nächsten Schritt schwebt mir vor die LED durch einen Stepper 
zu ersetzen.

Für Hinweise, was ich falsch gemacht habe bzw. was in dem Code noch 
alles ergänzt werden müsste, besten DANK!.
Gast #535548
Lesenswert?

Hallo Alexander,

zu 1):

ist das selbe und bei einem "ODER" auch unproblematisch. Bei "UND" muß 
darauf geachtet werden, andere Bits nicht zu beeinflussen.

Die Definition von Taktfrequenzen dient i. A. dazu, von der Taktfrequenz 
abhängige Parameter richtig zu berechnen.

Der Interrupt ist m.E. in Deiner Anwendung nur nötig, um den Zähler 
(rechtzeitig) wieder (richtig) zu laden (reload).

Gruß Otto
#535610
Lesenswert?

Alexander Grossmann wrote:

> #include <avr/io.h>
> void main(void)
> {
> TCCR1B = TCCR1B & ~(1 << WGM13);
> TCCR1A = (1<<WGM11)|(1<<WGM10)|(1<<COM1A1);
> TCCR1B = (1<<CS12) | (1<<CS10);
> OCR1A = 10; //schon mit allen möglichen Werten experiementiert
> while(1);
> }
>
> Ich glaube jedoch, es mir zu einfach zu machen.

Das passt schon.
Das einzige was du vergessen hast, ist den OC1A Pin auch
auf Ausgang zu schalten :-)  Vergess ich auch immer wieder
gerne mal.

> In vielen Forenbeiträgen werden irgendwelche Interrupts gesetzt

Die brauchst du nur, wenn du auf spezielle Timerereignisse
per Programm reagieren musst. In deinem Fall macht aber
die Hardware die PWM ganz von alleine. Daher braucht es auch
keine ISR.

Setzte einfach den OC1A Pin auf Ausgang und erfreue dich
an deiner ersten blinkenden LED.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren