Hallo,
ich arbeite mich gerade in den MSP430 ein (aktuell noch mit dem
Launchpad, MSP430G2553) und habe nun das erste programmiertechnische
Problem;-) Ich möchte über den Capture Mode von Timer1_A1 die Frequenz
am Pin P2.1 messen. Dazu wird der Timer beim ersten Aufruf der ISR
gestartet und nach 5 Perioden der Zählerstand ausgelesen. Anschließend
soll Timer0_A1 im Up-Mode die LED an Pin 1.0 mit der gemessenen Frequenz
phasengleich zum Eingang toggeln (das mit der LED ist nur testweise).
Das Problem ist, dass es zu einer kontinuierlichen Phasenverschiebung
zwischen dem gemessenen Signal und dem am µC erzeugten Signal kommt (s.
Oszi-Bilder: In türkis das Signal der LED an P1.6, dass bei jedem ISR
Aufruf getoggelt wird, in gelb das Signal der LED an P1.0 die mit der
berechneten Frequenz getoggelt wird). Jemand eine Idee woher die
Phasenverschiebung kommt und was ich da am Code ändern muss? Hat das was
mit der verwendeten Clock zu tun? Würde gerne die 32kHz bei behalten
weil ich das ganze dann im LPM3 laufen lassen kann. Gemessene Frequenzen
sind im Bereich 50 – 100 Hz.
Vielen Dank und viele Grüße
Simon
Hier noch der Code:
Wenn du die zwei Timer (externer vom Eingangssignal, interner A0) frei
laufen lässt, wird es immer eine Phasenverschiebung geben. Du musst mit
dem Periodenbeginn vom Eingangssignal synchronisieren.
Ich dachte ich wäre relativ synchron da ich den Timer für die
Frequenzerzeugung beim Aufruf des Interrupts durch die externe
Signalquelle starte. Und wenn es eine konstante Phasenverschiebung wäre,
wäre das auch nicht schlimm das könnte man ja noch irgendwie
kompensieren. Mein größtes Problem ist, dass die Phase sich ständig
ändert. Kann das überhaupt mit einem einzigen Timer funktionieren oder
sollte ich die Frequenzerzeugung mit Timer_B realisieren?
Hallo,
ich weiß zwar nicht was das bringen soll ein zum Eingang identisches
Signal zu erzeugen aber egal.
Dein Problem ist, das du mit dem Timer die Eingangsfrequenz nicht exakt
nachbilden kannst da abhängig von Taktfrequenz und Vorteiler des Timers
weder eine 100% exakte Messung der Periodendauer möglich ist, noch deren
Ausgabe. Die einzige Möglichkeit ist, das du den Ausgabetimer mit jeder
steigenden/fallenden Flanke des Einganssigals syncronisierst, so das die
Abweichung sich nicht aufsummieren kann.
Sascha
In der ISR vom Timer1 passt du zwar die Periodenlänge an, aber der
Timer0 läuft weiter. Er wird nicht gestoppt, gelöscht und wieder neu
gestartet, also nicht synchronisiert.
Und nebenbei,Schau dir einmal die Outmode des Timers im Family User
Guide an. Das sollte mit nur einem Timer und reiner HW ohne ISR gehen.
@Sascha: Ja, das Unterfangen klingt erstmal ziemlich sinnfrei! Wenn es
dich wirklich interessiert kann ich dir das gern auf noch auf ner halben
Seite ausführen ;-)
Es ist eben die Frage ob die Phasenverschiebung nur durch den Offset
kommt oder sich die Interrupts gegenseitig behindern (gibt ja
verschiedene Prioritäten wenn ich das richtig gelesen habe). Aber
vermutlich muss man das Eingangssignal ständig überwachen. Sich die
Frequenz zu "merken" hätte den Vorteil gehabt Strom zu sparen. Leider
geht es bei meiner Anwendung um jedes µA!
? Eig. sollte der Timer doch resetet werden wenn er überläuft, im
Up-Mode wenn der Wert in TA0CCTR0 erreicht ist! Was meinst du mit, das
könnte ohne ISR funktionieren?
Ja, der Timer fängt nach Überlauf wieder vom Anfang an. Aber der
Überlauf erfolgt nicht durch die Zuweisung xxCCR0!
Bsp. Der Timer läuft, noch kein Überlauf. Jetzt erfolgt intr vom
Eingang. Du weist die neue Periode zu, die Länger ist. Der Timer läuft
nun noch bis zum Ende der neuen Periode! Die alte Periode hast du jetzt
verlängert! Wenn das ein paar mal passiert, bekommst du das Bild von
oben.
Klingt einleuchtend! Eigentlich sollte es so aussehen, das aus 5
Perioden die Frequenz ermittelt wird und die Interrupts deaktiviert
werden. Dann sollte geschilderte Fall ja nicht mehr auftreten?! Ich
versuch das mal zu programmieren und meld mich wieder! Danke an alle bis
hierher!
Das war nur ein Beispiel. Beim Messen der Periode bekommst du immer
einer Fehler, denn der Timerhat ja keine unendliche Auflösung. Der
Fehler summiert sich auch auf. Du musst also unbedingt synchronisieren,
wenn es Phasen gleich laufen soll.
Wirf einen Blick in den family user guide. Die Outmode der Timer sind
dort gut erklärt. Deine Frequenz Ausgabe sollte nur in HW laufen, also
ohne ISR.
@asynchron: Meinst du mit "synchron", dass das Eingangssignal die ganze
Zeit anliegen muss? Genau das wollte ich ja eig. vermeiden! Ich wollte
über 5 Perioden die Frequenz messen und dann für Sagen wir max. 3
Sekunden die Frequenz im µC halten. Ich hab das jetzt grad mal
durchgerechnet mit dem Offset. Wenn ich mir im Debug-Modus die
Periodendauer anschaue, liegt die ziemlich konstant bei einem Zählerwert
von 327 selten 328. Ausgehend davon, dass der Quarz wirklich mit 32768Hz
schwingt beträgt der Fehler nach einer Sekunde etwa 2ms. Aber nach 3
Sekunden hab ich dann halt ne Phasenverschiebung von über 90°. Das heißt
ja eigentlich die einzige Schraube an der ich drehen könnte wäre eine
höhere Taktfrequenz oder öfters Synchronisieren. Was meinst du mit in HW
laufen lassen? Wenn ich die Ereignisse der verschiedenen Output-Modes
detektieren will läuft das doch auch über die ISR oder? Bin wie gesagt
noch sehr neu in der MSP430 Thematik!
Du hast die Phasenverschiebung zum Eingang bemängelt. Die bekommst du
nur weg, wenn du Eingangssignal und Ausgangssignal synchronisierte. Du
kannst bei jeder Periode oder auch alle 5, 10, ..., 1234 Perioden
synchronisieren. Du musst entscheiden, wieviel Abweichung du toleriert.
Die reine Frequenz Erzeugung kann per HW ohne ISR erfolgen. Für die
Frequenzänderung benötigt du ein Ereignis. Das macht aber der andere
Timer.