Forum: Mikrocontroller und Digitale Elektronik MSP430: Sinus höherer Frequenz per PWM erzeugen


von A. H. (dernetteeddie1978)


Angehängte Dateien:

Lesenswert?

Hallo Leute,

ich möchte mit nem MSP430G2452 einen Sinus um die 1-1,5 kHz erzeugen. 
Grundsätzlich wollte ich es ohne AD Wandler per PWM machen. Das Problem 
ist, dass ich den Sinus nur bis 150 Hz sauber hinbekomme, da der Chip 
selbst bei max. Takt einfach zu langsam ist um so eine Frequenz zu 
bekommen.

Realisiert habe ich die PWM einfach über einen Zähler mit 1000 
Zählschritten und 100 Stützstellen. Dadurch ergeben sich ja aber pro 
Periode bereits 100.000 Takte. So kommt man natürlich nie auf einen Wert 
im kHz Bereich.

Was ich schon versucht hab ist den Zähler nur bis 500 zählen zu lassen. 
Somit komme ich dann auf 300 Hz. Aber da kommt auch schon so ein 
leichtes Jittern in den Sinus.

Die Frage ist nun, geht das überhaupt auf diesem oder einem anderen Weg 
ohne AD Wandlung? Wollte versuchen mit möglichst wenig Bauteilen 
auszukommen.

Eine Idee hatte ich noch - zwei niedrige Frequenzen zu multiplizieren 
und so eine höhere zu erzeugen. Hab noch nen G2553 hier liegen der hat 
zwei Timer.

Dafür bräuchte man ja allerdings auch wieder Analogelektronik hinten 
dran. Hab mal versucht im Netz nen Rechner für die nötigen Frequenzen zu 
finden aber leider erfolglos... Vielleicht kennt jemand einen.

Code hab ich mal angehängt...

Gruß
Eddie

von Ulrich H. (lurchi)


Lesenswert?

Der Trick um höhere Signalfrequenzen zu erreichen ist es die 
Sinustabelle nicht immer in Schritten von 1 zu durchlaufen, sondern die 
Schrittweite für den Phasenwinkel zu benutzen um die Frequenz 
festzulegen.

Das Verfahren läuft unter dem Namen DDS.
Die Sinustabelle darf auch ruhig länger sein, etwa 256 Einträge, so dass 
man die langsame Modulus Operation (%) durch ein schnelleres Bitweises 
UND ersetzen kann.

Ganz ohne analoge Hardware geht das aber nicht. Man braucht schon einen 
Tiefpassfilter um das PWM Signal zu glätten (macht daraus dann so eine 
Art DA Wandler) und auch um das Sinussignal aus den nicht mehr so vielen 
Stützstellen zu rekonstruieren. Die Grenzfrequenz sollte entsprechend 
knapp über der maximalen Signalfrequenz liegen. Wenn man damit dichter 
an das Limit von 1/2 der PWM Frequenz kommt, muss der Filter deutlich 
aufwendiger werden. Das praktischen Limit für die Frequenz liegt daher 
eher bei 1/3 der Samplingfrequenz, bzw. für einen einfachen Filter (2. 
Ordnung) bei etwa 1/10 der PWM Frequenz.

Im Konkreten Beispiel sollte es bis etwa 5 kHz Ausgangssignal bei etwa 
62 kHz PWM Frequenz (= Sampling Rate für den DDS) funktionieren.

von mh (Gast)


Lesenswert?

Spontan fällt mir da ein Bandpassfilter ein, mit dem du einfach 
harmonische deines Rechtecksignals oder PWM rausfilterst.
Diese dann noch hinterher verstärken.

von Gerald G. (gerald_g)


Lesenswert?

1-1,5 kHz geht direkt bei steilem Tiefpassfilter bei 1,5kHz. Dann 
einfach in der gewünschten Frequenz den Ausgang schalten. Die erste 
harmonische beim Rechteck wäre dann beim 1kHz Signal bei 2kHz, was ja 
raus gefiltert wird. Zurück bleibt der Sinus in der Hauptfrequenz.

