Forum: Mikrocontroller und Digitale Elektronik Suche Idee für ne Software-PWM


von Florian - der Flo - Scharf (Gast)


Lesenswert?

Hi .. Ich habe eine Schaltung hier, die viiiiele (36) PWM Signale
braucht. Sinn des ganzen ist das Ansteuern und Dimmen von LEDs.
Derzeit lasse ich einfach eine Schleife von 0 bis $Grenzwert laufen,
und überprüfe jedesmal, ob sich einer der 36 Werte auf der Schwelle
befindet, und wenn ja, geht der entsprechende Port auf High. Danach
geht das ganze rückwärts auf Null und die Ports werden auf low gesetzt.
Wenn nichts passiert, wird ein nop() ausgeführt um die Durchlaufzeiten
konstant zu halten.

Also so:

for (;;)
{

for (pwmcounter=0; pwmcounter<32; pwmcounter++) {

  if (pixel[0].r == pwmcounter) { P6OUT &=~BIT7; } else { nop(); }
  if (pixel[0].g == pwmcounter) { P6OUT &=~BIT6; } else { nop(); }
  if (pixel[0].b == pwmcounter) { P6OUT &=~BIT5; } else { nop(); }
  if (pixel[0].w == pwmcounter) { P6OUT &=~BIT4; } else { nop(); }

  if (pixel[1].r == pwmcounter) { P6OUT &=~BIT3; } else { nop(); }
  if (pixel[1].g == pwmcounter) { P6OUT &=~BIT2; } else { nop(); }

.......

und so weiter, und entsprechend wieder rückwärts.

Jedoch komme ich dabei mit meinem MSP430-149 und den 8MHz recht schnell
an die Grenze, ab der man es deutlich flimmern sieht, wenn ich mit der
Detailierungsstufe (im Moment 32, also 32 Helligkeitsstufen) höher
will. Ich würde aber noch gerne eine Linearisierung der Helligkeit mit
einbauen, und dazu reichen 32 Helligkeitsstufen einfach nicht aus.

Hat jemand eine Idee, wie ich die Überprüfung schneller machen könnte?
Vielleicht gibt es ja eine einfache binäre Linearkombination, die man
einfach drüberlegen könnte, die das schneller erledigt. Ich meine, wozu
hab ich denn eine 16-Bit CPU ;)

Thx,

der Flo

von Markus (Gast)


Lesenswert?

a) Schau Dir mal an, welchen Code der Compiler insbesondere für die
Arrayzugriffe generiert, vielleicht läßt sich hier etwas optimieren.

b) Erzeuge die fertigen Bitmuster und speichere sie portweise. Also für
36 LEDs 5 Byte (wenn Du dafür 5 Ports benutzt) und bei jedem Schritt
werden diese 5 Byte ausgegeben. Dann brauchst Du dafür 5*32=160 Byte
RAM. Das ganze dann per Timerinterrupt (50Hz * 32Abstufungen =
1600Interrupts/s) ausgeben. Die NOPs entfallen dabei; in der
Interruptroutine mußt Du nur die 5 Bytes ausgeben und den indexcounter
hochzählen. Ich hoffe, Du hast meine Erklärung verstanden (bin bloß
gerade zu faul Bildchen zu malen).

Markus

von Peter D. (peda)


Angehängte Dateien:

Lesenswert?

Du könntest für das Dimmen einen T89C51RD2 nehmen und diesem dann über
die UART die einzelnen Werte senden.

Anbei mal ein Programmbeispiel für den Timerinterrupt, der die PWM
macht.

Das Prinzip ist einfach:

dimmcount zählt runter und setzt alle 256 Zyklen alle LEDs an.
dimmval[0] ... dimmval[35] zählen ebenfalls runter und schalten die
ihnen zugeordnete LED wieder aus.

Die Differenz der dimmval Werte zu dimmcount entspricht also dem
Tastverhältnis.

Werden auch andere Interrupts verwendet (z.B. die UART), dann muß dem
Timer 0 die höchste Priorität zugewiesen werden, damit die LEDs nicht
flackern.

Da der T89C51RD2 im großen Gehäuse schwer zu kriegen ist, könnte man
auch 3 kleine AT89C2051 nehmen (2. Variante).

Ich denke mal, das die 130Hz (156Hz) und die 256 Stufen ausreichend
sind.


Peter

P.S.:
Beides sind 8051-er (8-Bitter) und ich habs mit dem Keil C51
compiliert.

von Dirk Broßwick (Gast)


Lesenswert?

hiho,

ich habe hier sowas schon mal in einen thread beschrieben wie man sowas
im software umsetzten kann, aber nur für den AVR.
http://www.mikrocontroller.net/forum/read-1-31884.html sollte reichen
um das beispiel zu übertragen.

CA

von Florian - der Flo - Scharf (Gast)


Lesenswert?

Hey Leute, danke für die Anregungen, damit sollte sich was basteln
lassen.

Peter:
Die Lösung ist zwar gut, aber ich hab schon genug mit Lastverteilung zu
tun, da ich einen µC als Steuereinheit benutze, und vier µC die PWMs
erzeugen lasse. Und da möchte ich mir nich noch mehr Programmier- und
Lötarbeit aufhalsen. :)

Markus:
Stimmt ja, Arrays sind ja nur Verweise, am Besten wärs wahrscheinlich,
ich programmier das hart auf 36 einzelne Variablen.

Wird wahrscheinlich so eine Lösung mit Bitmuster werden. freu


der Flo

von Peter D. (peda)


Lesenswert?

4 * 36 = 144 PWMs, wofür braucht man denn soviel ?

Hast du mal durchgerechnet, ob meine Variante nicht auch auf nem MSP
schnell genug läuft ?

Wenn der MSP keine Bitzugriffe auf die Ports kann, kann man ja auch
immer je 8 LEDs in einer Temp-Variable sammeln und dann ausgeben.

Aber mindestens die Tabellenvariante (Dirks Link) sollte ein MSP doch
schaffen. Braucht eben nur nen Haufen SRAM (5 * 256 = 1280 Byte).


Peter

von Dirk (Gast)


Lesenswert?

Hi,

ich frage mich nur ob jede LED einzeln gedimmt werden soll?
Ist es wirklich noetig alle LED's einzeln zudimmen?

Mfg

Dirk

von Florian - der Flo - Scharf (Gast)


Lesenswert?

Dirk:
Also ich brauch die 144 PWMs um eine Lichtmatrix zu basteln. Die sollen
zwecks Farbmischung auch dimmbar sein. Das sind dann insgesamt 12x3
Pixel à 4 Farben (RGBW). Und somit werden von pro MSP 3x3 Pixel
gesteuert, und noch einer übernimmt das Management, mit Knöpfen und
Display und RS232 und dem ganzen Krams.

Peter:
Das kann ruhig die kompletten 2k Ram verschlingen, sind ja dediziert
dazu da ;) und wenn ich die Tabellenvariante umsetze, garantiere ich
auch eine gleichmäßige und schnelle Abarbeitung der einzelnen Stufen.
Gefällt mir bisher am besten.

Schöne Grüße,

der Flo

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.