Hi Leute, mich interessiert, wie man eine Sinus-Lookup Tabelle richtig erstellt, um z.B. 50Hz Wechselrichter mit Schaltfrequenzen von ca. 20-48kHz zu betreiben. Bis dato habe ich ein Header File verwendet, das für jede Schaltfrequenz eine eigene Lookup Tabelle bereit stellt (siehe sineLookupFile.h im Anhang). Im Hauptcode gehe ich jedes mal nach einer Schaltperiode in die ISR und aktualisiere das PWM Register mit dem aktuellen Wert der Sinus Tabelle. Da jede Sinus Tabelle unterschiedlich groß ist, muss ich den Counter (int i; int k;) jeweils umstellen bzw. anpassen. Auch stelle ich die Geschwindigkeit des DSPs jeweils um im PLL_setup() [siehe Example_2802xEPwmDeadBand.c im Anhang], damit das Verhältnis zwischen Grundfrequenz, Schaltfrequenz etc. einigermaßen ganzzahlig wird. Das macht natürlich alles sehr viel aufwendiger und weniger flexibel. Daher meine Frage an euch: Kann man irgendwie eine einzige Sinus Tabelle erstellen und diese für beliebige Schaltfrequenzen verwenden? Falls dem so ist, wie macht man das auf elegante Art und Weise? Gibt es Code Beispiele oder passende App Notes? Bisher bin ich nicht wirklich fündig geworden. Ich danke euch. Gruß, Alexander
Hi, ich würde die Lookup table über Phase nehmen, (also DDS):
1 | #define OUTPUT PWM_etc
|
2 | |
3 | unsigned int phase=0; |
4 | unsigned int ftw=256; |
5 | |
6 | |
7 | funktion_in_gleichen_Zeitabstaenden_ausfuerhen(void){ |
8 | phase+=ftw; |
9 | output=sine_aus_LuT(phase); |
10 | }
|
MfG ich
Ich würde auch eine Tabelle nehmen und dann über 'nen Phasen-Akkumulator gehen. Du brauchst übrigens nur die ersten 90°, den Rest kannst du durch Spiegeln und invertieren hinzaubern -- falls Speicherplatz/Tabellengröße ein Problem sein sollte.
Hi Leute, vielen Dank. Aber so wie ich das sehe, ist es doch genau das was ich momentan mache (auch wenn es weniger elegant zu sein scheint). Es gibt bei mir eine Sinus Tabelle und in festen Schritten wird darauf zugegriffen. Genau so läuft es bei mir auch. Es wird jedes mal, wenn die ISR aktiv ist, die SinusTabelle aktualisiert. Und in die ISR wird jedes Mal gesprungen, wenn eine Schaltperiode neu beginnt. Erhöhe ich die Schaltperiodenfrequenz, reduziert sich die Schaltperiode und es wird früher / öfter in die ISR gesprungen. Was ist, wenn ich jetzt z.B. die Schaltfrequenz verdoppele? Dann wird doppelt so oft in die ISR gesprungen und entsprechend wird die Sinus Tabelle doppelt so oft aktualisiert. Heißt also, dass ich nicht mehr 50Hz Grundwelle habe, sondern 100Hz. Und genau das ist mein ursprüngliches Problem. Vielleicht ist mein Ansatz auch völlig falsch, die Sinus Tabelle jedes mal zu aktualisieren, wenn ich in die ISR springe? Andererseits, bei irgendeinem Event muss die ISR ersetzt werden? Oder läuft es so ab: Man hat eine feste Abtastfrequenz. Diese Abtastastfrequenz löst die ISR aus. Und dann wird der Sinus Aktualisiert. Wenn die Abtastfrequenz konstant ist, also unabhängig von der Schaltfrequenz, könnte man so beliebige Schaltfrequenzen realisieren ohne die Grundwelle von 50Hz zu verändern. Wie machen es denn die Profis?
al3ko -.- schrieb: > Oder läuft es so ab: Weder noch. Man hat eine einzige vorausberechnete ziemlich hochauflösende Sinustabelle, mit z.B. 12 Bit Adresse für einen Quadranten. Dann hat man einen Phasenakkumulator, das ist z.B. ein 32-Bit Register, von dem nur die obersten 14 Bit als Argument für den Tabellenzugriff genutzt werden (2 Bit für die Lage des Quadranten + 12Bit). Auf diesen Phasenakkumulator addiert man einfach mit möglichst hoher aber fester Frequenz, z.B. 20MHz, ein Inkrement, das so genannte Frequenz Tuning Word FTW. Je nachdem, wie groß dieses FTW ist, wächst der Inhalt des Phasenakkumulators, der ja nichts anderes als einen Winkel repräsentiert, mehr oder weniger schnell und läuft ggfs. auch einfach über. Der Inhalt des Phasenakkumulators wird jedesmal an die die Sinustabelle und den DAC übergeben, selbst wenn sich die obersten Bits nicht geändert haben. Wenn im obigen Beispiel das FTW 1 ist, braucht man 2**32 Additionen, um eine vollständige Schwingung auszugeben. Die Frequenz wäre dann also 20MHz *1 / 2**32= 4,6566... mHz. Das ist dann auch die geringste hiermit erzeugbare Frequenz (ausser 0). Wenn das FTW 1 Million ist, dann ist die Ausgangsfrequenz 20MHz * 1Mio /2**32 /4 = 4656,6... Hz. Die Frequenz ist also freundlicherweise proportional zum FTW. Nachteilig ist ein geringes Phsenrauschen, da die Nulldurchgänge meist nicht genau bei 2**N Takten stattfinden. Die höchste Frequenz die man auf diese Weise sinnvoll herstellen kann, liegt bei etwa 40% der Taktfrequenz, im Beispiel also bei 8MHz. Das liegt daran, dass man zur Unterdrückung der bei der Abtastung auftretenden Spiegelfrequenzen, ein steiles analoges Tiefpassfilter nachschaltet, das alles ab der halben Taktfrequenz abtöten muss.
Du kannst dir mal den Quellcode zum 3-Phasen Umrichter zu Gemüte führen, wo der Phasenakkumulator ähnlich läuft. Auch hier gibt es einen Pointer in die Tabelle, der pro PWM Zyklus einmal mittels des Akkus aufaddiert wird. http://www.mikrocontroller.net/articles/3-Phasen_Frequenzumrichter_mit_AVR Mit den 16 kHz PWM und der gewählten Tabellenlänge von 192 Werten kommt man so auf etwa 0,1 Hz bis 162 Hz.
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.