Nabends allerseits. Wie ja schon so mitbekommen spiele ich seit einiger
Zeit mit meinem STK600 - ATmega2560 rum. Zuletzt hatte ich ja die
AD-Wandlung am Wickel. Diese ist zum Glück nun zu 80% verstanden und das
Programm läuft so wie gewollt. Ergo, SUPER.
Nach dem das nun erledigt ist habe ich mich der Hardware-PWM gewidmet.
Vorerst mal steht das Programm durch die gut gemachten Artikel und
Tutorials.
Die Pulsweiten kann ich auch wie gewünscht ändern und die ausgebene
Spannung ist im Mittelwert um 0,1V auch der errechneten und gewünschten
entsprechend.
Nun aber mal zu meinen offenen Fragen.
1.)
Ich gebe ja die Taktfrequenz des CPUs vor. In meinem Fall 16MHz
1
F_CPU16000000UL
Den Prescaler habe ich auf 1 gesetzt und somit ja keine Teilung
1
TCCR1B=(1<<CS10);
Wenn ich einfach die Sys-frequ. angenommen halbiere, dann müsste doch
die PWM-Frequenz auch halbiert werden? Und das ist bei mir nie der Fall.
Egal ob ich 16Mhz, 8Mhz oder 2MHz austesete, am Oszi liegt immer 313 Hz
an.
Im selben Zusammenhang stellte sich mir dadurch die Frage, warum dem so
sei? Ich dachte mir folgendes:
- CPU bekommt Taktfrequenz vorgegeben (16MHz)
- setzte die Register entsprechend für Fast-PWM und invertiert, sowie
eben den Vorteiler von 1
- danach setze ich den Zähl-Endwert
1
ICR1=0x0C80;//3200
- zum Schluss noch den Zählvergleichswert um den Rechteckpuls zu
generieren
1
OCR1A=0x0A00;//2560
So, wenn ich nun mit 16Mhz zur 3200 zähle, dann brauch ich dafür 0,2ms,
was 5kHz entsprechen würde. Aber laut Oszi stehen da nur 313Hz an. Erst
wenn ich
1
ICR1=0x00C8;//200
setzte und natürlch OCR1A auch entsprechend reduziere, komme ich in den
kHz-Bereich. Wie kommt denn die Frequenz zu stande???
2.)
Nach der Ausgabe des PWM-Signals habe ich ein RC-Glied hinten dran.
R=100Ohm, C=220nF, Vcc=5V. Ich versteh noch nicht ganz die Analogie mit
der Mittelwertspannung. Also wie die zustande kommt schon. Jedoch ist
laut Oszi eine Gleichspannung von z.B. 600mV drauf. Die nachgeschaltete
LED leuchtet trotzdem noch, obwohl die mit n Laborschaltnetzteil erst ab
ca. 1,5V schwach zu leuchten beginnt. Häää??
3.) Weiterhin dachte ich, dass ich mit dem RC-Glied eine sinusförmige
Wechselspannung generiere. Bzw. in 1.Ord. einen Dreieckspuls und bei
weiterem integrieren eine sinusförmige Wechselspannung. Dabei kommt eine
relativ gleichmäße Gleichspannung raus, auch wenn immer gut 0,1V weniger
wie errechnet. Wo ist mein derzeitig nicht zu sehender Denkfehler?
Ach so, ich habe die Toolchain-Optimize aus Os gesetzt.
Ich danke recht herzlich für weiterhin hilfreiche Aufklärungen und
Erläuterungen warum ich ich wo gedanklich hänge.
THX
batty man schrieb:> Nabends allerseits. Wie ja schon so mitbekommen spiele ich seit einiger> Zeit mit meinem STK600 - ATmega2560 rum. Zuletzt hatte ich ja die> AD-Wandlung am Wickel. Diese ist zum Glück nun zu 80% verstanden und das> Programm läuft so wie gewollt. Ergo, SUPER.> Nach dem das nun erledigt ist habe ich mich der Hardware-PWM gewidmet.> Vorerst mal steht das Programm durch die gut gemachten Artikel und> Tutorials.> Die Pulsweiten kann ich auch wie gewünscht ändern und die ausgebene> Spannung ist im Mittelwert um 0,1V auch der errechneten und gewünschten> entsprechend.>> Nun aber mal zu meinen offenen Fragen.> 1.)> Ich gebe ja die Taktfrequenz des CPUs vor. In meinem Fall 16MHz>
1
F_CPU16000000UL
Damit setzt Du aber nicht die uC-Taktfrequenz, sondern nur ein
Compiler-Define, dass alle Macros wissen, was die Rechenbasis ist.
Den Takt des uC setzt Du über die Fuses (interner oder externe
Taktquelle, bei der internen gibt's noch Stufen, bei Extern musst
verschiedene Oszillatoren anschliessen).
> Den Prescaler habe ich auf 1 gesetzt und somit ja keine Teilung>
1
TCCR1B=(1<<CS10);
> Wenn ich einfach die Sys-frequ. angenommen halbiere, dann müsste doch> die PWM-Frequenz auch halbiert werden? Und das ist bei mir nie der Fall.> Egal ob ich 16Mhz, 8Mhz oder 2MHz austesete, am Oszi liegt immer 313 Hz> an.> Im selben Zusammenhang stellte sich mir dadurch die Frage, warum dem so> sei? Ich dachte mir folgendes:> - CPU bekommt Taktfrequenz vorgegeben (16MHz)
Falls Du das so machst wie Du oben geschrieben hast, mit dem F_CPU, dann
ändert sich tatsächlich nichts, der AVR macht weiter seinen
Standardtakt. Weiss nicht, welcher der Beim Atmega2560 ist, 1 Mhz oder 8
Mhz?
Ah ja, sehe gerade, der hat Standard auch 8 Mhz mit internem Oszillator
und das CKDIV8 gesetzt, also läuft er mit 1 Mhz.
> - setzte die Register entsprechend für Fast-PWM und invertiert, sowie> eben den Vorteiler von 1> - danach setze ich den Zähl-Endwert
1
ICR1=0x0C80;//3200
> - zum Schluss noch den Zählvergleichswert um den Rechteckpuls zu> generieren
1
OCR1A=0x0A00;//2560
> So, wenn ich nun mit 16Mhz zur 3200 zähle, dann brauch ich dafür 0,2ms,> was 5kHz entsprechen würde. Aber laut Oszi stehen da nur 313Hz an. Erst> wenn ich
1
ICR1=0x00C8;//200
setzte und natürlch OCR1A auch
> entsprechend reduziere, komme ich in den kHz-Bereich. Wie kommt denn die> Frequenz zu stande???
1 Mhz / 3200 = 312 Hz
>> 2.)> Nach der Ausgabe des PWM-Signals habe ich ein RC-Glied hinten dran.> R=100Ohm, C=220nF, Vcc=5V. Ich versteh noch nicht ganz die Analogie mit> der Mittelwertspannung. Also wie die zustande kommt schon. Jedoch ist> laut Oszi eine Gleichspannung von z.B. 600mV drauf. Die nachgeschaltete> LED leuchtet trotzdem noch, obwohl die mit n Laborschaltnetzteil erst ab> ca. 1,5V schwach zu leuchten beginnt. Häää??
Mmh, auf welches Zeitfenster hast Du das Oszi denn eingestellt, würdest
Du das Rechteckssignal sehen, wenn Du vor dem RC-Glied misst?
Wenn nach dem RC-Glied noch eine gemäß dem PWM-Signal schwankende
Spannung anliegt, dann leuchtet die LED, weil sie Schubweise immer genug
Spannung bekommt.
Also wenn Du mal die Grenzfrequenz von R=100 Ohm und C = 220nf
berechnest, dann kommt man auf 7.2kHz - d.h. bei einem PWM-Signal von
300 Herz siehst Du noch nicht einmal richtig, dass das RC etwas tut - es
lässt das Signal voll durch, es werden höchstens die Flanken etwas
geschwächt.
http://www.sengpielaudio.com/Rechner-RCglied.htm> 3.) Weiterhin dachte ich, dass ich mit dem RC-Glied eine sinusförmige> Wechselspannung generiere. Bzw. in 1.Ord. einen Dreieckspuls und bei> weiterem integrieren eine sinusförmige Wechselspannung. Dabei kommt eine> relativ gleichmäße Gleichspannung raus, auch wenn immer gut 0,1V weniger> wie errechnet. Wo ist mein derzeitig nicht zu sehender Denkfehler?> Ach so, ich habe die Toolchain-Optimize aus Os gesetzt.>> Ich danke recht herzlich für weiterhin hilfreiche Aufklärungen und> Erläuterungen warum ich ich wo gedanklich hänge.>> THX
Conny G. schrieb:> batty man schrieb:> ...> Den Takt des uC setzt Du über die Fuses (interner oder externe> Taktquelle, bei der internen gibt's noch Stufen, bei Extern musst> verschiedene Oszillatoren anschliessen).> ...> Ah ja, sehe gerade, der hat Standard auch 8 Mhz mit internem Oszillator> und das CKDIV8 gesetzt, also läuft er mit 1 Mhz.
Aha, denn ists ja wirklich logisch, dass diese Änderungen von mir zu
nichts führten. Danke. Zu dem ist somit wieder ein Sachverhalt bzw.
Missverständnis meinerseits klarergeworden.
> Mmh, auf welches Zeitfenster hast Du das Oszi denn eingestellt, würdest> Du das Rechteckssignal sehen, wenn Du vor dem RC-Glied misst?> Wenn nach dem RC-Glied noch eine gemäß dem PWM-Signal schwankende> Spannung anliegt, dann leuchtet die LED, weil sie Schubweise immer genug> Spannung bekommt.
Ja, vor dem RC-Glied ist ein schönes Rechtecksignal zu messen. Wie
gesagt ist das Signal im Mittelwert immer 0,1V unter dem der
berrechneten, also ganz i.O..
> Also wenn Du mal die Grenzfrequenz von R=100 Ohm und C = 220nf> berechnest, dann kommt man auf 7.2kHz - d.h. bei einem PWM-Signal von> 300 Herz siehst Du noch nicht einmal richtig, dass das RC etwas tut - es> lässt das Signal voll durch, es werden höchstens die Flanken etwas> geschwächt.> http://www.sengpielaudio.com/Rechner-RCglied.htm
Mit R=100 Ohm habe ich als Spannungsmax-Mittelwert ca 2,52V. Wenn ich
mein R auf 160 kOhm z.B. erhöhe dann ist U-mittelwert-max nur noch 1,5
V. Ausserdem reduziert sich meine Grenzfrequenz auf f=10Hz. Dann
leuchtet keine LED mehr. Problem dabei war ja das die PWM-Frequenz nicht
die der gewünschten ist. Denn anstatt der 312Hz wollte ich eigentlich
5kHz generieren.
Noch ein kleiner Tip.
Wenn du 3200 meinst, dann schreib auch 3200
Es ist perfekt, Zahlen in der Schreibweise zu schreiben, in der sie den
meisten Sinn machen. Sei das Binär, sei das Hexadezimal, sei das
Dezimal.
In deinem Fall macht Dezimal den meisten Sinn, denn das ist das System,
in dem du normalerweise rechnest. So hast du dir ja auch den Wert
ausgerechnet. Also ist
1
ICR1=3200;
perfekt.
Selbiges natürlich auch für alle anderen Register. Man benutzt immer die
Schreibweise, die in der gegebenen Situation den meisten Sinn macht. Ob
der Compiler aus einer Hex-Zahl sich das Bitmuster generiert, welches in
das Register zu laden ist, oder ob er das von einer Dezimalzahl
ausgehend macht, ist dem Compiler egal. Aber dir als Mensch ist es nicht
egal. Mit 3200 verbindest du viel mehr als mit 0x0C80.
Es spricht auch nichts dagegen, sich den zu ladenden Wert ausrechnen zu
lassen.
1
#define F_CPU 1000000UL
2
#define FREQU 313
3
#define PRESCALER 1
4
5
6
...
7
ICR1=((F_CPU/PRESCALER)/FREQU)-1
8
...
und schon kannst du mittels
1
#define FREQU 313
die Frequenz relativ komfortabel einstellen. Auf die Grenzen müsste man
noch achten, so dass ICR1 bei größer werdenden Frequenzen nicht 0 wird.
Aber auch das könnte man mit noch ein paar Makros erledigen.
Fazit: Lass den Compiler für dich die Routine-Aufgaben übernehmen!
Genau dafür hast du ihn.
So erst einmal Danke für den Tipp:
>Ah ja, sehe gerade, der hat Standard auch 8 Mhz mit internem Oszillator>und das CKDIV8 gesetzt, also läuft er mit 1 Mhz.
ich habe jetzt in den Fuse das Bit CKDIV8 rausgenommen, wodurch sich die
CPU-Frequenz auf 8MHz erhöht hat.
Promt stieg bei dem Zählendwert
1
ICR1=3200;
die PWM-Frequenz auf 2,5kHz. Voller Freude denn dann hab ich das mit
der Frequenz nicht falsch berechnet sondern nur die falsche Angabe
benutzt. Jetzt hab ich
1
ICR1=1600;
und bekomme somit meine gewünschten 5kHz. Echt n dickes Danke. Freut
mich voll.
Wenn mein Programm die Dezimalzahl auch frisst dann nutze ich natürlich
diese. Thx for dis Tipp :D liest sich auch wesentlich schneller und vor
allem verständlicher.
Das mit der Rechnung:
1
#define F_CPU 1000000UL
2
#define FREQU 313
3
#define PRESCALER 1
4
5
6
...
7
ICR1=((F_CPU/PRESCALER)/FREQU)-1
8
...
ist ja auch ne geile übersichtliche Vereinfachung. Volle Logik, GEIL!!!
Jetzt muss ich nur noch was mit dem RC-Glied was vernünftiges anfangen.
Fragt sich nur was bei 5kHz eine sinnvolle Grenzfrequenz so ist?!?
Mal so noch ne andere Frage:
Ist es an sich egal ob ich normale PWM oder invertierte erzeuge? Also
das die Pulse immer zum Zählstartwert high oder eben bei Zählendwert low
werden ist mir schon klar. Dadurch verschiebt sich ja mein Puls auch auf
der Zeitskala. Welche Variante davon ist sinnvoller bzw. was wären denn
die Vor-Nachteile der verfahren?
batty man schrieb:> der Zeitskala. Welche Variante davon ist sinnvoller bzw. was wären denn> die Vor-Nachteile der verfahren?
Du kannst keine Hardware-PWM erzeugen, bei der du den Duty-Cycle
komplett auf 0 stellst. Selbst bei
1
OCR1A=0;
hast du immer noch kurze Puls am Ausgang. Wohl aber kannst du OCR1A auf
ICR1A bzw. größer setzen und erreichst damit eine PWM die tatsächlich
100% der Zeit auf an ist.
D.h. du musst dich prinzipiell zwischen 2 Möglichkeiten entscheiden:
entweder du brauchst einen der beiden Endwerte 0% bzw. 100% nicht, dann
kannst du mittels Pin-Invertierung den jeweils nicht gebrauchten Endwert
der 0 im OCR1A Register 'zuordnen'
oder aber du musst den aufwändigeren Weg gehen und für eine PWM von 0
den Timer vom Pin abkoppeln und händisch auf Dauer-0 (oder Dauer-1)
stellen.
Abgesehen davon fällt mir dann nur noch ein, dass es ja nicht
Gott-gegeben ist, das ein höherer OCR1A Wert auch automatisch ein
höheres-was_auch_immer_am_Ausgang_hängt zur Folge haben muss. Du kannst
ja genausogut auch ein 'Je höher der ADC-Wert desto dunkler die LED'
haben wollen. Klar kann man das auch im Programm per Arithmetik
erreichen, man kann aber auch einfach die PWM invertieren.