Assembler Software PWM optimieren (beschleunigen)

TommyB

Team Bitschubse
17. Mai 2010
2.151
80
48
40
127.0.0.1 ;)
Sprachen
  1. C#
  2. VB.Net
  3. LunaAVR
  4. Assembler
  5. Python
Heyho :)

Ich programmiere zwar in Assembler, aber mir geht es hier um die generelle Praxis.

Ich habe ein Software PWM (Schleife mit 64 Durchläufen).
Wenn der Wert 63 ist soll die LED immer leuchten, bei 0 nie. So weit so klar.
Wenn der Wert jetzt 31 ist würde er 32x die led einschalten, danach 32x aus.
So ist es ja normal.

Schöner wäre ja aber in dem 31er Beispiel wenn er bei jedem neuem Durchlauf den Zustand der led toggeln würde. Das würde ja eine weit höhere Frequenz (und somit weniger Flimmern) ergeben.
Kann man sowas (ohne großen Codeaufwand weils ein Tiny13 der schon zu ~50% befüllt ist) umsetzen?
Wenn ja wie?

(p.s.: Hardware PWM kommt nicht in Frage da das Ding nur einen Timer hat (der bereits genutzt wird), ich aber 4 PWM Kanäle brauche)
 
Hi
Ich hab mich zwar damit noch nicht beschäftigt, könnt mir aber folgendes vorstellen....
PWM= Pulsweitenmodulation
Also, ich nehme mal einen Wert von 0 bis 99 (100%)
Einen Referenzzähler, der den Vergleichswert liefert, bei dem die LED ausschalten soll.
Einen Zeitzähler von 0 bis 99 ( wird vom Timer gezählt)
Programm:
Vergleich Zeitzähler mit Sollzähler. Wenn gleich, dann LED Aus
Vergleich Zeitzähler mit 0 , wenn Gleich, dann LED an
Geht auch:
Vergleich Zeitzähler mit Sollzähler, wenn größer aus sonst an
Damit würdest du ein unterschiedliches Puls-Pausenverhältnis bekommen und das natürlich für beliebig viele Kanäle. Da eine Änderung der Helligkeit im unteren und oberen Bereich kaum noch feststellbar ist, kann man einmal die Schrittweite des Sollzählers vergrößern und die oberen und unteren 10% weg- oder voll zuschalten.
Sollte dein Programm unterschiedliche Zykluszeiten haben, dann ist der Aufruf der PWM-Ausgabe in einer Zeit ISR vorzunehmen, damit ein gleichbleibender Impuls erzeugt wird.
Gruß oldmax
PWM.PNG
 
So in Etwa habe ich es ja auch, nur ohne den Timer :)
Das wäre auch zu langsam weil ich sozusagen 2 PWM ineinander verschachtelt habe.
Einerseits hab ich einen für die Helligkeit (gesamt) und dieser steuert denn entweder 3 (laufen in der selben Schleife) für Rot, Grün und Blau (an) oder eine Warteschleife (aus).
Funktioniert soweit auch sehr gut, nur sehe ich die LEDs flackern, also beim vorbei schaun (wie bei Röhrenfernseher auch). Obwohl ich ohne Sleep etc mit den internen 9,6Mhz renne. Das finde ich etwas unschön.

Daher die Frage ob man das optimieren kann.
Mal ein Beispiel (50%):
Code:
Normal PWM: 11110000
Optimiert:  10101010

Frage ist nur wie man das berechnen oder umsetzen könnte
 
Hallo,

So in Etwa habe ich es ja auch, nur ohne den Timer :)
Das wäre auch zu langsam weil ich sozusagen 2 PWM ineinander verschachtelt habe.
Einerseits hab ich einen für die Helligkeit (gesamt) und dieser steuert denn entweder 3 (laufen in der selben Schleife) für Rot, Grün und Blau (an) oder eine Warteschleife (aus).
Funktioniert soweit auch sehr gut, nur sehe ich die LEDs flackern, also beim vorbei schaun (wie bei Röhrenfernseher auch). Obwohl ich ohne Sleep etc mit den internen 9,6Mhz renne. Das finde ich etwas unschön.
also bei mir läuft ne PWM mit 4 Softwarekanälen mit nem alten Atmel (vergleichbar Tiny2313) in Assembler mit 4MHz externem Quarz. Da sieht man nichts flimmern. Ich habe für alle Kanäle den selben Rampenzähler verwendet. Nur die Steuerwerte werden unterschiedlich eingestellt. Sieh mal die Routinen im Projektbereich an (Magierstab).

Gruß
Dino
 
Mit welcher Auflösung laufen die?
Ich hab ja durch das Verschachteln quasi 12 Bit (jeweils 6) + Delay für die Verarbeitung.

Vielleicht versteht auch jeder etwas Anderes unter dem Begriff flimmern. Ich würde wie gesagt schätzen dass das so bei 50Hz liegt. Eigentlich nicht sichtbar, aber ich sehe das leider, Wenn auch nur aus dem Augenwinkel wenn ich wo anders hin schau.

