Hallo Leute! Ich bräuchte für meine Anwendung 6 PWM Kanäle mit ca. 5kHz. Hab mir gedacht ich kann den ATmega64 nehmen, weil ich im Datenblatt gelesen habe: - Two 8-bit PWM Channels – 6 PWM Channels with Programmable Resolution from 1 to 16 Bits Und das versteh ich jetzt nicht ganz. Der hat doch nur 4 Timer (2 8Bit und 2 16Bit). Wie kann das dann funktionieren? Vielen Dank für eure Hilfe, Thomas!
Die Timer geben ja quasi nur den Takt vor. Im PWM Modus hast du meherere Compare-Register pro Timer (3 Stück je 16-Bit Timer), macht also 6 und eben die 2 für die 8-Bit Timer.
Hallo, wo ich das gerade lese, ich suche noch nach einem günstigen µC der 6 16 Bit PWM Ausgänge hat. Der mega64 würde ja passen, aber ist mit 4,85 bei Reichelt recht teuer für meinen Fall. (ich will davon 36 Stück verbauen) Naja, überdimensioniert wäre es wohl auch, da das Programm nur ca. 1 kb groß wird. Habe ich vielleicht noch irgendein Model übersehen? viele Grüße Biertrinker
@Martin Thomas (mthomas) >PWM Frequenz? 5kHz. > Wenn nicht allzu hoch: Software-PWM Das wird eng ;-) MFG Falk
Mir würden ja 100 Hz reichen, aber mit Software-PWM komme ich nicht über 10 Bit raus. Ich brauche aber für für eine etwas aufwendigere Kombination aus HSV-RGB Konvertierung und Helligkeitskorrektur. Daher suche ich nach einem Kontroller mit 6 16Bit Hardware-PWMs. viele Grüße Biertrinker
Hallo Aike, die Z8 Encore MC könnten etwas für Dich sein, die haben 6 Kanälee 12bit PWM. Schöne Architektur noch dazu. Aber wird wohl auch nicht deinen Preiswunschvorstellungen entsprechen, der mit 4k Flash kostet nämlich auch 4 Euro. Echte 6-Kanal 16bittige PWM schafft aber der ATmega64 auch nicht. Externe Single Channel PWM-Controller-ICs kosten auch an die 40 Cent pro Stück, das ist anscheinend wieder zu teuer. Ergo: So billig wie Du das willst geht es nicht ;) Müssen es wirklich 16 Bit Auflösung sein, bei der geringen Frequenz? Vielleicht gibts eine andere Lösung zu dem Problem, HSV kann man mittels Formel nach RGB wandeln, Helligkeitskorrektur ist doch nur die Veränderung des V-Werts. Wozu also die PWM?
Wie wäre es mit einem TLC5940 als LED-Treiber? Wenn dir 120mA pro Kanal ausreichen, ist das was, denn der IC hat 16 Kanäle mit 12 bit PWM. Und kann seriell von einem µC konfiguriert werden.
Maik F. wrote: > Wie wäre es mit einem TLC5940 als LED-Treiber? Wenn dir 120mA pro Kanal > ausreichen, ist das was, denn der IC hat 16 Kanäle mit 12 bit PWM. Hallo Maik, kein schlechter Tip, allerdings wollte der OP doch 16Bit. Der TLC5943 ginge jedoch, aber der ist dem OP bestimmt wieder zu teuer, denn den kriegt er auch nicht für unter 3 Euronzen. Außer er nimmt ein Kilo. Mir hats jedenfalls was gebracht, diese ganzen LED-Treiber-Chips kannte ich noch nicht.
Guten Morgen, also, erstmal vielen dank für die interessanten Tipps. Den TLC5940 muss ich mir nochmal genauer ansehen, der ist echt interessant. Allerdings denke ich, das ich mit 12 Bit nicht so recht weiter komme. Ich schaffe per Software-PWM 9 Bit Auflösung, mit etwas Optimieren 10 Bit. Ob ich nun mit 1024 Schritten arbeite oder mit 4096 macht dann nicht den großen unterschied. Allerdings stelle ich gerade fest, das möglicherweise meine Probleme auch mit 16 Bit nicht besser werden. Ich habe mal zwei Diagramme angehängt. Da kann man schön sehen, das die Ecken in der Ausgleichskurve am Anfang auch nicht viel besser werden, wenn man auf 16 Bit wechselt. Da werde ich also dann doch mir noch was einfallen lassen müssen. Oder gibts da nen Trick, das man die Stufen nicht so sieht? viele Grüße Aike
Lol Aike, you made my day! Aike Terjung wrote: > Ich habe mal zwei Diagramme angehängt. Da kann man schön sehen, das die > Ecken in der Ausgleichskurve am Anfang auch nicht viel besser werden, > wenn man auf 16 Bit wechselt. Die Ecken sind doch alle gleich groß! Nur deine Skala ist logarithmisch. > Da werde ich also dann doch mir noch was einfallen lassen müssen. > Oder gibts da nen Trick, das man die Stufen nicht so sieht? Lineare Skala nehmen, sicht gleich viel besser aus ;) > viele Grüße > Aike hth, Iwan
Ja, das ist schon richtig, auf der Zeichnung sieht das gut aus, wenn ich eine Lineare Skala nehme. Aber da das Auge leider auch quassi-Logaritmisch Helligkeiten wahrnimmt zeigt die Logarithmische Darstellung eben auch genau das Problem.
@Aike Terjung (biertrinker) >quassi-Logaritmisch Helligkeiten wahrnimmt zeigt die Logarithmische >Darstellung eben auch genau das Problem. Nicht ganz. Was du darstellst ist das Quantiesierungsrauschen relativ zum Ausgabewert. Und das ist prinzipiell mathematisch bedingt ganz unten sehr gross. Wenn du mit einem 8Bit oder auch 16Bit DAC den Wert 1 ausgibst, hast du ein Rauschen von 50%. Und auch wenn die Dynamik des Auges sehr hoch ist, 16 Bit schafft es in einer Beleuchtungssituation kaum, denke ich mal. Deswegen sieht man am Tage auch keine Sterne. MFG Falk
Das heißt du meinst das man bei 16 Bit keine Sprünge mehr sehen würde? Ich werde das mal mit einem einzelkanal probieren, da kann ja auch der Mega8 16Bit.
@Aike Terjung (biertrinker) >Das heißt du meinst das man bei 16 Bit keine Sprünge mehr sehen würde? Dazu reichen bisweilen 8..10 Bit, siehe LED-Fading. MFG Falk
Nun da drehe ich mich aber im Kreis, da haben meine Bemühungen angefangen ;-) Bei meinen Veruschen mit diesem Code sind bei den ersten paar Stufen ganz gruselige Sprünge sichtbar :-(
@Aike Terjung (biertrinker) >Nun da drehe ich mich aber im Kreis, da haben meine Bemühungen >angefangen ;-) Aha! >Bei meinen Veruschen mit diesem Code sind bei den ersten paar Stufen >ganz gruselige Sprünge sichtbar :-( Welche Auflösung? 16 Bit? Glaub ich kaum. Und vor allem bei welchem Umgebnungslicht? Klar, im dunklen Keller sieht man gerade im unteren Bereich bei SEEEEHR langsamen Dimmen Sprünge. Bei "normaler" Beleuchtung und nicht zuuu langesamen Dimmen sieht man bei 10 Bit nichts mehr. MFg Falk
Zum Dimmen will man ja eine log. Kennlinie haben, die bei 16Bit PWM zusätzliche Genauigkeit im oberen Bereich ist verschwendet. Was liegt also näher als eine PWM Routine zu schreiben die unterschiedlich aufgelöst ist? Die unteren 16 Stufen mache ich innerhalb der interrupt Routine weil sonst die Interruptfrequenz zu hoch wird. --- Was sonst bei Software PWM hilft ist sich ein Array an vorberechneten Werten zu berechnen, so daß der Interrupt diese nur noch an den Port schreiben muss. Etwas so: uint8_t leds[13]; SetLed(led, value) // LED (0-7) / value (0-4095) { for(uint8_t i = 0; i < 13; i++) { leds[i] &= ~_BV(led); if ((value & _BV(i)) != 0) leds[i] |= _BV(led); } interrupt() { switch(timer) { case 0: LEDPORT = leds[ 0]; break; case 1: LEDPORT = leds[ 1]; break; case 2: LEDPORT = leds[ 2]; break; case 4: LEDPORT = leds[ 3]; break; case 8: LEDPORT = leds[ 4]; break; case 16: LEDPORT = leds[ 5]; break; case 32: LEDPORT = leds[ 6]; break; case 64: LEDPORT = leds[ 7]; break; case 128: LEDPORT = leds[ 8]; break; case 256: LEDPORT = leds[ 9]; break; case 512: LEDPORT = leds[10]; break; case 1024: LEDPORT = leds[11]; break; case 2048: LEDPORT = leds[12]; break; } timer++; if (timer >= 4096) timer = 0; } dadurch enfällt alles rechnen im Imterrupt und man kann sehr schnelle Interrupts fahren und trotzdem 8x PWM machen. Weitere Optimierungen sind dann eben die unteren paar Bits mit nops innerhalb des Interrupts und oder umkonfigurieren des Interrupts: interrupt2() { LEDPORT = leds[timer]; OCR1A = 1 << timer; timer++; if (timer >= 13) timer = 0; } somit schafft man 8x 12Bit-PWM mit sehr wenig CPU last oder hoher Frequenz. Das Ausgangssignal sieht dann zwar nicht so aus wie man es von PWM gewohnt ist sondern so: normale 4Bit PWM Wert=5 : XXXXX__________ modifizierte 4Bit PWM Wert=5 : X__XXXX________ aber es kommt ja nur auf die Summe der Zeit an in der das Signal an ist, die Verteilung spielt keine Rolle. Alex
@Falk nö, bei 10 Bit @Alex Hm, sehr interessant, das muss ich mir genauer ansehen - so spontan raff ichs noch nicht ;-)
Schöne Verfahren, Alex :) Alex Wenger wrote: > aber es kommt ja nur auf die Summe der Zeit an in der das Signal an ist, > die Verteilung spielt keine Rolle. Ein Nachteil durch das häufigere Ein/Ausschalten sind erhöhte Verluste in den Mosfets. Mehr Kritik habe ich nicht, wenn es um LEDs geht ;)
Hallo Alex, also, ich arbeite mich gerade durch deinen Code. Könntest du mir nochmal erklären, was die Funktion SetLed macht? Also wann wird die aufgerufen, nur bei änderungen an der Farbe? Und was ist _BV? Das fehlt mir gerade noch, um das mal Testen zu können. viele Grüße Aike
Wollte das hier gerade nochmal aufwärmen, ich komme hier sonst nicht weiter, was ist denn _BV?
_BV ist ein Makro aus alten Zeiten des GCC. Siehe Doku der libc, ist beim GCC dabei. MFg Falk
Laut: http://www.mikrocontroller.net/articles/AVR-GCC#Tipps_.26_Tricks _BV(x) entspricht dabei (1<<x)
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.