Hallo, ich versuche eine variable PWM (Signalgenerator) mit einem MSP430FR4133 zu implementieren. Der Timer dafür hat eine 256 Zyklen lange Periode und läuft mit dem vollen Systemtakt. Die auszugebenden Werte werden aus einer Tabelle im RAM gelesen. Leider hat dieser MSP nur "Timer A" Module, die nicht über ein Latch für die Compare-Register verfügen wie "Timer B" Module haben. Daher läuft man beim Setzen der Compare-Register (z.B. TA0CCR1) in Gefahr, eine Periode zu überspringen, wenn die Phase gerade entsprechend kurz bzw. besonders lang ist. Das beschränkt den nutzbaren Bereich ziemlich stark, so auf ca. 50-200 für mit GCC compilierten Code. Nun will ich versuchen, den TA0CCR1 anstatt im Overflow-Interrupt in einem eigenen Interrupt (TA0CCR2=x) zu setzen, und zwar so dass der Wert genau zum Zeitpunkt TA0R == 0 gesetzt wird. Damit wird in etwa das Verhalten vom CCR-Latch eines "Timer B" simuliert. Ist das realistisch, oder ist der Ausführungszeitpunkt zu schlecht vorhersagbar, um den genauen Zeitpunkt zu treffen?
Die Anzahl der Taktzyklen ist genau spezifiziert (Abschnitt 4.5.1.5 des User's Guide). Allerdings braucht ein normaler Befehl zwischen 1 und 6 Zyklen, also ist beim Interrupt schon mal eine Ungenauigkeit von mindestens 5×MCLK drin. Timer_B oder zumindest DMA wären schon nützlich ...
P. G. schrieb: > Leider hat dieser MSP nur "Timer A" Module, die nicht über ein Latch für > die Compare-Register verfügen wie "Timer B" Module haben. Nun, ich habe keine Ahnung von der MSP-Hardware, aber wenn ich einen Timer hätte, der keine synchronisierten Updates der Compare-Register unterstützt, würde ich einfach in Software eine Synchronisation BAUEN, die den Schaden möglichst gering hält. Das ist doch absolut trivial. Der einzige Nachteil wäre, dass es passieren kann, das das Update des Compare-Registers um n (n=unbestimmt, aber mindestens 1) Zyklen verzögert erfolgt. In den verpassten Zyklen würde einfach der letzte gültige Wert erneut ausgegeben. Das ist immerhin sehr viel besser als ein Glitch. Man muss dazu nur das genaue Timingverhalten der eigenen Software kennen. Sprich: in der einzig akzeptablen Sprache für harte Echtzeit programmieren: Assembler.
Hm, die Befehle meines Codes im Interrupt kann ich ja ausmessen. Aber wie Clemens sagt ist der Interrupt-Einsprung schon auf 5 Zyklen ungenau, und da der MSP430 Caches hat würde mich nicht wundern wenn die Anzahl der Waitstates beim RAM-Zugriff ebenfalls schwankt. Allerdings sind die alle ausgegebenen PWM-Tabellen recht groß, so dass eigentlich kein Cache-Treffer zu erwarten ist, wenn die Tabellen immer vollständig ausgegeben werden, was im Moment der Fall ist. Man kann natürlich den Interrupt "rechtzeitig" ansetzen, und dann in der Interrupt-Routine wie bei einem Spinlock auf TA0R == 0 warten. Bzw. man kann sich doch sicher noch feiner rantasten, um die noch genauer als die Zyklenzeit einer Warteschleife zu arbeiten? Z.b. erstmal auf TA0R < 5 warten und dann noch etwas abhängig vom TA0R Wert machen? So müsste auch eine Punktlandung zu schaffen sein, oder?
P. G. schrieb: > So müsste auch eine Punktlandung zu schaffen sein, oder? Mit Code im SRAM, und genügend trickreichen Assemberbefehlen, rein theoretisch ja.
Ich habe das Problem nun anders gelöst: Da alle generierten Signale ein gutes Stück unterhalb der Nyquist-Frequenz liegen, ergibt sich die Garantie, dass die variablen Flanken der PWM sich niemals näher als einen bestimmten Mindestabstand kommen. Nach wie vor kann aber bei hoher Amplitude die variable Flanke beliebig nahe an die feste Flanke rücken. Daher habe ich nun das Aktualisieren des PWM-Wertes in einen Interrupt auf der variablen Flanke verlegt. Wegen des oben genannten Mindestabstandes wird nun keine Periode mehr übersprungen, die Interruptroutine passt immer in den Zeitraum zwischen zwei variablen Flanken. Das funktioniert natürlich nur mit Signalen mit einer begrenzten Steilheit, aber bisher genügen alle meine zu generierenden Signale dieser Bedingung. Das beantwortet zwar die ursprüngliche Frage nicht ganz, aber "funktioniert einfach" ohne großes ausmessen der Instruktions-Laufzeiten.
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.