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!.
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
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.
Große Freude super. Es funktioniert. Auch wenn ich nur die Zeile DDRB = DDRB | (1 << PB1); vergessen habe, ich hätte noch fünfmal das Datenblatt gelesen, gegoogelt etc. und wieder bis in die späte Nacht gegrübelt. Danke Karl Heinz und Otto für die super Hilfe.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.