Forum: Mikrocontroller und Digitale Elektronik Wieso 8 PWM Kanäle beim ATmega 64


von Thomas (Gast)


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!

von Tobi (Gast)


Lesenswert?

Indem 1 Timer mehrere Compare-Register hat!

von Timmo H. (masterfx)


Lesenswert?

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.

von Thomas (Gast)


Lesenswert?

Super, alles klar!

Danke

von Aike T. (biertrinker)


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

von Martin T. (mthomas) (Moderator) Benutzerseite


Lesenswert?

PWM Frequenz? Wenn nicht allzu hoch: Software-PWM

von Falk B. (falk)


Lesenswert?

@Martin Thomas (mthomas)

>PWM Frequenz?

5kHz.

> Wenn nicht allzu hoch: Software-PWM

Das wird eng ;-)

MFG
Falk

von Aike T. (biertrinker)


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

von Иван S. (ivan)


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?

von Maik F. (sabuty) Benutzerseite


Lesenswert?

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.

von Иван S. (ivan)


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.

von Aike T. (biertrinker)


Angehängte Dateien:

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

von Иван S. (ivan)


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

von Aike T. (biertrinker)


Lesenswert?

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.

von Falk B. (falk)


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

von Aike T. (biertrinker)


Lesenswert?

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.

von Falk B. (falk)


Lesenswert?

@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

von Aike T. (biertrinker)


Lesenswert?

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 :-(

von Falk B. (falk)


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

von Alex Wenger (Gast)


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

von Aike T. (biertrinker)


Lesenswert?

@Falk nö, bei 10 Bit

@Alex
Hm, sehr interessant, das muss ich mir genauer ansehen - so spontan raff 
ichs noch nicht ;-)

von Maik F. (sabuty) Benutzerseite


Lesenswert?

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 ;)

von Aike T. (biertrinker)


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

von Aike T. (biertrinker)


Lesenswert?

Wollte das hier gerade nochmal aufwärmen, ich komme hier sonst nicht 
weiter, was ist denn _BV?

von Falk B. (falk)


Lesenswert?

_BV ist ein Makro aus alten Zeiten des GCC. Siehe Doku der libc, ist 
beim GCC  dabei.

MFg
Falk

von Timmo H. (masterfx)


Lesenswert?


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
Noch kein Account? Hier anmelden.