von A. H. (dernetteeddie1978)


Angehängte Dateien:

Lesenswert?

Hallo,

erstmal danke für die nützlichen Tipps. Nachdem ich nun endlich wieder 
Zeit hatte hab ich nun mal versucht das Ganze umzusetzen. So habe ich 
nun die Sinustabelle auf 256 Werte erweitert und die Modulo Operation 
gegen ein bitweises UND ersetzt. Wenn ich die DDS richtig verstanden 
hab, so ist das im Prinzip genau das was ich tue?

Am Ausgang hängt ein RC Glied mit ca. 2kHz Grenzfrequenz (R=1k21 und 
C=68nF)

Der Chip taktet 16 MHz und die Zählschleife zählt von 0 bis 1000. Aus 
der Sinustabelle wird immer jeder 32. Wert abgefragt, somit müsste ich 
bei 2 kHz Samplingfrequenz liegen.

Grundsätzlich scheints auch zu funktionieren allerdings ist der Sinus 
extrem überlagert so dass er nur mit viel Phantasie noch zu erkennen 
ist.

Wenn ich ein zweites RC Glied hinten dran setze wirds schon etwas 
besser.

Liegts nun nur am Filter oder mache ich noch was falsch?

Das ganze jittert auch mal mehr mal weniger.

Bilder und Code hab ich angehängt...

Gruß
Eddie

von c-hater (Gast)


Lesenswert?

A. H. schrieb:

> ich möchte mit nem MSP430G2452 einen Sinus um die 1-1,5 kHz erzeugen.
> Grundsätzlich wollte ich es ohne AD Wandler per PWM machen. Das Problem
> ist, dass ich den Sinus nur bis 150 Hz sauber hinbekomme, da der Chip
> selbst bei max. Takt einfach zu langsam ist um so eine Frequenz zu
> bekommen.

Huch?

Ich kenne die MSPs nicht und habe deshalb eben kurz mal in das DB 
geschaut. Ich habe festgestellt: Das Teil kann mit bis zu 16MHz 
betrieben werden. Einen PWM-fähigen, mit Systemtakt betriebenen Timer 
hat es auch.

Es sollte also keinerlei Problem darstellen, selbst 10kHz per PWM zu 
erzeugen. Bei einer Reduktion des Timer-Zählumfangs auf 8 Bit käme man 
auf ca. 60kHz PWM-Zyklus. Der bräuchte dann ca. alle 16µs ein neues 
Sample. Bei einem AVR wären das ca. 60 Instruktionen, damit kann man 
ganz locker sogar eine DDS realisieren.

> Realisiert habe ich die PWM einfach über einen Zähler mit 1000
> Zählschritten und 100 Stützstellen. Dadurch ergeben sich ja aber pro
> Periode bereits 100.000 Takte. So kommt man natürlich nie auf einen Wert
> im kHz Bereich.

Wenn ich das richtig verstehe, hast du das rein in Software gemacht, 
statt den Timer zu verwenden. Sofern ein Timer verfügbar ist, ist das 
natürlich Unsinn. Aber selbst wenn das nicht der Fall ist, weil der 
vorhandene Timer für andere Zwecke benötigt wird: Irgendwas hast du 
dabei wohl falsch gemacht...

Eine PWM kann man in Software mit nur sehr wenigen Instruktionen 
erzeugen. Im Extremfall braucht man nur drei: Pin an, Pin aus, Schleife 
bilden.

Das Timing stellt man dann dadurch her, daß man alles an Instruktionen, 
was sonst noch für die Funktionalität der Steuerung der PWM nötig ist, 
nebenbei als Zeitfresser verwendet. Nur der dann noch verbleibende Rest 
der Zeit wird dann durch reine Warteoperationen verheizt.

