Der Quellcode ist sehr einfach und bedarf keiner Kommentare. Bei der
Ausführung auf einem ATmega8 @ 8Mhz blinkt die LED ungefähr in einem 1/2
Sekunden Takt. Daraus folgere ich, dass die while-Schleife wohl nur
zweimal in der Sekunde durchläuft. Kann das sein?
Ja, das kommt hin.
Vier Vergleiche a vier Takte, ein inkrementieren 2 Takte, 2 Takte für
die Schleife. Macht im besten Falle 20 Takte, die 2^16 Mal durchlaufen
werden - macht 1.3 Millionen, also nicht sehr weit von deinen
geschätzten 4 Millionen entfernt.
Maxim wrote:
> Sekunden Takt. Daraus folgere ich, dass die while-Schleife wohl nur> zweimal in der Sekunde durchläuft.
Die while Schleife wird schon öfter als 2 mal in der Sekunde
durchlaufen. Aber phase muss jedesmal bis 65535 hochgezählt werden,
bis dann durch den Überlauf wieder 0 in phase steht. Wenn das
2 mal pro Sekunde passiert, ist die while Schleife also mehr
in der Größenordnung von 130000 mal durchlaufen worden.
>Die while Schleife wird schon öfter als 2 mal in der Sekunde>durchlaufen. Aber phase muss jedesmal bis 65535 hochgezählt werden,>bis dann durch den Überlauf wieder 0 in phase steht. Wenn das>2 mal pro Sekunde passiert, ist die while Schleife also mehr>in der Größenordnung von 130000 mal durchlaufen worden.
Ach stimmt! War gestern zu müde um das zu sehen. Es gibt also keinen Weg
die PWM-Frequenz zu steigern? Wäre vielleicht ein Timer besser dafür
geeignet?
Maxim wrote:
> Ach stimmt! War gestern zu müde um das zu sehen. Es gibt also keinen Weg> die PWM-Frequenz zu steigern? Wäre vielleicht ein Timer besser dafür> geeignet?
Gibt es einen triftigen Grund für eine 16-Bit-Zählvariable? Entweder ne
8-Bit-Variable nehmen (Faktor 256 in der Geschwindigkeit) oder sozusagen
ein "CTC" (Clear Timer on Compare Match) in Software machen, also bei
Erreichen eines bestimmten Zählwertes den Zähler zurücksetzen. Ich denke
mal, eine Auflösung von 65536 Schritten ist i.d.R. eh nicht wirklich
sinnvoll.
BTW:
Ich sehe grad, dass r, g, und b sowieso nur 8 Bit breit sind. Was soll
dann überhaupt das mit der 16-Bit-Zählvariable? phase sollte
sinnigerweise auch uint8_t sein, und nicht uint16_t.
>Gibt es einen triftigen Grund für eine 16-Bit-Zählvariable? Entweder ne>8-Bit-Variable nehmen (Faktor 256 in der Geschwindigkeit) oder sozusagen>ein "CTC" (Clear Timer on Compare Match) in Software machen, also bei>Erreichen eines bestimmten Zählwertes den Zähler zurücksetzen. Ich denke>mal, eine Auflösung von 65536 Schritten ist i.d.R. eh nicht wirklich>sinnvoll.>BTW:>Ich sehe grad, dass r, g, und b sowieso nur 8 Bit breit sind. Was soll>dann überhaupt das mit der 16-Bit-Zählvariable? phase sollte>sinnigerweise auch uint8_t sein, und nicht uint16_t.
Danke für deine Vorschläge. Die 16-Bit-Auflösung ist nicht sinnlos
gewählt. Ich braue sie um später ein exponentielles Anwachsen des
Stromes durch einen linearen Faktor im Programm zu realisieren. Die
8-Bit Variablen r, g und b werden dann durch eine Tabelle auf einen
16-bittigen Wert umgerechnet, welcher mit dem Zähler vergliechen wird
...
Zuerst muss das Programm aber wenigstens so funktionieren. Ich habe den
Zähler auf Timer1 umgestellt. Die LED blinkt trotzdem etwa zweimal in
der Sekunde auf. Es kann doch nicht sein, dass der ATMega8 bei 8Mhz
keine dreifache software-PWM packt?!
Ach ja, CTC passt hier nicht, da ich ja drei unabhängige PWM-Signale
brauche.
Maxim wrote:
> Danke für deine Vorschläge. Die 16-Bit-Auflösung ist nicht sinnlos> gewählt. Ich braue sie um später ein exponentielles Anwachsen des> Stromes durch einen linearen Faktor im Programm zu realisieren. Die> 8-Bit Variablen r, g und b werden dann durch eine Tabelle auf einen> 16-bittigen Wert umgerechnet, welcher mit dem Zähler vergliechen wird> ...>> Zuerst muss das Programm aber wenigstens so funktionieren. Ich habe den> Zähler auf Timer1 umgestellt. Die LED blinkt trotzdem etwa zweimal in> der Sekunde auf. Es kann doch nicht sein, dass der ATMega8 bei 8Mhz> keine dreifache software-PWM packt?!
Doch, aber nicht mit der Auflösung. So ist das nunmal in einer
Hochsprache. Und dann auch noch mit 16-Bit-Zahlenwerten, deren
Verarbeitung sowieso deutlich länger dauert als bei 8-Bit-Werten.
> Ach ja, CTC passt hier nicht, da ich ja drei unabhängige PWM-Signale> brauche.
Das eine hat mit dem anderen nichts zu tun. Ich sagte schließlich "in
Software". Und da kannst Du auch einen Grenzwert setzen, ohne dafür
andere Ressourcen einzubüßen. Das ist dann nur eine zusätzliche Abfrage,
die zwar an sich den Durchlauf der Schleife ein wenig verlängert, aber
insgesamt gesehen das ganze durchaus beschleunigen kann. Wenn Du
anstelle von 16 Bit auf z.B. 11 Bit runtergehst, hast Du immerhin einen
Faktor von ungefähr 32 in der Geschwindigkeit gewonnen. Du zählst dann
eben nicht bis 65535, sondern nur bis 2047. Dementsprechend sind dann
natürlich auch die Tabellenwerte anzupassen. Da die Größe der Tabelle im
Mega8 sowieso ziemlich beschränkt sein dürfte (es sei denn, Du legst die
Werte in einem externen Speicher ab), wirst Du um eine (lineare)
Interpolation von Stützwerten eh nicht rumkommen. Und da macht es sicher
keinen sichtbaren Unterschied, ob Du mit 16 oder mit 11 Bit arbeitest.
@ Maxim (Gast)
>Danke für deine Vorschläge. Die 16-Bit-Auflösung ist nicht sinnlos>gewählt. Ich braue sie um später ein exponentielles Anwachsen des>Stromes durch einen linearen Faktor im Programm zu realisieren. Die
AHA.
LED-Fading>der Sekunde auf. Es kann doch nicht sein, dass der ATMega8 bei 8Mhz>keine dreifache software-PWM packt?!
Schon mal nachgerechnet? Per 16 Bit Timer und 8 MHz Takt kommst du auf
~123Hz PWM-Freqeunz. Pech nur dass deine Schleife "etwas" mehr als einen
Takt braucht.
Ergo.
Mach eine 8-Bit PWM in Software, das reicht. Siehe Artikel.
>Ach ja, CTC passt hier nicht, da ich ja drei unabhängige PWM-Signale>brauche.
Dann brauchst du einen festen Timer, der den PWM Takt in Software
nachbildet.
100 Hz, 8 Bit -> 39us.
MfG
Falk