Hallo zusammen,
ich habe eine generelle Frage zur Verwendung des MSP430 Timers:
Kann man den Timer zuverlässig auch ohne Interrupt per Polling und ohne
Verwendung der CCRx-Units verwenden?
Anwendung: Wenn ich bei meinem Mega AVR128 bisher keinen Interrupt
benutzen wollte, dann habe ich das Zählregister mit einem Wert geladen,
den Timer gestartet und das Interruptflag gepollt und bei Überlauf
gestoppt! Dies funktioniert zuverlässig. Der Timer generiert eine 100us
Zeitbasis, von der ich per Funktion dann auch Vielfache generieren kann
-alles kein Problem, funktioniert wie gesagt.
Ich wollte dies nun auch beim MSP430x169/1611 umsetzen. Beispiele zur
Verwendung der CCR0-2 gibt es ja genug und diese funktionieren auch bei
mir. Die TI-Beispiele bzw. die Ports für den MSPGCC zeigen aber eine
gemeinsame Eigenschaft: sie nutzen alle ausschliesslich die CCR-Units
und starten diese einmal, wobei die Interrupts vorwiegend genutzt
werden, kein Polling.
Ich habe mein o.g. Beispiel nun mit der CCR0 umgesetzt, habe aber immer
wieder Probleme mit der Erzeugung des exakten Zeitintervalls. Im
Unterschied zu den Beispielen starte und stoppe ich den Timer jedoch.
Ist dies beim MSP430 ein Problem?
Kann man das Interrupt-Flag zuverlässig auch im Polling-Betrieb
abfragen?
Weiterhin habe ich in einem weiteren Versuch die CCR0 ganz weggelassen
und den Interrupt des TAR direkt genutzt. Auch hier lade ich das
Register vor, starte den Timer und warte auf ein Setzen des Flags. Zur
genauen Erzeugung der 100us-Basis habe ich die Latenzzeiten
berücksichtigt.
Nachdem ich nicht sicher war, ob das Interruptflag im Pollingbetrieb
richtig gesetzt wird, habe ich das ganze mit Interrupt umgesetzt. Ich
zähle in der ISR eine Variable herunter, um Vielfache der Einsprungzeit
zu erzeugen. Unter Berücksichtigung der Latenzzeiten lief der Timer bei
Vielfachen ungenau.
Mir ist klar, dass hier der Code fehlt, es ist sehr spät und ich habe
ihn momentan nicht zur Hand. Bitte dies zu entschuldigen.
Mir geht es auch vielmehr darum zu erfahren, ob das Unterbrechen eines
Timers speziell beim MSP430 zu Synchronisationsproblemen führt, wenn ich
diesen immer wieder starte, beim AVR ist das kein Problem.
Verwundert hat mich, dass in allen TI-Beispielen, die ich bisher gesehen
habe, immer Zeiten mit der CCRx erzeugt werden, nie mit dem TAR direkt,
obwohl ich dies bei durchlaufendem Timer mit Interrupt erfolgreich
umsezten konnte.
Bitte um Nachsicht, dass meine Erläuterung zu dem Thema etwas lang
geworden ist, wäre aber sehr dankbar für jede Erfahrung von eurer Seite
und vielleicht hilfreiche Tips, wo ich mehr erfahren kann. Habe nun drei
Tage probiert. In den App.Notes konnte ich dazu nichts finden (?)
Danke für's reinschauen,
Gruss
Gunb
@ Gunb (Gast)
>Kann man den Timer zuverlässig auch ohne Interrupt per Polling und ohne>Verwendung der CCRx-Units verwenden?
Verwenden ja, zuverlässig naja, klingt aber eher nach Unsinn.
>benutzen wollte, dann habe ich das Zählregister mit einem Wert geladen,>den Timer gestartet und das Interruptflag gepollt und bei Überlauf>gestoppt! Dies funktioniert zuverlässig.
Was soll der Quark? Du hast das Prinzip des Timers und Interrupts noch
nciht verstanden. Nochmal drüber nachdenken.
AVR-Tutorial: Timer
[AVR-Tutorial: Interrupts]]
>und starten diese einmal, wobei die Interrupts vorwiegend genutzt>werden, kein Polling.
Was auch sinnvoll ist um
a) die CPULast zu minimieren
b) eine GENAUE Zeitbasis zu erzeugen, ohne sprodisch verschluckte Takte
>Ist dies beim MSP430 ein Problem?
Nein, DU hast ein VErständnisproblem. Der Rest der Welt nutzt Timer mit
Interrupt ohne Probleme.
>Kann man das Interrupt-Flag zuverlässig auch im Polling-Betrieb>abfragen?
Nein. Das wird prinzipbedingt ungenau.
>zähle in der ISR eine Variable herunter, um Vielfache der Einsprungzeit>zu erzeugen.
Genau so muss es sein.
> Unter Berücksichtigung der Latenzzeiten
Welche Latenzzeiten?
> lief der Timer bei Vielfachen ungenau.
Dann hast du ihn falsch initialisiert oder sonstwo einen
Programmierfehler drin. Poste mal etwas Sourcecode, als Anhang.
>Mir geht es auch vielmehr darum zu erfahren, ob das Unterbrechen eines>Timers speziell beim MSP430 zu Synchronisationsproblemen führt, wenn ich>diesen immer wieder starte, beim AVR ist das kein Problem.
Dort ist das auch ein Problem, du hast es nur nicht gesehen, warum auch
immer.
>habe, immer Zeiten mit der CCRx erzeugt werden, nie mit dem TAR direkt,
Logisch, weil das das Timeregister ist, welches nur durchläuft. Das
braucht man direkt beim AVR auch eher selten.
MfG
Falk
Hallo Falk,
danke für deine Antwort.
Eines mal vorweg: Es ist mir durchaus bewusst, dass Polling eine
unprofessionelle "Lösung" darstellt, sie stammt auch nicht von mir,
sondern war auf Atmel-Code bereits vorhanden. Messungen mit Scope haben
jedoch gezeigt, dass diese für einfache Zwecke ausreichend war. Ich
wollte sie nur probeweise auf den MSP portieren und testen, ob's hier
genauso klappt. Keine Frage, programmiere für genaues Timing immer mit
Interrupt, seit eh und je. ICH habe also kein Problem mit dem MSP430.
Inzwischen habe ich den Fehler auch gefunden, es lag am Interruptflag
des TAR-Überlaufs, das ich fälschlicherweise noch von der CCR0
übernommen hatte. Zuvor bekam ich nämlich nie einen Überlauf, daher
meine Frage.
Es sieht so aus:
ICH WEISS, DASS DIES NICHT SEHR SCHÖN IST! Ich hab's ja nur mal testen
wollen und festgestellt, dass es auf dem Atmel genauer als auf dem MSP
läuft.
Was meine ich damit? Das Makro stellt die Zeit auf genau 100us ein. Ruft
man die Funktion mit 1 im Argument auf, um 100us zu erzeugen, stimmt's
exakt. Ruft man sie hingegen mit 10 auf, um 1ms zu erzeugen, dann messe
ich mit dem Scope so ziemlich genau 948us - da hätte ich eher einen Wert
grösser 1ms erwartet.
Nun gut, schätze, da ist das Polling dann wirklich eine extrem schlechte
Option. Der Mega128 läuft da auf jeden Fall genauer. Stimme dir aber
uneingeschränkt zu, dass dies prinzipiell ungenau ist und keiner
professionellen Umsetzung entspricht.
Aber nun doch eine Frage, nur zur Klärung der Vollständigkeit halber:
Was spricht dagegen, auf die CCRs gänzlich zu verzichten, wenn ich zum
Beispiel nur einen simplen Timer brauche, der Überläuft und einen
Interrupt erzeugt?
Um es etwas zu konkretisieren:
Ich starte den Timer A im Continuous-Mode, dann zählt das TAR-Register
bis 0xFFFF und erzeugt beim Überlauf auf 0 einen Interrupt, durch den
das TAIFG gesetzt wird. In der ISR kann ich dann per Abfrage das TAR als
Quelle ermitteln, z.B. so:
1
interrupt(TIMERA1_VECTOR)Timer_A(void)
2
{
3
switch(TAIV)
4
{
5
case10:
6
TAR=0xFFD6;
7
P6OUT^=0x80;
8
break;
9
}
10
}
Ich meine, es funktioniert ja perfekt und wenn ich keine weiteren Zeiten
benötige, warum dann die CCRs benutzen?
An deiner Meinung wäre ich sehr interessiert, siehst du da irgendeinen
Nachteil? Ich habe mich nur gewundert, warum die Beispiele einen
einfachen Timer nicht auf dieser Basis berücksichtigen. Oder ist das
zuuu trivial?
Danke dir und einen angenehmen Tag,
Gunb :-)
@ Gunb (Gast)
>Was spricht dagegen, auf die CCRs gänzlich zu verzichten, wenn ich zum>Beispiel nur einen simplen Timer brauche, der Überläuft und einen>Interrupt erzeugt?
Nichts. Aber du brauchst dazu den UP-Modus. Dann kannst du dir das Ganze
ungenaue Rücksetzen sparen.
MFG
Falk
Wenn du das TAR verändern willst, musst du den Timer vorher anhalten,
also in den Stopp-Modus bringen.
Insgesamt ist das aber alles keine schöne Angelegenheit, weil man da
leicht Jitter reinbekommt, je nach Taktfrequenz und Timertakt. Ich mache
sowas, um Timer auf Funksensorknoten zu synchronidieren, die laufen aber
bloß mit 32Khz und die CPU mit 6MHz, da geht das.
Schau dir doch lieber mal die CCR-Geschichten an, die sind sowas von
universell, das ist echt eine Freude, damit zu arbeiten. Schon mit dem
Timer A kann man 3 unterschiedliche Zeitintervalle ohne CPU-Last
erzeugen. Mit dem Timer B sogar 7.
@Falk: DU BIST MEIN HELD!
MENSCH, DATT ISSET! Jetzt läuft datt Ding endlich so, wie es soll!
TACCR0 geladen und TAR als Zähler - perfekt.Ich hab's vor lauter Bäumen
nicht mehr gesehen, zu lange vor dem Compi gesessen ;-)
@Chris:
Hast natürlich Recht, ich nutze sie ja bereits seit Jahren. In dem oben
geschilderten Fall hat mich aber mein Ehrgeiz gepackt und ich wollte
einfach wissen, ob das mit dem MSP nicht auch ohne Weiteres geht. "Der
muss das doch auch können", habe ich mir gedacht.
Nutzen werde ich die CCRs, aber interessant ist's schon. Der Hintergrund
ist der, dass ich Geräte entwickle, die per Gesetz gewissen Empfehlungen
unterliegen. Wenn ich auch darauf an dieser Stelle nicht weiter eingehen
kann, so sei dazu soviel gesagt, dass die Verwendung von Interrupts
möglichst vermieden werden sollte. Wenn dies wahrscheinlich auch ein
etwas Interrupt-ängstlicher Bürokrat geschrieben hat, so ist doch
verständlich, warum der Code für den Atmel bereits das Polling
verwendete. Ich wollte dies nun einmal auf dem MSP checken. Nutze aber
trotzdem die CCRs :-))))
Danke euch für den Support!
MfG
Gunb