Forum: Mikrocontroller und Digitale Elektronik Sine-Lookup Tabelle. Wie macht man es richtig?


von Al3ko -. (al3ko)


Angehängte Dateien:

Lesenswert?

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

von ich (Gast)


Lesenswert?

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

von ghl (Gast)


Lesenswert?

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.

von Al3ko -. (al3ko)


Lesenswert?

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?

von foo (Gast)


Lesenswert?

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.

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

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