Forum: Compiler & IDEs Anfängerfrage PWM


von pwm-gast (Gast)


Lesenswert?

Hallo,

ich habe einen ATmega2560 (STK600)und versuche im folgenden eine 8-bit 
pwm über Timer0 zu erzeugen.
Ich habe als F-CPU 8MHz.
Die PWM lege ich auf eine LED, die leuchtet auch, allerdings unabhängig 
vom eingestellten OCRA0A.
Auch mit dem Oszi kann ich keine PWM feststellen, finde aber den Fehler 
nicht. Hoffe mir kann jemand weiterhelfen.

Vielen Dank schonmal.


int main(void)
{
    while(1)
    {
    DDRB|=0b10000000;
    OCR0A=0x80;
    TCCR0A|=(1<<WGM01)|(1<<WGM00);  //PWM-Mode 3 (FastPWM)
    TCCR0A|=(1<<COM0A1);    //Non-Inverting PWM
    TCCR0A|=(1<<CS01);              // Prescaler auf 8
    }
}

von Stefan E. (sternst)


Lesenswert?

pwm-gast schrieb:
> TCCR0A|=(1<<CS01);              // Prescaler auf 8

Nö. Und ein Timer, der steht, kann natürlich auch keine PWM erzeugen.

Und von deinem eigentlichen Problem mal abgesehen: welchen Sinn hat es, 
die Initialisierung innerhalb der Endlosschleife zu haben und damit 
immer wieder und wieder auszuführen?

von pwm-gast (Gast)


Lesenswert?

Hallo,

Danke erstmal für die Antwort.
Also ich habe die Initialisierung aus der main rausgenommen. Das mit dem 
stehenden Timer habe ich allerdings nicht verstanden bzw. läuft der doch 
nach der Initialisierung.

int main(void)
{
    DDRB|=0b10000000;
    OCR0A=0x80;
    TCCR0A|=(1<<WGM01)|(1<<WGM00);  //PWM-Mode 3 (FastPWM)
    TCCR0A|=(1<<COM0A1);    //Non-Inverting PWM
    TCCR0A|=(1<<CS01);

while(1)
return 0;
}

von Karl H. (kbuchegg)


Lesenswert?

pwm-gast schrieb:
> Hallo,
>
> Danke erstmal für die Antwort.
> Also ich habe die Initialisierung aus der main rausgenommen. Das mit dem
> stehenden Timer habe ich allerdings nicht verstanden

Schau nochmal ins Datenblatt, welches Steuerbit in welchem 
Kontrollregister beheimatet ist.
Hinweis: Nicht alle Bits sind im Kontrollregister TCCR0A. Es gibt bei 
deinem µC noch ein zweites: TCCR0B


Wenn du von woanders Code übernimmst, der für einen anderen µC (auch aus 
derselben Familie) geschrieben wurde, musst du IMMER mit dem für deinen 
µC relevanten Datenblatt kontrollieren, ob
* die Bitnamen auch dasselbe bedeuten (tun sie in deinem Fall)
* die Bits auch in diesem Register sind

Tust du das nicht, kannst du ordentlich auf die Schnauze fallen.
Daher: Das Datenblatt ist dein Freund, deine Bibel, die einzige für 
deinen µC relevante Autorität!

>
> while(1)

da fehlt mindestens ein ;

Du willst ja nicht endlos oft einen 'return 0;' ausführen.

Wenn du dir nicht sicher bist, dann benutz halt die Langform mit { }
1
    while( 1 )
2
    {
3
    }
4
5
    return 0;

so kann dann auch ein Blinder greifen, dass es in der Hauptschleife 
nichts zu tun gibt.

von pwm-gast (Gast)


Lesenswert?

Hallo,

das ; bei while ist durchs kopieren untergegangen, im Quelltext verwende 
ich die Langform, bei sowas meckert ja eh der Compiler.
Das Datenblatt habe ich hier liegen, den Code habe ich versucht selbst 
zu schreiben, daher funktioniert es wohl auch nicht :)


