Hallo, ich beschäftige mich gerade mit der PWM-Problematik für ein LED-Projekt. Ich benutze auf dem Board von Pollin einen Atmega8, der extern mit 16MHz getaktet wird. Der µC macht auch soweit erstmal das, was er soll. Programmierung mit AVRISPMKII funktioniert, die UART gibt mir das Gewünschte auf dem Terminal aus, die Interrupts und die Timer funktionieren. Soweit so gut. Für die PWM-Geschichte versuche ich, den erste Codevariante aus dem TUT zu verwenden: http://www.mikrocontroller.net/articles/Soft-PWM Ich möchte mit 100Hz und 255 Schritten arbeiten. Ich lasse also meinen Timer bis 627 zählen, das sind bei 16MHz 25,5kHz. Wenn ich jetzt mit dieser Frequenz jeweils bis 255 zähle, dann sind das ca. 100Hz. Ich habe das nach bestem Wissen und Gewissen programmiert, aber ich muss einen ganz hohlen Denkfehler gemacht haben, denn die LED wird nicht etwa dunkler, sondern sie blinkt nur mit ca. 2Hz. Die UART sagt, dass der PWM-Zähler brav immer von 0 bis 255 zählt und auch an der entsprechenden Stelle die LED abschaltet. Also z.B. bei 150, wenn der Sollwert bei 150 steht. Aber irgendwie geht das viel zu langsam. Ich weiß echt nicht, was ich noch machen könnte. Ich habe das TCCR1B auseinandergenommen, überall die Frequenzen geprüft und bin mit meinem Latein erstmal am Ende. Es wäre schön, wenn mal jemand über meinen Quellcode drüber schauen könnte. Danke! Olaf
Der Atmega 8 hat 2 CTC-Modi. Der, den du verwendest (WGM=1100), lässt den Timer bis ICR1 laufen und nicht wie du annimmst bis OCR1A. Gruß Skriptkiddy
Hallo Oger hier dein Quelltext: //************* Timer ********************* TCCR1B=0; TCCR1B |=(1<<CS10); // ohne 1024 Prescaler TCCR1B &=~(1<<CS11); TCCR1B &=~(1<<CS12); TCCR1A=0; TCCR1A &=~(1<<WGM10); // CTC Modus TCCR1A &=~(1<<WGM11); TCCR1B |=(1<<WGM12); TCCR1B |=(1<<WGM13); OCR1AH =0x02; // Vergleichswert:3D09=15625=16000000/1024 =1s 0273 ist für PWM 627Takte für 100Hz mal 255 zählen OCR1AL =0x73; TIMSK |=(1<<OCIE1A); //Interrupt an //***************************************** //*************** Interrupt *************** MCUCR |= (1<<ISC01); // steigende Flanke für INT0 MCUCR |= (1<<ISC00); MCUCR |= (1<<ISC11); // steigende Flanke für INT1 MCUCR |= (1<<ISC10); GICR |=(1<<INT1); // INT0 und INT1 aktivieren GICR |=(1<<INT0); Fass deine Einstellungen zu jeweils 8-Bit zusammen. Also die Register in einem Rutsch programmieren. OCR1A ist ein 16Bit-Reg kannst also auch OCR1A = 0x0273; schreiben.
Hallo, danke für die Antworten! @Skriptkiddy: Ich habe jetzt das WGM auf 0100 geändert, damit laut Datenblatt jetzt das OCR1A für CTC benutzt wird. Leider macht der Timer das gleiche, wie vorher?! Was mich am meisten wundert ist, dass ich mit den vorherigen Einstellungen problemlos die 1s Zeitbasis für eine Uhr realisiert bekommen habe. Dort habe ich nur noch den 1024 Prescaler dringehabt und dann bis 15625 gezählt. Das hat wunderbar funkioniert... @Oger-Berserker: Danke für den Hinweis. Ich habe das so auseinandergezogen, damit ich besser nachschauen kann, was die einzelnen Bits bedeuten.
Also da deine UART-Verbindung funktioniert schätze ich mal das deine Fuses korrekt eingestellt sind. Wenn nicht kannst du dort ja nochmal genau nachschauen.
@Oger-Berserker: Ja, die Fuses sind in Ordnung. Extern-Crystal/Resonator, High-f... Ich werde morgen mal sehen, ob ich an ein Oszi rankomme, evtl. bringt mich das weiter.
Tjoa, mittelfristig komme ich nicht ins Labor, also keine Oszimessung. Hat noch jemand eine Idee, was das Problem bei meinem Code sein könnte?
Oger, ich würde das Programm zuerst mal vereinfachen. 1) Weg mit den anderen Interrupts (INT0, INT1) 2) ISR für den COMPA-Interrupt entschlacken. Die UART-Ausgabe inkl. itoa() haben dort nichts zu suchen. Die Debugausgabe von pwm_cnt ist wertlos. Wenn du COMPA-Interrupts verlierst, weil dein Debuggerötel zu lange dauert, wird zwar pwm_cnt sauber hochgezählt aber die PWM funktioniert nicht mit der beabsichtigten Frequenz. Pi*Daumen: Aufruf des COMPA-IRQ mit 25,5kHz, d.h. alle 0,04 ms. Reine Debugausgabe von 2 bis 8 Zeichen bei 9600 Baud: 2 bis 8 ms! => Statt 25.5 kHz hast du effektiv nur noch 0,5 kHz bis 0,125 kHz
@Helfer: Ich glaub' es nicht, die UART-Geschichte in der ISR des COMPA war das ganze Problem! Jetzt funktioniert alles wunderbar. Also daran hätte ich nie gedacht, dass die Umwandlung für uart_puts und dann natürlich die megalangsame Ausgabe selber mir meinen PWM-Takt verderben... Die UART war immer mein Standard-Debugger und weil ich kaum mal etwas wirklich schnelles gemacht habe, ist es mir nie aufgefallen, was da an Takten "verloren geht". Herzlichen Dank für deine Hilfe! Oger
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.