Hallo Leute,
ich habe eine SPWM auf einem Atmega8 realisiert. Diese Funktioniert auch
soweit ganz gut (siehe Bild SPWM.jpg). Frequenz der Grundwelle soll 50Hz
betragen. Schaltfrequenz beträgt (der Übersichtlichkeit halber) 2kHz.
Der Atmega8 läuft mit dem internen RC Oszillator bei 2MHz.
Ich habe in diesem Thread
Beitrag "Sinustabelle, header und Werte verwenden"
bereits anfängliche Fragen bezüglich Sinustabelle etc. gestellt.
Nun ist der Code fertig und ich möchte euch gerne um euer Feedback
bitten, was am Code optimiert werden könnte. Das hat zweierlei
Hintergründe:
(1) Ich möchte meine Programmierkenntnisse festigen, verfeinern und
ausbauen
(2) Verbraucht der Code knapp 50% meines Speichers - was sicherlich weit
weg vom Optimum ist :D
Ich bin mir ziemlich sicher, dass die Sinustabelle einen nicht
unerheblichen Faktor dazu beiträgt, da ich 256 uint16 Werte habe. Meine
Frage an die erfahrenen Leute wäre jetzt, aus wie vielen Werten der
Sinus bestehen sollte bzw. ob es einen Pi mal Daumen Richtwert gibt, bis
wohin der Sinus noch als sauber anzusehen ist.
Ich danke euch für eure Meinung.
Viele Grüße,
Michael
Michael schrieb:> ob es einen Pi mal Daumen Richtwert gibt, bis wohin der Sinus noch> als sauber anzusehen ist
Das kommt auf den angelegten Maßstab drauf an. Manche Geräte sehen auch
ein Trapez als hinreichend gute Näherung für einen Sinus ;-)
Moin Michael,
du kannst dir 3/4 deiner Sinustabelle sparen. Genaugenommen die letzten
3/4.Du kannst aus dem ersten Viertel nen kompletten Sinus generieren,
indem du die Tabelle auch rückwärts ausliest, und in der 2ten Hälfte
musst du von den Werten jeweils errechnen, wie weit der Wert vom
Mittelwert weg ist, und dann diese Abweichung nach unten vom
Mittelwert´abziehen.
Also probiert hab ich das auch noch nicht, ich hatte auch mal n Sinus
per Tabelle erzeugt, und den kompletten Sinus verwendet, da kam auch
dieser Tip.
Wobei mir auch nicht ganz klar war, wie genau das zu handeln wäre.
Mathematisch bin ich mir inzwischen klar darüber, aber ich hatte es noch
nicht in Software umgesetzt, ich hatte die Befürchtung,das der Sinus bei
hohen Frequenzen ganz schön verformt wird, wenn man zwischendrin
Berechnungen ausführen muss, um den nächsten Wert zu erhalten.
Aber da hilft Googel sicher weiter =)
MfG Chaos
@ Michael (Gast)
>ich habe eine SPWM auf einem Atmega8 realisiert.
Was soll SPWM schon wieder sein? Sinus PWM?
> Diese Funktioniert auch>soweit ganz gut (siehe Bild SPWM.jpg). Frequenz der Grundwelle soll 50Hz>betragen. Schaltfrequenz beträgt (der Übersichtlichkeit halber) 2kHz.>Der Atmega8 läuft mit dem internen RC Oszillator bei 2MHz.
Warum so langsam?
>Nun ist der Code fertig und ich möchte euch gerne um euer Feedback>bitten, was am Code optimiert werden könnte.http://www.mikrocontroller.net/articles/AVR-GCC-Codeoptimierung#Prinzipien_der_Optimierung>(1) Ich möchte meine Programmierkenntnisse festigen, verfeinern und>ausbauen
Gut.
Deine Sinustabelle gehört NICHT in eine Headerdatei sondern eine
C-Datei. Auf dem AVR packt man die in den PROGMEN, sonst verschwendet
man nur sinnlos RAM.
http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#Programmspeicher_.28Flash.29
Deine Funktion void CarrierCalculation(void) hat einen irreführenden
Namen, das ist eine Initialisierung, sonst nix.
Strukturierte Programmierung auf Mikrocontrollern
sei() packt man besser ins main, nicht in spezielle Initfunktionen.
Für die Generierung der PWM und des Hochzählen des Tabellenindex kann
und sollte man besser einen Timer nutzen, spart Resourcen und ist voll
synchron.
> i=i+1;> if(i==255)> {> i=0;> }
Kann man sich sparen, eine 8 Bit Variable läuft bei 255 allein über,
i++; reicht.
i muss nicht global und auch nicht volatil sein, eine statische, lokale
Variable in der ISR reicht.
>Ich bin mir ziemlich sicher, dass die Sinustabelle einen nicht>unerheblichen Faktor dazu beiträgt, da ich 256 uint16 Werte habe.
Das sind 512 Byte Flash. Die interessieren heute keinen mehr.
>Frage an die erfahrenen Leute wäre jetzt, aus wie vielen Werten der>Sinus bestehen sollte bzw. ob es einen Pi mal Daumen Richtwert gibt,
256 Punkt ist schon OK.
> bis>wohin der Sinus noch als sauber anzusehen ist.
Das hängt vor allem von deinem Filter nach der PWM ab.
http://www.mikrocontroller.net/articles/Pulsweitenmodulation#DA-Wandlung_mit_PWM
Vielen Dank schon mal an alle für eure Antworten.
Falk Brunner schrieb:> Was soll SPWM schon wieder sein? Sinus PWM?
Genau. Sorry, habe es unter diesem Namen gelernt.
> Warum so langsam?
Meinst du damit die 2MHz Taktfrequenz vom Atmega? Gute Frage, war mehr
oder minder willkürlich festgelegt, um irgendwo zu starten.
> Deine Sinustabelle gehört NICHT in eine Headerdatei sondern eine> C-Datei. Auf dem AVR packt man die in den PROGMEN, sonst verschwendet> man nur sinnlos RAM.
Okay, ist gemerkt. Werde ich ändern.
> Deine Funktion void CarrierCalculation(void) hat einen irreführenden> Namen, das ist eine Initialisierung, sonst nix.
Hast recht. Wirklich berechnen tue ich da nichts. Wobei, mit der
Initialisierung wird der Timer berechnet.
> sei() packt man besser ins main, nicht in spezielle Initfunktionen.
Ist geändert.
> Für die Generierung der PWM und des Hochzählen des Tabellenindex kann> und sollte man besser einen Timer nutzen, spart Resourcen und ist voll> synchron.
Ich bin mir nicht sicher, ob ich dich genau verstehe. Der Timer läuft
doch jeden Takt linear nach oben (erhöht sich jeden Takt um 1). Wenn ich
jetzt den aktuellen Wert des Timers verwende zum Auslesen der
Sinustabelle, muss ich doch den richtigen Prescaler finden, der z.B. zu
genau 78.5us das TCNTn Register um 1 nach oben setzt.
Wolltest du das damit ausdrücken oder meinst du etwas anderes?
> Kann man sich sparen, eine 8 Bit Variable läuft bei 255 allein über,> i++; reicht.
Okay, danke.
> i muss nicht global und auch nicht volatil sein, eine statische, lokale> Variable in der ISR reicht.
Danke.
> Das sind 512 Byte Flash. Die interessieren heute keinen mehr.
Okay, vielleicht ist der Atmega8 ein wenig oldschool dafür :D
Vielen Dank!
@ Michael (Gast)
>Meinst du damit die 2MHz Taktfrequenz vom Atmega? Gute Frage, war mehr>oder minder willkürlich festgelegt, um irgendwo zu starten.
PWM mach man meisten möglichst hochfrequent, um dann einfacher filtern
zu können.
>> Für die Generierung der PWM und des Hochzählen des Tabellenindex kann>> und sollte man besser einen Timer nutzen, spart Resourcen und ist voll>> synchron.>Ich bin mir nicht sicher, ob ich dich genau verstehe. Der Timer läuft>doch jeden Takt linear nach oben (erhöht sich jeden Takt um 1).
Ja.
> Wenn ich>jetzt den aktuellen Wert des Timers verwende zum Auslesen der>Sinustabelle,
Nein, in der selben ISR muss dein Programmteil stehen.
> muss ich doch den richtigen Prescaler finden, der z.B. zu> genau 78.5us das TCNTn Register um 1 nach oben setzt.>Wolltest du das damit ausdrücken oder meinst du etwas anderes?
So halbwegs.
Du hast jetzt 2 Timer.
Timer 1 macht die phasenkorrekte PWM mit 2 kHz, sprich 500us Pro PWM
Durchlauf.
Timer2 läuft mit 78us Periodenauer und zählt deinen Index der
Sinustabelle hoch. Das ist aber eher Unsinn, weil deine PWM nur alle
500us einen Updat der PWM-Ausgabe machen kann. Hier verschenkst du
Zwischenwerte, weil dein Index ca. 6,5 mal schneller läuft als die PWM.
Klar, wenn man jetzt eine niedrigere Frequenz generiert, kann man mehr
Zwischenwerte ausgeben.
Falk Brunner schrieb:> PWM mach man meisten möglichst hochfrequent, um dann einfacher filtern> zu können.
Ergibt Sinn. Die 2kHz habe ich zu Demonstrationszwecken verwendet, weil
das Oszibild dann noch "schön" lesbar ist. Angepeilt sind 20kHz am Ende
zur Ansteuerung einer H-Brücke.
>>Ich bin mir nicht sicher, ob ich dich genau verstehe. Der Timer läuft>>doch jeden Takt linear nach oben (erhöht sich jeden Takt um 1).>> Ja.
Okay, immerhin hier sind wir schon auf dem gleichen Nenner ;)
>> Wenn ich>>jetzt den aktuellen Wert des Timers verwende zum Auslesen der>>Sinustabelle,>> Nein, in der selben ISR muss dein Programmteil stehen.
Hmm, welchen Programmteil meinst du genau? Ich kann dir nicht wirklich
folgen, für mich ist das Thema noch Neuland.
>> muss ich doch den richtigen Prescaler finden, der z.B. zu>> genau 78.5us das TCNTn Register um 1 nach oben setzt.>>>Wolltest du das damit ausdrücken oder meinst du etwas anderes?>> So halbwegs.>> Du hast jetzt 2 Timer.
Richtig.
> Timer 1 macht die phasenkorrekte PWM mit 2 kHz, sprich 500us Pro PWM> Durchlauf.
Genau
> Timer2 läuft mit 78us Periodenauer und zählt deinen Index der> Sinustabelle hoch.
Genau.
> Das ist aber eher Unsinn, weil deine PWM nur alle> 500us einen Updat der PWM-Ausgabe machen kann. Hier verschenkst du> Zwischenwerte, weil dein Index ca. 6,5 mal schneller läuft als die PWM.> Klar, wenn man jetzt eine niedrigere Frequenz generiert, kann man mehr> Zwischenwerte ausgeben.
Hier hast du mich wieder verloren. Meinem Verständnis nach brauche ich
einen zweiten, unabhängigen Timer mit 78us Periodendauer. Das resultiert
daraus, dass ich meine 256 Sinuswerte in 20ms Periodendauer abklopfen
muss. Also muss ich alle 78us meine Sinustabelle auslesen. Dieser Wert
wird dann ins OCR1A Register geschrieben und mit der phasenkorrekten PWM
verglichen.
Wenn ich alles in einem Timer (Timer1) machen würde, hätte mein Sinus
doch auch eine hohe Frequenz, weil der Sinus doch nur aus 256 Werten
besteht. Ergo müsste ich in den Sinus mehr Zwischenwerte packen, um eine
höhere Auflösung desgleichen zu bekommen und die 50Hz beizubehalten.
Ich befürchte, dass ich dich noch immer nicht verstanden habe.
Wenn es dir nicht zu viel Mühe macht, wäre ich dir dankbar, wenn du mir
die ISR mit dem Code zeigen könntest. Vielleicht kann ich dir dann eher
folgen.
Da muss ich Falk recht geben,
bei einer Periodendauer von 20ms und einer PWM Dauer von 500µs reicht es
eigentlich, wenn du z.B. auf einen Timer1_OVL Interrupt oder auch aus
dem Timer1_COMP interrupt den Compare Wert aktualisierst, dann benötigst
Du eine Tabellengröße von gerade mal 40 Werten, ohne dass Dein Sinus
schlechter wird wie jetzt;
Wenn Du zudem noch nur eine Viertelwelle Speicherst und nach jeweils 10
Schritten die Zählrichtung des Indexes umkehrst, dann kommst Du sogar
mit 10 Werten aus. (ohne Qualitätsverlust)
Nochmal zum Verständniss:
Du hast in Deinem Qszilogramm eine Ganze Sinuswelle dargestellt.
Die einzelnen PWM Zyklen kannst Du dort von Hand abzählen, und es sind
deutlich weniger als Die 256 in der Tabelle, sondern exakt 40 Schritte.
Es reicht also aus nach jedem timer1 Durchlauf den index zu
aktualisieren, weil alles andere sowieso verloren geht.
nobi schrieb:> Nochmal zum Verständniss:> Du hast in Deinem Qszilogramm eine Ganze Sinuswelle dargestellt.> Die einzelnen PWM Zyklen kannst Du dort von Hand abzählen, und es sind> deutlich weniger als Die 256 in der Tabelle, sondern exakt 40 Schritte.> Es reicht also aus nach jedem timer1 Durchlauf den index zu> aktualisieren, weil alles andere sowieso verloren geht.
Jetzt hat es Klick gemacht. Tut mir Leid, Falk, dass ich mich so schwer
getan habe. Nun meine ich nachvollziehen zu können, wie es besser zu
machen ist.
Ich werde mit dem Code ein wenig rumspielen und die Hinweise und Kritik
einfügen.
Euch allen vielen Dank!
Hallo noch mal,
ich habe mal versucht, mich auf den Hinweis mit dem einen Timer (Timer1)
zu konzentrieren und das Programm entsprechend zu ändern.
Wenn ich euch richtig verstehe, ist das Prinzip das folgende:
1. Timer1 macht phasenkorrekte PWM mit 2kHz. Das heißt, dass TCNT1 alle
500us bei 0 anfängt zu zählen.
2. Jedes mal, wenn TOP erreicht ist (TCNT1 erreicht TOP Wert), entsteht
ein Overflow. Das passiert nun alle 250us (dual slope feature bei
phasenkorrekte PWM). Da mein Sinus 20ms sein soll und alle 250us ein
Interrupt (Overflow) ausgelöst wird, benötige ich 80 Werte in meiner
Sinustabelle.
Diese Logik habe ich mal implementiert, siehe beigefügten Code. Das
Ergebnis ist allerdings alles andere als erhofft :D
Tut mir Leid, dass ich mich dämlich anstelle. Aber ich habe ziemliche
Verständnisschwierigkeiten in der Umsetzung :(
Danke.
@ Michael (Gast)
>Diese Logik habe ich mal implementiert, siehe beigefügten Code. Das>Ergebnis ist allerdings alles andere als erhofft :D
Du bist auf dem richtigen Weg, hast das Ziel nur knapp verfehlt!
Du hättest deine Sinustabelle bei 256 Einträgen belassen sollen. Denn
JETZT, mit nur 80 Einträgen klappt der Trick mit dem Überlauf nicht
mehr! Dein Index i geht von 0-255, darf aber nur von 0-79 gehen. Damit
greifst du auf undefinierte Daten hinter der Sinustabelle zu. Schlimmer
noch, du hast i als int definiert. Das ist eine vorzeichenbehaftete 16
Bit Variable, die erst nach 2^16=65536 Schritten überläuft.
Mach also wieder 256 Einträge und nimm einen uint8_t als Index. Die
Geschwindigkeit/Frequenz regelt man per variabler Schrittweite, so macht
das jede DDS.
sei() macht man NACH allen Initialisierungen kurz vor der endlosen
Hauptschleife, sonst kann es böse Effekte geben.
Und noch was, schreib keine Lyrik in die Kommentare, das bringt nichts.
Sowas macht man bestenfalls als Kurzbeschreibeung für Funktionen, aber
nicht hinter jeder C-Zeile.
>Tut mir Leid, dass ich mich dämlich anstelle. Aber ich habe ziemliche>Verständnisschwierigkeiten in der Umsetzung :(
Nana, kein Grund zur Selbstkasteiung ;-) Das ist alles vollkommen
normal, es ist noch kein Meister vom Himmel gefallen. Am Ball bleiben
ist wichtig.
Noch ein Tip zu Debuggen. Schau dir nicht die PWM direkt an, sondern
nach einem passenden RC-Filter. Fürs erste reicht hier vielleicht ein
200 Hz RC-Filter 1. Ordung. Sagen wir 10k und 3,3uF. Dann siehst du
deinen Sinus direkt.
Hallo an alle,
hier nun wie versprochen das Update. Zunächst allerdings ein Bild vom
Aufbau. Das Filter besteht aus einem 200kOhm Widerstand mit einem 820nF
Folienkondensator. Sonderlich viel Auswahl hatten wir leider nicht.
Zu deinem Code, Falk:
Grundsätzlich sieht das gut aus, siehe F0000TEK. Allerdings beträgt die
Periodendauer 21.2ms anstelle der gewünschten 20ms.
Ich habe noch mal selbst versucht meinen Fehler von Freitag zu finden
und eine SPWM zu implementieren. Und es funktioniert nun, siehe
F0001TEK. Die Sinustabelle besteht aus 40 Werten, Periodendauer beträgt
19.60ms.
Den Code habe ich mit beifügt für jene, die es interessiert.
Eine abschließende Frage hätte ich noch:
Zwischen dem PWM Ausgang (Kanal 2) und dem gefilterten Signal (Kanal 1)
sieht man eine deutliche Phasenverschiebung. Ich hätten den Spitzenwert
des Sinus beim größten Duty Cycle (also in der Mitte bei der größten
Pulsbreite) des PWMs erwarten.
Ich frage mich, woher die Phasenverschiebung kommt. Ich vergleiche ja
nicht Spannung mit Strom, sodass eine Phasenverschiebung durch den
kapazitiven Anteil des Filters verursacht wird. Das Filter dient ja
lediglich dazu, hochfrequente Oberwellen zu unterdrücken. Man sieht ja
noch ein Zappeln auf dem Sinus, das sind die nicht unterdrückten
Oberwellen. Der Sinus, den wir hier sehen, müsste ja sowohl von der
Frequenz als auch von der Phasenlage mit dem PWM Pattern übereinstimmen.
Weiß jemand von euch, warum das gefilterte Signal phasenverschoben ist
und lässt mich an dem Wissen teilhaben?
@ Michael (Gast)
>Aufbau. Das Filter besteht aus einem 200kOhm Widerstand mit einem 820nF>Folienkondensator. Sonderlich viel Auswahl hatten wir leider nicht.
Ist OK.
>Grundsätzlich sieht das gut aus, siehe F0000TEK. Allerdings beträgt die>Periodendauer 21.2ms anstelle der gewünschten 20ms.
Logisch, weil die 6 gerundet sind, echt müsten es 6,4 sei. Aber eins
nach dem anderen ;-)
>Den Code habe ich mit beifügt für jene, die es interessiert.
Gut.
>Ich frage mich, woher die Phasenverschiebung kommt.
Vom Filter.
> Ich vergleiche ja>nicht Spannung mit Strom, sodass eine Phasenverschiebung durch den>kapazitiven Anteil des Filters verursacht wird.
Doch. Denn dein Ausgangs"widerstand" ist ein Kondensator. Jeder Filter
hat auch einen Phasengang, auch dein einfacher RC-Filter. Deutlich
unterhalb der 3dB Bandbreite ist der nahe Null, bei 3dB hat man 45 Grad
Phasenverschiebung, nach oben hin geht es dann auf 90 Grad zu.
> Das Filter dient ja>lediglich dazu, hochfrequente Oberwellen zu unterdrücken.
Sicher, aber diese Eigenschaft kommt nicht allein.
>Oberwellen. Der Sinus, den wir hier sehen, müsste ja sowohl von der>Frequenz als auch von der Phasenlage mit dem PWM Pattern übereinstimmen.
Nein.
Damit man die Frequenz feiner einstellen kann, nutzt man einfach
Festkommaarithmetik. Dazu nimmt man anstelle eines 8 Bit Index einen
16 Bit Index, wobei die unteren 8 Bit die Nachkommastellen darstellen,
welche beim Tabellenzugriff abgeschnitten werden. Siehe unten, wobei
hier wieder mit der 256er Sinustabelle gearbeitet wird. Damit kann man
die Nachkommastellen mit 1/256 vorgeben.
1
#include<avr/io.h>
2
#include<util/delay.h>
3
#include<avr/interrupt.h>
4
#include<avr/pgmspace.h>
5
#include"SineLookupTable.h"
6
7
volatileuint16_tf_inc=6*256+102;
8
9
intmain(void)
10
{
11
DDRB|=(1<<PB1);// PB1 (OCA1) as output
12
OCR1A=pgm_read_word(&sineLookup[0]);// Value where match occurs. Later to be replaced by the sine wave
13
ICR1=500;// TOP value for TCNT1 register
14
TCCR1A|=(1<<COM1A1);// High at bottom, low on compare match
Falk Brunner schrieb:> Logisch, weil die 6 gerundet sind, echt müsten es 6,4 sei. Aber eins> nach dem anderen ;-)
In seinem angehängten Code gibt's keine Schrittweite von 6. Könnte eher
vom ungenauen internen R/C kommen, außerdem ist ICR als Top mit 500
falsch. Schau' die Formel im DB nach, das gibt 501 Schritte bis CT.
Falk Brunner schrieb:> Doch. Denn dein Ausgangs"widerstand" ist ein Kondensator. Jeder Filter> hat auch einen Phasengang, auch dein einfacher RC-Filter. Deutlich> unterhalb der 3dB Bandbreite ist der nahe Null, bei 3dB hat man 45 Grad> Phasenverschiebung, nach oben hin geht es dann auf 90 Grad zu.
Ah stimmt, natürlich. Völlig vergessen, dass es ja noch so ein
Übertragungsverhalten gibt.
Okay, jetzt ist alles glasklar.
Vielen Dank für deine Hilfe und deine Geduld.
Gruß
Noch was, die Sinustabelle gehört in eine .c Datei, in .h wird nur
deklariert (bekannt machen), nicht definiert (Speicher zuweisen).
http://www.mikrocontroller.net/articles/FAQ#Header_File.2C_wie_geht_das.3F
sinus.h
extern const uint16_t sineLookup[] PROGMEM;
sinus.c
const uint16_t sineLookup[] PROGMEM={
250, ......
@ MWS (Gast)
>> Logisch, weil die 6 gerundet sind, echt müsten es 6,4 sei. Aber eins>> nach dem anderen ;-)>In seinem angehängten Code gibt's keine Schrittweite von 6.
Doch, man muss nur den richtigen Anhang betrachten. ;-)
Beitrag "Re: SPWM auf Atmega8, bitte um Feedback hinsichtlich Optimierung"
Falk Brunner schrieb:> Noch was, die Sinustabelle gehört in eine .c Datei, in .h wird nur> deklariert (bekannt machen), nicht definiert (Speicher zuweisen).
Werde mich damit befassen und den Link durchlesen. Hatte es mal auf die
Schnelle versucht zu ändern, aber mit folgender Fehlermeldung:
"../SineLookupTable.c:2:16: error: expected '=', ',', ';', 'asm' or
'__attribute__' before 'sineLookup'
"
Muss mich mal schlau machen, was damit gemeint ist. Wenn ich nicht
weiterkomme, melde ich mich.
@ Michael (Gast)
>Schnelle versucht zu ändern, aber mit folgender Fehlermeldung:>"../SineLookupTable.c:2:16: error: expected '=', ',', ';', 'asm' or>'__attribute__' before 'sineLookup'>"
Naja, man braucht in jeder .c Datei die notwendigen inludes
#include <avr/pgmspace.h>
Falk Brunner schrieb:> Doch, man muss nur den richtigen Anhang betrachten. ;-)
Ich schrieb: "angehängten Code" und das war dieser:
Beitrag "Re: SPWM auf Atmega8, bitte um Feedback hinsichtlich Optimierung"MWS schrieb:> In seinem angehängten Code gibt's keine Schrittweite von 6.
Darauf bezog sich seine ursprüngliche Nachricht, Deine Antwort, als auch
darauf meine Nachricht. Warum sollte ich plötzlich über früheren Code
diskutieren wollen ? Da bringst Du was durcheinander.
MWS schrieb:> außerdem ist ICR als Top mit 500> falsch. Schau' die Formel im DB nach, das gibt 501 Schritte bis CT.
Das habe ich noch mal überprüft. Auf Seite 92 im Datenblatt kann die PWM
Frequenz im phasenkorrekten PWM berechnet werden:
Umgestellt nach TOP:
Mit
folgt:
Wenn ich das Datenblatt richtig verstehe, hält ICR1 den TOP Wert inne.
Okay, dann möchte ich das Thema für mich an dieser Stelle gerne
abschließen, denn das Problem wurde durch die tolle Unterstützung hier
im Forum gelöst. Die SPWM funktioniert nun und noch besser: Ich weiß
sogar, wieso :D
Damit habe ich mein erstes kleines Projekt in Sachen uC fertiggetsellt
und kann nun mit dem Hardwareteil fortfahren.
Gruß,
Michael
Michael schrieb:> Okay, dann möchte ich das Thema für mich an dieser Stelle gerne> abschließen, denn das Problem wurde durch die tolle Unterstützung hier> im Forum gelöst. Die SPWM funktioniert nun und noch besser: Ich weiß> sogar, wieso :D>> Damit habe ich mein erstes kleines Projekt in Sachen uC fertiggetsellt> und kann nun mit dem Hardwareteil fortfahren.
Und natürlich einen großen Dank an alle Beteiligten!