Der Trick ist, das es zwischen den zwei Zeitpunkten für Pin an und Pin 
aus oder alternativ zwischen den Zeitpunkten für Pin aus und Pin an 
immer eine Lücke von der Dauer mindestens knapp eines halben 
PWM-Zyklus gibt. Man schreibt nun seinen Code einfach so, daß er immer 
in einer dieser benutzbaren Lücken liegt.

Das läuft dann darauf hinaus, daß es zwei Varianten des Codes gibt, 
zwischen denen je nach aktuellem PWM-Wert hin-und hergesprungen wird. 
Mit dieser Zweier-Lösung ist auf jeden Fall eine PWM mit einer Auflösung 
in der Größenordnung der kürzestmöglichen Zähl-Warteschleife 
realisierbar, bei einem AVR würden also drei Takte pro möglichem 
PWM-Zählschritt anfallen. Bei einer 8Bit-Auflösung für die PWM wären 
also schon damit bei 16MHz Systemtakt 16.000.000/(3*256)=knapp 21kHz. 
Mehr als ausreichend, um einen Sinus von 1,5kHz darüber auszugeben und 
den dann auch noch anständig gefiltert zu bekommen.

Ich glaube nicht, daß das mit einem MSP nennenswert schlechter wäre, 
wenn den jemand in die Mache nimmt, der wirklich programmieren kann...

Übrigens kann man den Ansatz durchaus noch verfeinern, wenn man genug 
Platz im Flash hat. Mit noch ein paar Codevarianten mehr ist (jedenfalls 
beim AVR) sogar Taktgenauigkeit für die Zahlschritte erreichbar, damit 
wäre also PWM mit demselben Timing möglich, was auch ein 
8Bit-Hardware-Timer mit 1:1-Vorteiler macht, also bei 16MHz Systemtakt 
gut 60kHz PWM-Frequenz und damit sinnvolle Sinuserzeugung bis ca. 6kHz, 
wenn man etwas mehr Hirnschmalz in den PWM-Filter steckt, sollten auch 
so um die 12kHz damit noch sehr gut realisierbar sein.

von A. H. (dernetteeddie1978)


Angehängte Dateien:

Lesenswert?

Hmm, also hab nun nochmal weiter rumexperimentiert und den Code nochmal 
geändert. Den Interrupt des Zählers abgeschaltet und feste Werte für den 
Zähler vergeben. Zählgrenze bei 8000 und den Pin-Toggle bei 4000. 
Passiver Tiefpass 2-ter Ordnung hinten dran mit fg=2kHz und siehe da - 
1A Sinus von 2kHz.
Wenn ichs jetzt richtig verstanden hab sind das wohl zwei Ansätze einen 
Sinus per PWM zu erzeugen.
Einmal einfach den Rest des Spektrums weggefiltert oder aber per DDS 
über die Pulsbreitenänderung einen Sinus erzeugt...

Hab ich das nun richtig erfasst?

LG
Eddie

von Noch einer (Gast)


Lesenswert?

Den analogen Tiefpass brauchst du auf jeden Fall.

DDS brauchst du zusätzlich, falls die Frequenz des Sinus unabhängig von 
der PWM-Frequenz sein soll.

Bu willst Z.B:  winkel = (winkel+ 32.1 )&255;
Geht nicht so einfach, da nimmt man den DDS-Algorithmus.

von Ge E. (re_n)


Lesenswert?

Ich bin gerade mit einem ähnlichen Projekt beschäftigt. Nehme doch 
einfach einen dsPIC mit 70MIPS und PWM Modul. Gepart mit einer 
Sinustabelle die 36.000 Stützen hat (1/100 Grad Auflösung) kannst du 
locker sehr saubere 130kHz Sinus und mehr mit einem LC Filter 2. Ordnung 
rausholen. Wenn du mehr Details brauchst oder wenn ich dir eine 
Sinustabelle nach Wahl generieren soll (habe ein Script dafür 
geschrieben) PN me


MRG René

