STM32 Phasenverschobene Sinuswellen

#4747215
Lesenswert?

Hi,

Wie realisiere ich am besten 3 Phasenverschobene Sinuswellen mit einem 
STM32F4? Eine Sinuswelle ist mit einer Look-Up Table schnell erzeugt, 
aber wie kann ich es bewerkstelligen, dass die 3 Sinus Wellen zueinander 
120° verschoben sind? Dafür bräuchte ich doch 3 Timer und die müssten 
irgendwie synchronisiert sein?

Grüsse Sebastian
Gast #4747238
Lesenswert?

Eine Verschiebung in der Phase entspricht einem Verschiebung im Index in 
der Tabelle mit den Sinuswerten. Die Verschiebung addiert man halt vor 
dem Auslesen der Tabelle jeweils dazu. Wenn man es per Ausgabe per DMA 
machen will, muss man ggf. 2 Timer nutzen, wenn man nicht einen Timer 
als trigger für 2 DMAs nutzen kann. Bei der Ausgabe im Interrupt kann 
man die Tabelle natürlich auch mehrfach auslesen.

Man muss im µC an sich nur 2 der 3 Sinussignale erzeugen (kommt also mit 
2 DAC Ausgängen aus), der 3. Sinus lässt sich analog als -Wurzel 3 mal 
der summe der beiden anderen erzeugen.
#4747242
Lesenswert?

Angenommen, Du hättest 3600 Werte in Deiner Sinus-Tabelle/Array.

Nun nimmst Du 3 Zeiger und läßt sie jeweils in die Tabelle zeigen:

- Zeiger 1 zeigt auf Array-Platz 0
- Zeiger 2 zeigt auf Array-Platz 1200
- Zeiger 3 zeigt auf Array-Platz 2400

Der Ablauf ist dann wie folgt:

1.)   Hole Dir die 3 Werte auf die die 3 Zeiger zeigen aus Deiner
      Sinus-Tabelle und gib diese 3 Werte via D/A-Wandler aus

2.)   Per Timer erhöhst Du die Zeiger dann jeweils um 1 und hüpfst
      dann wieder zu Schritt 1.)

Selbstverständlich mußt Du ein wenig Hirnschmalz investieren,
damit Deine Zeiger nach Position 3599 wieder bei 0 anfangen -
aber das schaffst Du sicherlich.

Viele Grüße

Igel1
#4747251
Lesenswert?

Lurchi schrieb:
> Man muss im µC an sich nur 2 der 3 Sinussignale erzeugen (kommt also mit
> 2 DAC Ausgängen aus), der 3. Sinus lässt sich analog als -Wurzel 3 mal
> der summe der beiden anderen erzeugen.

Das spart natürlich Speicher, danke.

Ein bisschen was zum Hintergrund: Ich erhoffe mir mit einer Sinus 
Ansteuerung des DRV8313 BLDC Controllers einen ruhigeren lauf bei 
langsamen Geschwindigkeiten. Denkt ihr, mann kann einfach die EN 
Eingänge auf HIGH belassen und dann die IN Eingänge mit den drei 
Phasenverschobenen Sinuswellen füttern, also natürlich nicht D/A 
Wandlung vornehmen, sondern direkt durch die duty cycles?

Datenblatt DRV8313:
http://www.ti.com/lit/ds/symlink/drv8313.pdf

Grüsse Sebastian
(Firma: TU Darmstadt) #4747411
Lesenswert?

Schau Dir den HRTimer im F334 an.

Ausserdem kannst Du 3 Timer im Master/Slave Betrieb nutzen. Timer A 
startet Timer B, Timer B startet Timer C. Alles Timer haben den gleichen 
ARR Wert und in das PWM Compare Register jeded Timers kommt der aktuelle 
PWM Wert aus der Sinustabelle.
#4747559
Lesenswert?

Uwe B. schrieb:
> Ausserdem kannst Du 3 Timer im Master/Slave Betrieb nutzen. Timer A
> startet Timer B, Timer B startet Timer C. Alles Timer haben den gleichen
> ARR Wert und in das PWM Compare Register jeded Timers kommt der aktuelle
> PWM Wert aus der Sinustabelle.

Kann ich das folgendermassen auf einem STM32F4 implementieren:
Man nimmt z.B Timer2 und benützt 3 Subchannels für PWM Signale. Die 
jeweiligen duty cycles für die nächste Periode werden jeweils beim 
Aufruf  von der IRQ für Timer2 festgelegt und dann werden auch gleich 
alle Timer wieder neu synchronisiert. Die Frequenz für den Sinus lege 
ich dann über den Prescaler oder evtl. ARR fest, wobei bei ARR die 
Abhängigkeit der Sinustabelle eine Rolle spielt.
Gast #4747660
Lesenswert?

Sebastian T. schrieb:
> Die
> jeweiligen duty cycles für die nächste Periode werden jeweils beim
> Aufruf  von der IRQ für Timer2 festgelegt und dann werden auch gleich
> alle Timer wieder neu synchronisiert

Wieso so kompliziert? Du gibst im Interrupt für Timer 2 einfach alle 3 
PWM-Werte neu aus, die du entsprechend (um 120 Grad) versetzt aus der 
selben Tabelle liest. Es werden weder weitere Timer gebraucht noch eine 
Synchronisation, die ergibt sich einfach aus dem Versatz in der Tabelle.

