Hallo zusammen. Ich stehe vor folgendem Problem: In meiner Applikation erzeuge ich mittels Timer0 (8bit) einen Sinus. Der Timer0 hat 20MHz clock source. Er läuft im Fast-PWM Mode. Top wurde auf 200 eingestellt. Somit hat ja eine PWM Periode eine maximale Auflösung von 200 ticks. Das bedeutet, zu diesem Zeitpunkt wurden die 20MHz auf 100KHz geteilt (dies ist ja nun meine PWM Frequenz) Dieser Zähler erhält die Werte für den Compare Output aus einer Sinustabelle mit 200 Werten. Diese werden nach jedem 10ten Überlauf von Timer0 aktualisiert. Somit ergibt dies, wen wunderts, genau 50Hz! Soweit so gut. Das klappt auch. Nun soll sich dieser Sinus jedoch an ein externes Rechtecksignal Anpassen (also die Frequenz). Das Externe Signal entspricht dem Nulldruchgang eines Sinus. Und kann zwischen 45 und 65Hz sein. Ab hier habe ich nun eine Blockade... Wie kann ich meine PWM Wezeugung an die externe Frequenz anpassen? Ich dachte zuerst an den externen Clock Eingang von Timer0. Aber dann müsste ich eine Frequenz im Bereich 20MHz erzeugen. Oder aber einfach Elemente der Sinustabelle auszulassen... Die Periodendauer des externen Signals wird bereits gemessen mit Timer1 (16bit) mit 3.2us Auflösung. Hat jemand einen Tipp, wie ich hier weiterkomme? Danke!
Claudio Hediger schrieb: > Hat jemand einen Tipp, wie ich hier weiterkomme? Du mußt natürlich eine PLL (phase locked loop) bauen. Sowas besteht aus drei Teilen: 1) Phasenkomparator Das Teil vergleicht zwei Signale bezüglich ihrer zeitlichen Lage und ermittelt daraus ein Fehlersignal. In deinem Fall würde man das wohl so lösen, daß man zum Zeitpunkt des extern gelieferten Nulldurchgangs schaut, an welcher Position der Sinustabelle man gerade ist. Dann schaut man, wo in der Sinustabelle der nächstliegende Nulldurchgang ist. Die Differenz aus diesen beiden Tabellenoffsets ist das Fehlersignal. Denn das Ziel ist ja das Erreichen des Nullpunktes der Tabelle zum Zeitpunkt des externen Nulldurchgangs. 2) Rückkoppungsverstärker/Tiefpass Reine Software. Irgendeine (natürlich eine geeignete) Implementierung eines Reglers. 3) Aktor Hierfür wurde sich der Top-Wert des Timers anbieten, denn der bestimmt letztlich, wie schnell es in der Sinustabelle vorangeht. Ein Problem hast du aber unabhängig von der genauen Implementierung der Sache: Das externe Nulldurchgangssignal alleine genügt nicht für eine korrekte Synchronisation, denn es erlaubt ein Einrasten der PLL bei einer Phasenlage von 0° und von 180°. Du brauchst zusätzlich ein Polaritätssignal. Der oben beschriebene Phasenkomparator wäre insofern abzuändern, daß er nicht den nächstliegenden Nullpunkt als Referenz nutzt, sondern den einen mit der korrekte Polarität.
c-hater schrieb: > Hierfür wurde sich der Top-Wert des Timers anbieten, denn der bestimmt > letztlich, wie schnell es in der Sinustabelle vorangeht. Cielen Dank für deine Antwort... An deinen Plan mit der PLL habe ich auch schon gedacht. Ein Problem sehe ich jedoch bei dem von dir genannten Aktor. Der Top-Wert des Timers für den PWM ist zwar die Frequenz, aber zugleich auch die Auflösung (oder sehe ich hier was falsch?) Dieser hat ja bei mir den Wert 200. Der Outputcompare OCR1B vom Timer wird auf einen Wert zwischen 0 und 199 gestellt. Der Timer erzeugt ja damit dann das PWM Signal. Deshalb würde ja eine anpassung des TOP-Wertes eine anpassung der Auflösung zur Folge haben. Deshalb hab ich eben eine Blockade :) Vermutlich ist dieses Problem nicht lösbar :( Mein Nulldurchgang kommt immer nur einmal pro Periode. Bei 0° geht die Flanke nach oben und bei 180° nach unten. Somit wäre dieses Problem gelöst...
Eventuell wäre eine verkürzte bzw. verlängerte Sinustabelle eine lösung. Wenn ich beispielsweise 45Hz messe, dann wird die 45Hz Sinustabelle ausgegeben. Dann kann ich die Sample Rate identisch lassen, aber die anzahl Einträge der Tabelle Variieren dann halt... Erzeugt einfach viel zusätzlichen Speicherbedarf und ich verbrauche einiges an Zeit in den Interrupts, da ich dort ja mit switch prüfen muss, welche Tabelle denn ausgegeben werden muss. Und dies mit 2.5KHz
@ Claudio Hediger (hedie) >Das bedeutet, zu diesem Zeitpunkt wurden die 20MHz auf 100KHz geteilt >(dies ist ja nun meine PWM Frequenz) OK. >Nun soll sich dieser Sinus jedoch an ein externes Rechtecksignal >Anpassen (also die Frequenz). Das Externe Signal entspricht dem >Nulldruchgang eines Sinus. Und kann zwischen 45 und 65Hz sein. >Wie kann ich meine PWM Wezeugung an die externe Frequenz anpassen? Wie der Rest der Welt, mit dem DDS Prinzip. PLL ist hier nicht sinnvoll. >Oder aber einfach Elemente der Sinustabelle auszulassen... Genau so macht das DDS.
Falk Brunner schrieb: >>Oder aber einfach Elemente der Sinustabelle auszulassen... > > Genau so macht das DDS. Danke für den Tipp... Werden beim DDS auch veschiedene Tabellen abgelegt?
Claudio Hediger schrieb: > Falk Brunner schrieb: >>>Oder aber einfach Elemente der Sinustabelle auszulassen... >> >> Genau so macht das DDS. > > Danke für den Tipp... > > Werden beim DDS auch veschiedene Tabellen abgelegt? Nein. Eine Tabelle. DDS ist nur ein Trick, wie man im Grunde mit Nicht-ganzzahligen Werten beim Tabellen-Index bzw. seinem Inkrement von einem Zeitpunkt zum nächsten hantieren kann, so dass man im Endeffekt wieder ganzzahlig ins Array zugreift, aber ab und zu, aber vor allen Dingen regelmässig, genau die (jeweils anderen) Werte aus der Tabelle auslässt, so dass man eine 200 Einträge große Tabelle in zb 185 Schritten abarbeitet und somit die letztendlich damit erzeugte Frequenz erhöht. Im Grunde könnte man es als eine Variation von Fixed-Point Arithmetik bei der Berechnung der Array-Indizes auffassen. Wobei man natürlich cleverer Weise eine 2-er Potenz als Vielfaches nimmt, damit das im Rechner schnell geht. DDS ersetzt diesen Teil hier > Diese werden nach jedem 10ten Überlauf von Timer0 aktualisiert.
:
Bearbeitet durch User
Falk Brunner schrieb: > Wie der Rest der Welt, mit dem DDS Prinzip. Richtig, die Schrittweite einer DDS wäre hier deutlich besser als "Aktor" geeignet. > PLL ist hier nicht sinnvoll. Wieso nicht? Wie willst du sonst die DDS mit der externen Sollfrequenz synchronisiert bekommen (und synchron halten)? Nö, die richtige Lösung ist natürlich PLL UND DDS.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.