Karl Heinz Buchegger schrieb:
> Hinweis: Nicht alle Bits sind im Kontrollregister TCCR0A. Es gibt noch
> ein zweites: TCCR0B

Handelt es sich bei deinem Schlag auf meinen Hinterkopf um das Bit 7 des 
TCCR0B? Ich vermute es muss auf eins gesetzt werden. Allerdings verstehe 
ich nicht ganz was da vor sich geht. Irgendwie wird ein Vergleichswert 
gesetzt...
Also muss ich noch TCCR0B|=(1<<FOC0A); hinzufügen?

von Stefan E. (sternst)


Lesenswert?

pwm-gast schrieb:
> Also muss ich noch TCCR0B|=(1<<FOC0A); hinzufügen?

Nein.

Du sollst die von mir zitierte Code-Zeile anhand des Datenblattes 
überprüfen und korrigieren.

von pwm-gast (Gast)


Lesenswert?

TCCR0A|=(1<<CS01); ändert doch "nur" die Frequenz der PWM, oder? Diese 
wäre mir erstmal relativ egal.
Ich steh echt auf der Leitung, sorry.

von Werner (Gast)


Lesenswert?

pwm-gast schrieb:
> Das mit dem stehenden Timer habe ich allerdings nicht verstanden bzw.
> läuft der doch nach der Initialisierung.

Nein tut der nicht. Das könntest du dir z.B. mit dem Simulator in 
AVR-Studio auch ansehen, indem du den Wert im TimerCóunt0 Register 
verfolgst.

von Stefan E. (sternst)


Lesenswert?

pwm-gast schrieb:
> Ich steh echt auf der Leitung, sorry.

Wenn du mit meinem Hinweis, dass diese Zeile falsch ist, und 
Karl-Heinz's Ergänzung bezüglich des zweiten Steuerregisters das Problem 
nicht siehst, dann ja, ja du stehst echt auf der Leitung.

von pwm-gast (Gast)


Lesenswert?

TCNT0 = 0xFF;

jetzt läufts...

Ich dachte der Maximalwert wird bei fastpwm allein gesetzt.

von TestX .. (xaos)


Lesenswert?

pwm-gast schrieb:
> TCNT0 = 0xFF;
>
> jetzt läufts...
>
> Ich dachte der Maximalwert wird bei fastpwm allein gesetzt.

datenblatt lesen..kommt auf den pwm mode an ;)

von pwm-gast (Gast)


Lesenswert?

Stefan Ernst schrieb:
>> TCCR0A|=(1<<CS01);              // Prescaler auf 8
>
> Nö. Und ein Timer, der steht, kann natürlich auch keine PWM erzeugen.

Falscher Register
TCCR0B|=(1<<CS01);
so müßte es richtig sein.
So langsam wirds glaub ich.

von Karl H. (kbuchegg)


Lesenswert?

pwm-gast schrieb:
> Stefan Ernst schrieb:
>>> TCCR0A|=(1<<CS01);              // Prescaler auf 8
>>
>> Nö. Und ein Timer, der steht, kann natürlich auch keine PWM erzeugen.
>
> Falscher Register
> TCCR0B|=(1<<CS01);
> so müßte es richtig sein.
> So langsam wirds glaub ich.

Na endlich.
Schwere Geburt.

Der Punkt ist:
natürlich hätten wir dir sagen können, dass die Vorteilerbits in TCCR0B 
beheimatet sind. Aber dann hättest du dir wieder nicht im Datenblatt 
angesehen und verinnerlicht, dass es deren 2 Kontrollregister gibt.
So hast du eine Lektion durchgemacht, die du so schnell nicht wieder 
vergisst.
Auch Datenblattstudium will gelernt werden und wenn man es nie macht, 
lernt man es auch nicht.

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.