Ich fürchte, nach dem bisherigen schwachen Verständnis ist auch nicht 
bekannt, dass man für einen Sinus nur eine Tabelle von 0..90 Grad 
braucht, also 12mal weniger Daten als von dir geplant.

Georg
#4747754
Lesenswert?

Georg schrieb:
> Wieso so kompliziert? Du gibst im Interrupt für Timer 2 einfach alle 3
> PWM-Werte neu aus, die du entsprechend (um 120 Grad) versetzt aus der
> selben Tabelle liest. Es werden weder weitere Timer gebraucht noch eine
> Synchronisation, die ergibt sich einfach aus dem Versatz in der Tabelle.

Und wie soll ich die ausgeben, wenn ich keinen D/A Wandler verwende? Mit 
D/A ist das klar, aber ohne muss ich ja 3 Timer benützen, sonst kann ich 
nicht unterschiedliche duty cycles haben.
(Firma: TU Darmstadt) #4747784
Lesenswert?

Nochmals: Du verkettest Timer A, B und C.
TIMa->ARR = TIMb->ARR = TIMc->ARR= ARR fuer benoetigte PWM Frequenz
TIMa->CNT = 0,
TIMb->CNT = ARR/3
TIMc->CNT = 2*ARR/3
TIMB ist Slave von TIMa, TIMc Slave von TIMb
TIMa und TIMB senden Signal mit Timer Start,
TIMa startest Du mit CEN.

TIMa->CCRx = TIMb->CCR = TIMc->CCR = gewuenschter PWM Wert.
(Firma: matzetronics) #4747800
Lesenswert?

Man kann die drei PWM Signale auch mit einem einzigen Advanced Timer und 
den dazugehörigen CCRn Registern (und der DTI) erzeugen.

Ein Pointer in eine 3 spaltige Tabelle mit U, V und W Werten reicht dazu 
- das Prinzip wird für kleine AVR in AppNote AVR447 beschrieben, die 
allerdings wirklich alle 3 Timer eines Mega88 belegt, weil es bei denen 
das Limit der komplementären Ausgänge gibt, jeder Timer hat nur 2.

Diese Beschränkung gibts es beim Advanced Timer des STM32 nicht und es 
gibt ein DeadTime Unit, das einem ein paar Berechnungen abnimmt.
Gast #4748076
Lesenswert?

Für die Sinuswert reicht wirklich eine Tabelle, ggf. auch nur einer 
kleiner Teil der Periode, aber für eine Periode sollte der Platz i.A. 
reichen. Für das Einstellen der Frequenz kann man ähnlich wie beim DDS 
Generator vorgehen, also den Index nicht immer um 1 weiter zählen, 
sondern ggf. auch Zwischenwerte nutzen. So kann man die Sinus Frequenz 
unabhängig von der PWM Frequenz wählen ohne die Tabelle neu zu 
berechnen.
Gast #4748313
Lesenswert?

Bei einem Arduino Mega hast Du Timer mit 3 Vergleichsregister für das 
PWM.
Ansonsten kannst Du auch 3 Timer parallel laufen lasssen. Die bleiben 
schon synchron.

Meine Sinustabelle ist 156 in der Länge (durch 3 teilbar).
1
signed char si[156] = {0,
2
                       5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 54, 59, 63, 68, 72, 76, 80, 84, 88, 92,
3
                       95, 98, 102, 105, 107, 110, 112, 115, 117, 119, 120, 122, 123, 124, 125, 126, 127, 127, 127, 127,
4
                       127, 126, 125, 124, 123, 122, 120, 119, 117, 115, 112, 110, 107, 105, 102, 98, 95, 92, 88, 84,
5
                       80, 76, 72, 68, 63, 59, 54, 50, 45, 40, 35, 30, 25, 20, 15, 10, 5, 0, -5, -10,
6
                       -15, -20, -25, -30, -35, -40, -45, -50, -54, -59, -64, -68, -72, -76, -80, -84, -88, -92, -95, -98,
7
                       -102, -105, -107, -110, -112, -115, -117, -119, -120, -122, -123, -124, -125, -126, -127, -127, -127, -127, -127, -126,
8
                       -125, -124, -123, -122, -120, -119, -117, -115, -112, -110, -107, -105, -102, -98, -95, -92, -88, -84, -80, -76,
9
                       -72, -68, -64, -59, -54, -50, -45, -40, -35, -30, -25, -20, -15, -10, -5
10
                      };
Berechnung der 3 Stellen fuer den 120 Grad Versatz. "zaehl" wird laufend 
erhöht. Die Division durch 16 macht eine feinere Frequenzeinstellung 
möglich.
1
  arg0 = (zaehl / 16 + 0) % 156;
2
  arg1 = (zaehl / 16 + 52) % 156;
3
  arg2 = (zaehl / 16 + 104) % 156;
Der Tabellenzugriff
1
      OCR5AL =  X + Ampl * si[arg0] / 256 ;
2
      OCR5BL =  Y + Ampl * si[arg1] / 256 ;
3
      OCR5CL =  Z + Ampl * si[arg2] / 256 ;

Dabei wird nach jedem pwm Zyklus ein Interrupt ausgelöst und dieser 
Vergleichswert geladen.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren