www.mikrocontroller.net

Forum: Digitale Signalverarbeitung / DSP F2808 für PWM zur Motoransteuerung


Autor: Thomas Schermer (cheesie)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hallo liebe Mikrocontroller,

ich sitze jetzt schon ne woche vor nem problem, nämlich möchte ich ein 
pwm-signal erzeugen welches zur Motoransteuerung geeignet ist, sprich 
ein PWM das seinen Dutycycle kontinuierlich verändert. (In PSpice durch 
Vergleich von Dreieckspannung und Sinus).

Ich habe zum Programmieren den TMS320F2808, ein PWM Signal auszugeben 
stellt kein Problem mehr dar, jedoch ich weiß nicht wie ich es anstellen 
soll das man praktisch wie in pspice das Dreiecksignal (ich nehm mal an 
das ist beim 2808 dann das UP-DOWN-Count Signal) mit einer Sinusspannung 
zu vergleichen, und jenachdem den Dutycycle verändert, sodass ich am 
ausgang dann wie im beigefügten bild eine rechteckspannung hab (negative 
halbwelle nat. keine negative spannung sondern einfach weniger 
highphasen) die wenn ich über einen entsprechenden Tiefpass gebe wieder 
ein "schönes" Sinus Signal rausbekomme.

Hoffe damit hat schon jemand Erfahrung gesammelt.

Grüße
Tom

Autor: Flo (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Für diese Art von Signal braucht der Sinus einen Gleichanteil in Höhe 
der Amplitude, dann schwingt er von 2*Amplitude bis 0 hin und her.

Autor: Michael K. (kichi)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wie du richtig geschrieben hast stellt der Timer-Wert (z.B. 
Up-/Down-Count-Mode) einen der beiden Vergleichswerte dar und 
gleichzeitig die Schaltfrequenz. Den anderen Vergleichswert musst du 
selbst ins Compare-Register schreiben.

Wenn du einen festen Wert im Compare-Register stehen hast wird sich ein 
fester Pegel einstellen, mehr nicht. Daher musst du den Compare-Wert 
verändern und zwar je nach gewünschter Ausgangsfrequenz und 
Auflösung/Genauigkeit/Signalverlauf (und Schaltfrequenz). Ob du diese 
veränderlichen Werte aus einer Tabelle nimmst oder jedesmal neu 
berechnest bleibt dir überlassen. Du wirst dafür eine zweite Zeitbasis 
brauchen, die dir vorgibt wann du den Compare-Wert verändern musst.

Vielleicht hilft dir auch der Artikel DDS und die Links dort weiter.

Autor: Thomas Schermer (cheesie)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ob du diese
> veränderlichen Werte aus einer Tabelle nimmst oder jedesmal neu
> berechnest bleibt dir überlassen. Du wirst dafür eine zweite Zeitbasis
> brauchen, die dir vorgibt wann du den Compare-Wert verändern musst.


Schonmal Danke für die Antwort Michael, aber ich kann mir nicht richtig 
vorstellen wie ich den Wert für das Compare-Register berechnen soll und 
dann zur richtigen Zeit in das Register schreiben soll (Also das neue 
schreiben dann evtl. wenn der Counter = 0 ist, dann könnte man das ja 
gleich ins active Register anstatt in das shadow register schreiben, 
sodass es gleich benutzt werden kann). Vom Verständis her hab ichs glaub 
ich schon einigermaßen begriffen, aber es scheitert halt gnadenlos an 
der Umsetzung.=(

Wäre für jede weitere Hilfe sehr dankbar!

Grüße
Tom

Autor: Peter Diener (pdiener) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Der Wert, der in das Compareregister geschrieben wird, ist direkt 
proportional zu der Spannung die du dem Motor an der jeweiligen Phase 
geben möchtest.

Es gibt es verschiedene Methoden, wie man die Spannung der drei 
Motorphasen vorgibt.

Ich zähle mal ein paar auf:
1.) u/f=const
2.) (u-Unull)/f=const
3.) Stromregelung mit Feldorientierung und Encoder
4.) Stromregelung mit Feldorientierung nach Rotorpositionsschätzung

Jetzt kann man noch weiter optimieren, schließlich kann man den 
Motorsternpunkt verschieben, ohne, dass das eine negative Auswirkung 
hat.

Stichwort Raumzeigermodulation.

>dann könnte man das ja
>gleich ins active Register anstatt in das shadow register schreiben,
>sodass es gleich benutzt werden kann

Das ist keine so gute Idee.
Prinzipiell ist es aber richtig, dass das Register bei jedem 
Timerduchlauf einmal geschrieben wird.

Grüße,

Peter

Autor: Thomas Schermer (cheesie)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Ich zähle mal ein paar auf:
> 1.) u/f=const
> 2.) (u-Unull)/f=const
> 3.) Stromregelung mit Feldorientierung und Encoder
> 4.) Stromregelung mit Feldorientierung nach Rotorpositionsschätzung

Hallo Peter,

ja eine der Methoden hab ich auch vor in Zunkunft umzusetzen nämlich die 
Stromregelung mit Feldorientierung und Encoder. Aber jetzt am Anfang 
möchte ich erst versuchen das "Sinus"PWM Signal zu erzeugen, bevor ich 
weitere schritte mache.


> Der Wert, der in das Compareregister geschrieben wird, ist direkt
> proportional zu der Spannung die du dem Motor an der jeweiligen Phase
> geben möchtest.

Aber hier liegt noch mein Problem, ich weiß nicht wie ich das umsetzen 
soll damit ich, wie in meinem angehängten Bild ganz oben, das Compare 
Register zu jeder neuen Periode des UP-DOWN-Counters so beschreibe damit 
das ausgegebene PWM Signal bei einer Tiefpassfilterung auch wieder eine 
Sinusform bekommt.
Also Praktisch wie berechne ich zu jeder neuen Periode meinen dutycycle. 
Wahrscheinlich ist das problem so simple zu lösen, aber weiß leider 
nicht wie.=(

grüße

tom

Autor: Peter Diener (pdiener) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Als erstes musst du einen Interrupt einrichten, der immer dann auslöst, 
wenn das Zählregister einmal durchgelaufen ist. Üblicherweise lässt man 
den triggern, wenn der Zähler 0 erreicht.

Damit ist die Zeitbasis für die Modulationsfrequenz festgesetzt und man 
erhält eine Funktion (den Interrupt), die immer dann aufgerufen wird, 
wenn ein neuer Puls ausgegeben wird. Dort hat man die Möglichkeit das 
shadowregister zu schreiben.

Dieser Interrupt kommt regelmäßig immer nach der gleichen Zeit. Dadurch 
hat man zusätzlich die Information, wie viel Zeit vergangen ist, wenn 
man mitzählt, wie oft der Interrupt aufgetreten ist.

Wenn man diese Zeit jetzt kennt und eventuell sogar in Mikrosekunden 
oder was auch immer umrechnet, kann man sie direkt für die Erzeugung des 
Sinus verwenden:

U = Unull * sin (omega * t + phi);

Omega ist hier die gewünschte Ausgangsfrequenz, Unull die gewünschte 
Amplitude.
Man muss nur ein bisschen mit den Einheiten aufpassen:
Spannungen sind hier in counts des Timers anzugeben und die 
Kreisfrequenz so, dass das mit der Einheit der Zeit t klappt.

Diese Berechnung macht man für alle 3 Phasen mit der jeweils richtigen 
Phasenverschiebung phi (0°, 120°, 240°).

Achtung: t sollte niemals überlaufen oder man muss einen Überlauf 
handhaben können.

Das war die Methode mit dem direkt berechneten Sinus.
Damit das Programm schneller läuft (wenn die Rechenzeit für den Sinus 
nicht reicht), kann man Sinustabellen verwenden, anstatt in Echtzeit zu 
rechnen.

Komplizierter wird es dann, wenn sich die Frequenz über die Zeit ändert.
Dann sollte man eine komplexe Zeigerdarstellung verwenden und in jedem 
Zeitschritt eine Drehoperation mit der gewünschten Winkelgeschwindigkeit 
ausführen. Der Realteil des Zeigers ergibt die gewünschte Spannung. Das 
multipliziert man dann noch mit der gewünschten Amplitude und schreibt 
es in das shadowregister.

Hier genauso getrennt für alle 3 Phasen. Die Phasenverschiebung von 120° 
kann man beispielsweise durch eine Drehoperation auf den Raumzeiger 
erreichen.

Das Ergebnis ist eine dreiphasen-Pulsweitenmodulation nach dem 
Unterschwingungsverfahren, wobei der Motorsternpunkt im schnellen 
zeitlichen Mittel spannungsfrei ist.

Um einen höheren Modulationsindex (mehr Spannung am Motor) zu erreichen, 
braucht man dann weitere Optimierungen. Aber ich denke, es ist schon 
noch ein bisschen Programmierarbeit bis dahin.

Es gibt da dann auch noch einige mathematische Werkzeuge, die einem die 
Zeigerrechnung vereinfachen. Wichtig sind die folgenden beiden, die 
sollte man sich genau anschauen:

-Clarke transformation
-Park transformation

Dazu gibts ein Paper von TI:
http://www.ti.com/sc/docs/psheets/abstract/apps/bpra073.htm

Und einige von Atmel:
http://www.atmel.com/dyn/resources/prod_documents/...
http://www.atmel.com/dyn/resources/prod_documents/...
http://www.atmel.com/dyn/resources/prod_documents/...

Ich hoffe, das genügt vorerst um die ersten Versuche zum Laufen zu 
bekommen.

Ein Oszilloskop mit mindestens 4 Kanälen ist dabei sehr hilfreich. Mit 3 
Kanälen kann man die PWM-Kanäle anschauen und mit dem 4 irgendeinen 
Hilfspin am Controller um z.B. bestimmte Events (Timerüberlauf...) 
anzuzeigen.

Autor: Ralf (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi Thomas,

auf der TI Seite findest Du auch eine Digital Motor Control Library die 
du dir frei runterladen kannst. Unter anderem enthält die Lib den 
Quellcode von allen möglichen Funktionen (auch von der 
Raumzeigermodulation (SVM = space Vector Modulation)) und auch eine 
relativ ausführlich PDF Doku zu den einzelnen Funktionsblöcken.
Vielleicht hilft dir die Lib weiter.

Gruß,
Ralf

Autor: Thomas Schermer (cheesie)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo zusammen,

vielen Dank für die Beitrage, helfen weiter!! Jetzt steh ich vor dem 
Problem wie ich den Sinus in Code Composer ausrechnen soll.
Die eingebundene "IQMathLib.h" scheint irgendwie das nicht zu haben, 
weil er weiterhin fehler bringt den funktionsaufruf nicht zu kennen?!
weiß für dieses Problem noch jemand rat??
Vielen Dank an die freundliche Unterstützung!!

Viele Grüße

Tom

Autor: Ralf (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi Tom,

mit der IQMath Lib kenne ich mich nicht im Detail aus, d.h. ich habe sie 
noch nie verwendet weil ich keine TI Prozessoren einsetze.
Aber ich mache das normalerweise mit einer look-up-table. D.h. ich habe 
im Code eine Tabelle mit z.B. 1024 Einträgen die vorberechnete 
Sinuswerte enthält. Die Sinuswerte sind im Festkommaformat berechnet, 
d.h. sin(90°)=1=32767=0x7FFF und sin(270°)=-1=-32768=0x8000. Weiterhin 
verwende ich eine 16Bit Winkelvariable die Winkel im Bereich von 0 bis 
65535 entsprechend 0 bis 360° speichert. Möchte ich nun den Sinus 
berechnen, so nehme ich einfach die oberen zehn Bit meiner 
Winkelvariable und nehme diese als Index in der Sinustabelle. Dieses 
Element ist dann der Sinuswert. Den Cosinus berechne ich gleich, nur mit 
einem Offset von 90°, d.h. Winkelvariable + 16384.

Viele Grüße,
Ralf

Autor: Peter Diener (pdiener) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
IQmath muss man erst installieren.

Hier die Beschreibung:
http://focus.ti.com/lit/sw/sprc990/sprc990.pdf

Und hier gibt es den Download:
http://focus.ti.com/docs/toolsw/folders/print/sprc087.html

Grüße,

Peter

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.