Wieso 8 PWM Kanäle beim ATmega 64

Gast #946818
Lesenswert?

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!
#946942
Lesenswert?

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
#947126
Lesenswert?

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
#947399
Lesenswert?

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?
#947459
Lesenswert?

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.
#947778
Lesenswert?

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
Angehängte Dateien:
#947884
Lesenswert?

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
#948156
Lesenswert?

@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
#948830
Lesenswert?

@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
Gast #948916
Lesenswert?

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
#950023
Lesenswert?

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

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren