Einen wunderschönen guten morgen zusammen! Ich beschäftige mich zum ersten mal ernsthaft mit einer PWM und möchte gerne einen Sinus "simulieren". LEDs heller und dunkler leuchten lassen habe ich hinter mir - die generelle Erzeugung zur PWM sind klar. Jetzt würde ich gerne mal einen Sinus erzeugen, habe aber gerade eine leichte Denkblockade. Hierzu habe ich mich schon ein wenig durchs Internet geklickt und mehrere Beiträge gelesen, stehe aber noch ein wenig auf dem Schlauch. Aber ich erzähl erstmal, was ich mir vorgestellt habe - bitte korrigiert mich, wenn ich hier schon was falsch verstehe: - Ich möchte 256 diskrete Stufen machen, also quasi einen 8-Bit-Sinus - Diese diskreten Stufen sind sozusagen meine Zeitachse (x-Achse) - Dieser 8-Bit-Wert ist nun mein Zählindex, für den ich y-Werte berechne - Imaginär lege ich mir die Nullinie nun auf Vcc/2 - Bei x= +127 wähle ich y= 100% - Bei x= 0 wähle ich y = 50% - Bei x= -127 wähle ich y= 0% - Die y-Achse ist somit mein Timer-Wert (16-Bit-Timer: 0x0000 - 0xFFFF) - Über diesen Timer kann ich die Frequenz des Signals bestimmen - Über die %-Werte kann ich den Duty-Cycle einstellen Als Beispiel: Würde ich den Timer im Set-Reset-Mode betreiben und würde für den Timer einen Wert von 0x8000 (32768), so müsste ich, um hier einen Duty-Cycle von 50% hinzubekommen, den Compare Wert zum Reset auf 0x4000 (16384) einstellen. Ergo müsste ich mir eine Funktion aufstellen, welche mir zu jedem x, also zu jedem der 256 Stufen, einen %-Wert errechnet. Dieser Wert wäre ja fix und könnte als Tabelle abgelegt werden. Durch diesen Prozent-Wert, welcher ja relativ ist, könnte ich nun zu jeder beliebigen Frequenz, also meinem Timer-Wert, den entsprechenden Reset-Wert errechnen. Das müsste natürlich zur Laufzeit passieren. Jetzt meine Frage: Ist die Denkweise erstmal grundsätzlich falsch, bzw. macht man das ganz anders? Es geht mir halt darum, die Frequenz verändern zu können. Bitte gebt mir mal ein Feedback dazu! Vielen Dank
Ich würde das mit einem Akkumulator bauen. Also eine Zählvariable, die bei jedem PWM-Takt um einen gewissen Wert erhöht wird. Über diesen Wert kannst du deine Frequenz einstellen (besser als über einen Zähler). Die Zählvariable des Akkumulator kann dann auf deine Tabelle verweisen. Dabei kann die Zählvariable ruhig 16 Bit breit sein, während deine Tabelle nur 256 Werte hat. Du verwendest als Index dann einfach das MSB. Man bekommt zwar so kleine Rundungsfehler, aber das macht nichts.
PWM-Neuling schrieb: > Jetzt meine Frage: Ist die Denkweise erstmal grundsätzlich falsch, bzw. > macht man das ganz anders? Nein und nein. Du kannst auch zwei Timer nehmen: einen, der sich um die PWM an sich kümmert und einen der nach einer gewissen Zeit den Compare-Wert ändert.
PWM-Neuling schrieb: > Es geht mir halt darum, die Frequenz verändern zu können. Welche Frequenz? Erst mal so: die PWM-Frequenz ist fix. Nur das Tastverhältnis wird geändert. Du kannst also nur deine "Sinus-Frequenz" meinen. Und da ist klar: du legst dir eine Tabelle mit dem Sinus an. Und dann liest du über einen Index irgendeinen Wert aus dieser Tabelle aus, skalierst den ein wenig um, und addierst den zu deinem Compare-Wert 0x4000 (um bei deinen Beispielwerten zu bleiben) dazu. Das Weiterschalten erfolgt einfach mit einem "anderen" Timer, der nach einer bestimmten Zeit den Index ändert und damit den nächsten Wert aus der Sinus-Tabelle holt... Das könntest du natürlich beliebig verfeinern, indem z.B. zwischen 2 Stützpunkten der Tabelle noch interpoliert wird, um eine feinere Auflösung hinzubekommen... BTW: Es reicht, 1/4 des Sinus in die Tabelle zu legen, der Rest des Sinus wird einfach gespiegelt und invertiert... Ich habe sowas (leider nur in VHDL, aber die Idee ist die selbe) dort mal dokumentiert: http://www.lothar-miller.de/s9y/archives/57-Sinusausgabe-mit-PWM.html 1. Der Wert aus einem Sinus-Generator, der einen "langsamen" Sinus erzeugt, 2. wird als Vergelichswert einer PWM-Einheit verwendet. Du siehst, dass die PWM-Frequenz vom PWM_OUT konstant bleibt und sich nur das Tastverhältnis ändert.
Also schonmal danke für die Antworten! Ganz ist es mir jedoch noch nicht klar... Stefan L. schrieb: > Über diesen Wert > kannst du deine Frequenz einstellen (besser als über einen Zähler). Also würde ich bei steigender Frequenz einfach Zwischenschritte auslassen, oder wie soll ich das verstehen? Mein Sinus würde also hakeliger? Lothar Miller schrieb: > die PWM-Frequenz ist fix. Nur das Tastverhältnis wird geändert Genau das hakt bei mir grad - wenn die PWM Frequenz fix ist, wie kann ich dann die Sinusfrequenz verändern? Das Tastverhältnis verändert ja quasi nur die Amplitude. Auch hier wieder: Die Frequenz könnte ich dann ja nur erhöhen, wenn ich beim Tastverhältnis mehrere Schritte "überspringe" und meine Amplitude schneller ihren Wet erreicht. Das wäre das einzige, wie ich mir eine schnellere Schwingung vorstellen könnte... Lothar Miller schrieb: > Es reicht, 1/4 des Sinus in die Tabelle zu legen, der Rest des > Sinus wird einfach gespiegelt und invertiert... Ja, das habe ich auch schon im Internet gefunden, das werde ich dann weiter verfolgen - dann könnte ich die Auflösung ja erhöhen bei gleichem Speicherverbrauch. Lothar Miller schrieb: > Ich habe sowas (leider nur in VHDL, aber die Idee ist die selbe) dort > mal dokumentiert: Danke - das werde ich mir direkt mal angucken!
PWM-Neuling schrieb: > Danke - das werde ich mir direkt mal angucken! OK, VHDL ist wohl nicht so mein Ding! Aber das Bild dazu ist ja wirklich genau das, was ich vorhabe.
Du musst deine Tabelle entsprechend der schnellsten Ausgangsfrequenz (sinus-Frequenz) anlegen. Bei niedrigeren Frequenzen hast du dann u.U. mehrere Zyklen lang denselben Compare-Wert. Dein Sinus wir also etwas "stufig".
PWM-Neuling schrieb: > Aber das Bild dazu ist ja wirklich genau das, was ich vorhabe. Ja, und das ist, was ich beschrieben habe: du hast eine feste PWM-Frequenz. Damit kannst du jetzt ja schon LEDs heller und dunkler machen. Und jetzt änderst du nur noch den PWM-Vergleichswert (und damit den Umschaltzeitpunkt) abhängig von deinem Sinuswert, der von einer ganz anderen Zeitbasis (wesentlich langsamer) bestimmt wird.
PWM-Neuling schrieb: > Genau das hakt bei mir grad - wenn die PWM Frequenz fix ist, wie kann > ich dann die Sinusfrequenz verändern? Das Tastverhältnis verändert ja > quasi nur die Amplitude. Auch hier wieder: Die Frequenz könnte ich dann > ja nur erhöhen, wenn ich beim Tastverhältnis mehrere Schritte > "überspringe" und meine Amplitude schneller ihren Wet erreicht. Das wäre > das einzige, wie ich mir eine schnellere Schwingung vorstellen könnte... Es hakt bei dir aufgrund folgenden kleinen Denkfehlers: Die PWM-Frequenz ist nicht gleich der Sinusfrequenz. Wie du eigentlich schon erkannt hast, hängt die Frequenz des entstehenden Sinus davon ab, wie schnell du den Compare-Wert für deine PWM wechselst, da dieser ja die Amplitude bestimmt (ein Sinus höherer Frequenz ändert logischerweise seine Amplitude schneller). Die PWM-Frequenz hat damit erstmal nichts zu tun.
Ansgar K. schrieb: > Es hakt bei dir aufgrund folgenden kleinen Denkfehlers: Die PWM-Frequenz > ist nicht gleich der Sinusfrequenz. Ja, OK. Ich gin erstmal von meiner Variante aus dem Anfangspost aus...würde ich das so machen, wenn es denn überhaupt geht, dann würde die PWM-Frequenz ja schon meine Sinusfrequenz bestimmen. Aber ich werde von der Variante jetzt erstmal Abstand nehmen. Dieser Phasenakkumulator wird ja auch bei den DDS-Generatoren verwendet. Und von euch hier auch beschrieben - also werde ich den Ansatz jetzt weiter verfolgen. Dann ist klar, die PWM ist nebensächlich.
Wenn die gewünschte PWM-Frequenz nicht zu hoch ist (<10kHz) geht noch eine andere, sehr einfache Methode: Du brauchst zwei Timer (Timer1 und Timer2), die bei Überlauf einen Interrupt auslösen. Als Ausgang brauchst Du ein "PWM-Bit". Timer1 stellst Du auf die PWM-Frequenz ein. Die zugehörige Überlauf-Interruptroutine lässt Du das PWM-Bit auf "1" setzen. Timer2 hat eine einstellbare Frequenz. Die zugehörige Überlauf-Interruptroutine lässt Du das PWM-Bit auf "0" setzen. Das PWM-Bit verändert sich jetzt sinusartig mit der Frequenzdifferenz zwischen Timer1 und Timer2. Indem Du die Frequenz von Timer2 veränderst, kannst Du die "Sinusfrequenz" des PWM-Signals verändern, ohne dass sich die PWM-Frequenz ändert. Vorteil ist, dass Du nicht bei jeder PWM-Periode einen neuen Vergleichswert einstellen musst. Ciao, mare_crisium
Harald M. schrieb: > Das PWM-Bit verändert sich jetzt sinusartig mit der Frequenzdifferenz > zwischen Timer1 und Timer2. Das ist allerdings alles mit unnötig viel Software verbunden... Warum der Aufwand, wenn eine CC-Unit mit passendem Ausgang eh schon vorhanden ist? > Vorteil ist, dass Du nicht bei jeder PWM-Periode einen neuen > Vergleichswert einstellen musst. Das ist ja sowieso nur nötig, wenn sich der Wert ändert... > Das PWM-Bit verändert sich jetzt sinusartig mit der Frequenzdifferenz > zwischen Timer1 und Timer2. Es entsteht dabei m.E. eine Schwebung, die eine wesentlich niedrigere PWM-Frequenz als die eigentliche PWM hat. Mal angenommen der eine Zähler läuft mit 1000 Hz, der andere mit 1001 Hz.
Ich hab das auch mal über 2 Timer gemacht, 3 Phasig. Allerding hatte ich 99 Werte pro Schwingung glaub ich. Meine maximalfrequenz war allerdings irgendwie um 140Hz und dabei habe ich dan schon jede 3te Stützstelle ausgelassen, also 99/3. MAchte aber in Summe (33*140Hz = 4,62kHz Timerüberlauf interrupt) mehr wa nicht drinn mit einem Mega128 16kHz Gruß Knut
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.