Wenn ich den Quelltext soweit fertig hab kann ich den ja mal hier rein stellen. Die Schaltung ist easy. Nur der Tiny, 3 LEDs nebst Rv und 2 Taster.
 
Hallo,

Vielleicht versteht auch jeder etwas Anderes unter dem Begriff flimmern. Ich würde wie gesagt schätzen dass das so bei 50Hz liegt. Eigentlich nicht sichtbar, aber ich sehe das leider, Wenn auch nur aus dem Augenwinkel wenn ich wo anders hin schau.
so etwas wirst du nicht vollständig unterbinden können.

Es gibt ja zB fürs Jonglieren solche Kugeln am Faden die eine Farbwechsel-LED drinhaben. Wenn du die schnell rumschleuderst, dann siehst du auch Striche mit den einzelnen Grundfarben die für die Mischfarbe per PWM zusammengesetzt wurden. Es kommt immer auf die Bewegungsgeschwindigkeit an.

30-50Hz sieht du nicht mehr wenn du es ruhig ansiehst. Wenn du dich aber bewegst dann wirst du flimmern sehen. Das tue ich auch. Man kann das zB manchmal an den LED-Rücklichtern der Autos sehen wenn man den Kopf schwenkt. Dann fangen die auch an zu flimmern. Bei diesen LED-Anzeigen (Werbeanzeigen oder in Bussen, Bahnen, ...) sieht man auch ein flimmern durch die Multiplexfrequenz wenn man sich dran vorbeibewegt.

Wenn du das verhindern willst, dann mußt du mit deiner PWM-Frequenz in den Kiloherz-Bereich gehen.
Nehmen wir beispielsweise mal 1kHz PWM-Frequenz. Dann müßtest du für 64 Dimmwerte (6Bit) deinen Rampenzähler mit einer Frequenz von 64kHz erhöhen. Also alle 15,6µs um plus Eins. Wenn du 256 Dimmwerte haben willst (8Bit) dann brauchst du bei gleicher PWM-Frequenz (1kHz) eine Frequenz von 256kHz für deinen Rampenzähler (alle 3,9µs plus Eins).

Bei so hohen Frequenzen bekommst du mit Software-PWM selbst mit Assembler langsam echte Probleme. Der Controller macht dann neben der PWM-Erzeugung nichts anderes mehr.

Bei 256kHz Rampenzähler hätte dein Atmel bei 16MHz Takt grade mal 62 Befehle Zeit bis er den Zähler wieder um 1 erhöhen muß. In diesen 62 Befehlen muß dann alles ablaufen (Erzeugung der 256kHz, Vergleich mit PWM-Wert, Ausgang entsprechend schalten, ...). Das wirst du mit Software evtl noch mit einem Kanal hinbekommen, dann ist aber Schluß. Bei 64 Dimmwerten hättest du 250 Befehle pro Durchlauf zur Verfügung.

Gruß
Dino
 
Naja sogesehen hab ich ja 12 Bit PWM (1x 6 Bit für die Helligkeit, 1x 6 Bit für die Farben).
Und ich nutz die internen 9,6MHz schon voll aus (kein idle, sleep etc.).

Hmmm denn ist der Controller wohl zu langsam. Ok, ich werde es eh so lassen weil ich finde es geht noch so. Vielleicht findet sich später ja auch wer der an dem Source noch Optimierungspotential findet ;)
Hab da jetzt nur noch einen Bug drin den ich bisher nicht gefunden habe. Aber debugWire wird schon helfen. Die Frage ist nur wann ^^
Dann werd ich den Quelltext mal online stellen, vielleicht ist es ja für den ein oder Anderen noch interessant :)
 

Über uns

  • Makerconnect ist ein Forum, welches wir ausschließlich für einen Gedankenaustausch und als Diskussionsplattform für Interessierte bereitstellen, welche sich privat, durch das Studium oder beruflich mit Mikrocontroller- und Kleinstrechnersystemen beschäftigen wollen oder müssen ;-)
  • Dirk
  • Du bist noch kein Mitglied in unserer freundlichen Community? Werde Teil von uns und registriere dich in unserem Forum.
  •  Registriere dich

User Menu

 Kaffeezeit

  • Wir arbeiten hart daran sicherzustellen, dass unser Forum permanent online und schnell erreichbar ist, unsere Forensoftware auf dem aktuellsten Stand ist und der Server regelmäßig gewartet wird. Auch die Themen Datensicherheit und Datenschutz sind uns wichtig und hier sind wir auch ständig aktiv. Alles in allem, sorgen wir uns darum, dass alles Drumherum stimmt :-)

    Dir gefällt das Forum und unsere Arbeit und du möchtest uns unterstützen? Unterstütze uns durch deine Premium-Mitgliedschaft!
    Wir freuen uns auch über eine Spende für unsere Kaffeekasse :-)
    Vielen Dank! :ciao:


     Spende uns! (Paypal)