von A. H. (dernetteeddie1978)


Lesenswert?

Hi,

danke aber ich wollte möglichst wenig Hardwareaufwand treiben. Für 
meinen einfachen Sinus, der muss auch nicht so sonderlich präzise sein, 
sollte ein µC mit Tiefpass hinten dran doch ausreichen. Immerhin hab ich 
ja nun endlich meinen Sinus mit 2kHz hinbekommen. Als nächster Schritt 
soll die Frequenz noch periodisch zwischen ca. 600 Hz und 1,5 Khz rauf 
und runter modulieren. Da muss ich nochmal schauen. Die DDS möchte ich 
gerne noch richtig verstehen. Da hab ich grad ein Tutorial von Analog 
Devices gefunden. Da werd ich mich demnächst mal durchackern.

Gruß Eddie

von Ge E. (re_n)


Lesenswert?

A. H. schrieb:
> Hi,
>
> danke aber ich wollte möglichst wenig Hardwareaufwand treiben. Für
> meinen einfachen Sinus, der muss auch nicht so sonderlich präzise sein,
> sollte ein µC mit Tiefpass hinten dran doch ausreichen. Immerhin hab ich
> ja nun endlich meinen Sinus mit 2kHz hinbekommen. Als nächster Schritt
> soll die Frequenz noch periodisch zwischen ca. 600 Hz und 1,5 Khz rauf
> und runter modulieren. Da muss ich nochmal schauen. Die DDS möchte ich
> gerne noch richtig verstehen. Da hab ich grad ein Tutorial von Analog
> Devices gefunden. Da werd ich mich demnächst mal durchackern.
>
> Gruß Eddie

Von "Hardware Aufwand" kann man da nicht sprechen. Du brauchst nur nen 
Leistungsstarken PIC und und nen LC Filter fertigist die Hütte. Um die 
FQ zu bestimmen rechnet man sie einfach in °/Step um. Die Step-Rate muss 
dabei immer gleich sein (zB per INT) dort Addierst du die Schritte und 
holst den dazu Passenden Wert aus der LTB fertig ist der Lack. Achja und 
Überlauf bei 360° nicht vergessen

von A. H. (dernetteeddie1978)


Lesenswert?

Noch einer schrieb:
> Den analogen Tiefpass brauchst du auf jeden Fall.

Jepp, den hatte ich ja immer drin.

> DDS brauchst du zusätzlich, falls die Frequenz des Sinus unabhängig von
> der PWM-Frequenz sein soll.

Genau das ist der Punkt. Der Sinus soll im nächsten Schritt rauf und 
runter "heulen" (Soll ne Tonerzeugung für ne Alarmanlage werden)

> Bu willst Z.B:  winkel = (winkel+ 32.1 )&255;
> Geht nicht so einfach, da nimmt man den DDS-Algorithmus.

Daran muss ich noch knacken...

von A. H. (dernetteeddie1978)


Lesenswert?

Ulrich H. schrieb:
> Der Trick um höhere Signalfrequenzen zu erreichen ist es die
> Sinustabelle nicht immer in Schritten von 1 zu durchlaufen, sondern die
> Schrittweite für den Phasenwinkel zu benutzen um die Frequenz
> festzulegen.

Da kann ich ja einfach +x im Interrupt statt +1 nehmen

> Das Verfahren läuft unter dem Namen DDS.
> Die Sinustabelle darf auch ruhig länger sein, etwa 256 Einträge, so dass
> man die langsame Modulus Operation (%) durch ein schnelleres Bitweises
> UND ersetzen kann.

Das muss ich noch sauber umsetzen.


> Im Konkreten Beispiel sollte es bis etwa 5 kHz Ausgangssignal bei etwa
> 62 kHz PWM Frequenz (= Sampling Rate für den DDS) funktionieren.

Nämlich wenn der Zähler nicht bis 1000 sondern nur bis 256 zählt. Okay, 
soweit hab ichs schon mal...

