Hallo miteinander,
Habe jetzt schon länger das Problem, dass ich es nicht schaffe auf einem
Atmega1284p ein 16bit PWM mit ca. 25kHz zu programmieren.
Ich brauche insgesamt vier unabhängige einstellbare PWM-Kanäle mit
unterschiedlichem duty-cycle - daher auch noch die Verwendung der
16bit-Timer (auf den 8bit-Timern läuft schon alles ohne Probleme).
Mein Problem ist nun allerdings, dass, egal ob im Fast-PWM Mode 14 oder
15, ich kein passendes Signal bekomme (habe leider kein Oszi um es zu
testen, aber das Empfangsgerät reagiert nicht, also unpassende
Frequenz).
Habe am Atmega den Fuse rausgenommen, damit er bei 8MHz läuft, womit
sich theoretisch folgender Code ergeben müsste:
Im Mode15:
1
DDRD=(1<<PD4);//PWM Timer1, OC1B, Pin18 - 16bit
2
3
TCCR1A=(1<<COM1B1)|(1<<WGM11)|(1<<WGM10);
4
TCCR1B=(1<<CS11)|(1<<WGM12)|(1<<WGM13);
5
6
OCR1A=40;//Top-Wert für 25kHz
7
OCR1B=10;//Duty-cycle
Im Mode14:
1
TCCR1A=(1<<COM1A1)|(1<<WGM11);
2
TCCR1B=(1<<CS11)|(1<<WGM12)|(1<<WGM13);
3
4
ICR1=40;//Top-Wert für 25kHz
5
OCR1A=10;//Duty-cycle
Doch mit beiden Ansätzen funktioniert es nicht.
Wäre Klasse, wenn jmd einen Rat hätte.
Grüße
Hi
>DDRD = (1<<PD4); //PWM Timer1, OC1B, Pin18 - 16bit
....
>OCR1A = 40; //Top-Wert für 25kHz>OCR1B = 10; //Duty-cycle
Hier ist OC1B der Ausgang, also PD5.
Die Initialisierung ist eigentlich, bis auf die Ausgänge, in Ordnung.
Lediglich der Topwert ist für 25kHz nicht 40 sondern 39.
MfG Spess
Den ICR1 will ich genau deshalb auch vermeiden, aber mich wundert
einfach, dass es mit beiden nicht geht.
Ja sry, TOP-Wert müsste 39 sein, war bloß zu faul es zu ändern, aber ist
gut innerhalb der Toleranz des Signals, also kein Problem.
Und ja, hab ich oben im Code vergessen: Bei Mode 14 hatte ich den
Ausgang auf OC1A.
Aber wieso soll OC1B auf PD5 sein? Bei mir im Datenblatt ist der PD4 und
der OC1A auf PD5 (da kann ich den Fehler auch ausschließen, da atm beide
auf Ausgang stehen, sowohl als auch, auch schon getestet).
Hi
>Keine Ahnung aber das Setzen des ICR1 ist nur bei Einzelereignissen>sinnvoll.>Den ICR1 will ich genau deshalb auch vermeiden, aber mich wundert>einfach, dass es mit beiden nicht geht.
Unsinn. Mit OCR1A als Top hast du nur einen PWM-Kanal. Mit ICR1 zwei.
>Aber wieso soll OC1B auf PD5 sein? Bei mir im Datenblatt ist der PD4 und>der OC1A auf PD5 (da kann ich den Fehler auch ausschließen, da atm beide>auf Ausgang stehen, sowohl als auch, auch schon getestet).
Entschuldige. War ein Versehen.
MfG Spess
> Unsinn. Mit OCR1A als Top hast du nur einen PWM-Kanal. Mit ICR1 zwei.
Das ist mir klar, aber das ändert ja leider nicht das Problem, dass es
nicht funktioniert.
Evtl. noch Ideen, wo der Fehler/das Problem liegen könnte?
Gruß
mit den ganzen Megas kannst du nur eine 16bit PWM mit maximal 305Hz
erzeugen.
xeno schrieb:> OCR1A = 40;
hiermit erzeugst du eine 5 komma irgendwas Bit PWM
Hi
>Evtl. noch Ideen, wo der Fehler/das Problem liegen könnte?
Sicher, das du das richtige Programm flasht? Ansonsten den Timer so
langsam machen, das du die PWM mit einer LED beobachten kannst.
MfG Spess
Vlad Tepesch schrieb:> mit den ganzen Megas kannst du nur eine 16bit PWM mit maximal 305Hz> erzeugen.>> xeno schrieb:>> OCR1A = 40;>> hiermit erzeugst du eine 5 komma irgendwas Bit PWM
Ich wollt schon fragen. 25kHz ist eine Periodendauer von 40µs. Das mit
16 bit.. Da müsste der Timer ja mit 1638.4 MHz laufen.
Moment, ich lege doch einen neuen TOP-Wert fest, damit er eben nur noch
bis dahin zählt - sonst würden all die Frequenzberechnungen ja keinen
Sinn ergeben.
Wieso sollte er dann noch die vollen 16bit durchlaufen? Es handelt sich
doch um einen Wertebereich für das Maximum des Interrupt-Flags, nicht
eine Konstante.
Oder habe ich da einen Denk-/Verständis Fehler.
Aus dem Datenblatt(Seite 126, Letzter Absatz aus 16.9.3 Fast PWM mode):
"The waveform generated will have a maximum frequency of
Wenn man eine 16bit PWM haben will, dann verwendet man eine 8Bit PWM und
macht nochmals 8 Bit mit Subzyklen. Dh man laesst sich den TimerOverflow
geben und laedt da einen neuen PWM wert. Und den laedt man mit
subzyklen. Also um einen PWM von 0x1280 zu haben laesst man den
hardwaere PWM auf 0x12 laufen und aendert in 0x80 von 256 durchgaengen
den Wert nach 0x13.
Hi
>"The waveform generated will have a maximum frequency of>f_{OCnA} = f_{clk(I/O)}/2> when OCRnA is set to zero (0x0000)."
PWM heisst Pulsweitenmodulation. Also es geht um ein Signal mit
variablen Tastverhältnis bei fester Frequenz. Bei OCRnA=0 gibt es aber
nichts mehr zu variieren. Da ist das Tastverhältnis 50%.
MfG Spess
Mal anders rum gefragt
> Doch mit beiden Ansätzen funktioniert es nicht.
Was genau funktioniert denn nicht?
Ich nehme mal an, die 25kHz stimmen nicht. Wie groß ist denn die
realisierte Frequenz?
> Habe am Atmega den Fuse rausgenommen, damit er bei 8MHz läuft
Und du hast auch kontrolliert, ob das stimmt?
Die Taktfrequenz ist Berechnungsbasis für alles weitere. Wenn die nicht
stimmt, kannst du rumrechnen soviel du willst, das wird nie stimmen.
Ja, das ist das Problem, habe leider kein Oszi zur Hand um die Frequenz
zu messen.
Der Fuse ist auf jeden Fall nicht mehr gesetzt, habe es eben noch einmal
überprüft. Außerdem laufen ja schon zwei 8bit-Timer mit selbem Prinzip
bei 25kHz (Timer0 und Timer2) auf dem Atmega mit passender
Signalausgabe.
@Spess53: Da gebe ich dir recht, das steht auch so direkt im Datenblatt
was du gesagt hast, wollte bloß nicht den ganzen Absatz kopieren, aber
es heißt wiederrum eben auch das höhere Frequenzen möglich sind.
@Hopp Triceratops: Wie würde man so etwas den konkret umsetzen?
Um das ganze Problem noch mal zu konkretisieren:
Es geht um die Ansteuerung von mehreren PWM-Lüftern, die ich eben gerne
in mehrere Kanäle splitten würde, da sie an unterschiedlichen Stellen
eingesetzt werden.
Das Stellsignal ist dabei auf 25kHz (erlaubt zwischen 23 und 28kHz, also
"kleine" Abweichungen kann ich auch ausschließen) bei +5V festgelegt,
der duty-cycle gibt dabei prozentual die Drehzahl an.
Grüße
holger schrieb:>>Es geht um die Ansteuerung von mehreren PWM-Lüftern,>> 16Bit PWM für einen beschissenen Lüfter.
Er hat keine 16 BIt PWM.
Er benutzt MOdus 14 oder 15.
(Also entweder ICR1 als Top oder OCR1A)
Hmm.
Ich hab mal deine Konfiguration mit dem Datenblatt verglichen und
nachgerechnet. Sie ist korrekt, wenn der µC ein Mega1284 ist und auf
8Mhz läuft.
Irgendwelche sonstige Beeinflussung im Code (Output Pin irgendwo
irrtümlich wieder abgeschaltet? OC2, also der Output vom Timer 2 liegt
am gleichen Port und wenn du den so
DDRD = (1<<PD7);
auf Output stellst, drehst du dir für den Timer 1 die Output Pins wieder
ab).
Mein Vorschlag: ein Testprogramm, bei dem nur und ausschlieslich diese
PWM in Betrieb genommen wird. Damit ist sicher gestellt, dass es nicht
irgendwelche Querverbindungen zu anderem Code gibt.
>>>Es geht um die Ansteuerung von mehreren PWM-Lüftern,>>>> 16Bit PWM für einen beschissenen Lüfter.>>Er hat keine 16 BIt PWM.
Das weiss ich. Ich finde nur den Betreff lustig.
Ansonsten hätte ich kein Problem damit per
PWM "La Paloma" von einer SD Karte auf einem
Lüfter per PWM abzuspielen;)
holger schrieb:>>>>Es geht um die Ansteuerung von mehreren PWM-Lüftern,>>>>>> 16Bit PWM für einen beschissenen Lüfter.>>>>Er hat keine 16 BIt PWM.>> Das weiss ich. Ich finde nur den Betreff lustig.> Ansonsten hätte ich kein Problem damit per> PWM "La Paloma" von einer SD Karte auf einem> Lüfter per PWM abzuspielen;)
Ja. Das hat was :-)
Karl Heinz Buchegger schrieb:> ...(Output Pin irgendwo> irrtümlich wieder abgeschaltet? OC2, also der Output vom Timer 2 liegt> am gleichen Port und wenn du den so> DDRD = (1<<PD7);> auf Output stellst, drehst du dir für den Timer 1 die Output Pins wieder> ab).
Och mist... Wie man sich an Kleinigkeiten eine Ewigkeit aufhalten
kann...
Das wars! Habe dummerweise die Outputs nacheinander (Zeilenweise)
definiert und das | (OR) vergessen.
Vielen dank dir!
Hoffe der Fehler war mir eine Lehre xD
@Holger: Dass das nicht gerade ein passendes Einsatzgebiet für einen
16bit-Timer ist, ist mir klar, ändert aber nix daran, dass man ihn dafür
verwenden kann ;)
Grüße