von Klaus (Gast)


Lesenswert?

A. H. schrieb:
> (Soll ne Tonerzeugung für ne Alarmanlage werden)

Und für so einen Krachmacher braucht man einen Sinus?

MfG Klaus

von A. H. (dernetteeddie1978)


Lesenswert?

Klaus schrieb:
> A. H. schrieb:
>> (Soll ne Tonerzeugung für ne Alarmanlage werden)
>
> Und für so einen Krachmacher braucht man einen Sinus?
>
> MfG Klaus

Lässt sich was anderes einfacher erzeugen?

von Max G. (l0wside) Benutzerseite


Lesenswert?

A. H. schrieb:

> Lässt sich was anderes einfacher erzeugen?

Der heult auch an einem Rechteck. Die Induktivität und Trägheit des 
Lautsprechers wirken per se schon als Tiefpass. Schönheit des Klangs ist 
bei einer Alarmanlage eher sekundär bis kontraproduktiv.

Ansonsten hat auch der MSP430G2xxx, wie schon richtig bemerkt, ein 
Timer-Register, das du auch nutzen solltest (genauer die 
Compare-Funktionalität des Capture/Compare-Moduls). TI hat da in der 
Regel recht brauchbaren Beispielcode.

Bei der Sinus-Erzeugung per PWM kannst du entweder zeitlich gut auflösen 
(kleiner Überlaufwert für den Timer) oder die Werte genau einstellen 
(großer Überlaufwert). Hier musst du einen passenden Tradeoff finden.

Max

von A. H. (dernetteeddie1978)


Lesenswert?

> Der heult auch an einem Rechteck.

dann geb ich ja aber Gleichanteil auf meine Lautsprecherspule.
>
> Ansonsten hat auch der MSP430G2xxx, wie schon richtig bemerkt, ein
> Timer-Register, das du auch nutzen solltest (genauer die
> Compare-Funktionalität des Capture/Compare-Moduls).

Okay, den Timer nutze ich ja. Ich dachte das sei gemeint gewesen. Dann 
muss ich nochmal schauen...

von Yalu X. (yalu) (Moderator)


Lesenswert?

A. H. schrieb:
> Grundsätzlich scheints auch zu funktionieren

Ich glaube eher nicht, da liegt noch einiges im Argen ;-)

Das Signal in RC_1ter_Ordnung.jpg ist zwar – wie es sich gehört –
abschnittsweise aus e-Funktionen zusammengesetzt, macht aber an den
Übergängen Sprünge. Ein tiefpassgefiltertes Signal ist aber immer
stetig, auch wenn das Eingangssignal dies nicht ist. Gründe für das
seltsame Verhalten des Tiefpassfilters können sein:

- fehlerhafter Aufbau

- maroder Kondensator (ein ESR von etwa 100Ω würde das Verhalten
  erklären)

- schlechter Anschlusskontakt des Kondensators

Unabhängig davon scheint aber auch schon das ungefilterte PWM-Signal
an ein paar Stellen fehlerhaft zu sein. Kannst du davon auch mal eine
Osziaufnahme posten?

A. H. schrieb:
> dann geb ich ja aber Gleichanteil auf meine Lautsprecherspule.

Auch dein Sinussignal hat einen Gleichanteil. Deswegen sollte das Signal
am Ausgang mit einem Serienkondensator ausgekoppelt werden. Wenn das
Signal noch einen handelsüblichen Verstärker durchläuft, ist dieser
Kondensator wahrscheinlich schon am Eingang desselben vorhanden.

: Bearbeitet durch Moderator
von Klaus (Gast)


Angehängte Dateien:

Lesenswert?

Das ist die Schaltung aus dem original IBM XT. Über den 7438 kann der 
Timerausgang von einem Portbit geschaltet werden. Das geht bei einem µC 
intern einfacher. Und am Pinheader ist direkt der Lautsprecher. Damit 
wurde "Musik" gemacht

MfG Klaus

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.