Forum: Mikrocontroller und Digitale Elektronik MSP430 Timer mit TAR - Timingproblem


von Gunb (Gast)


Lesenswert?

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

von Falk B. (falk)


Lesenswert?

@ 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

von Gunb (Gast)


Lesenswert?

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:
1
#define DELAY()  TAR=0xFD29;while(!(TACTL&TAIFG));TACTL&=~(TAIFG)
2
3
void delay_100us(uint16_t wTime)
4
{
5
  while(wTime){
6
    DELAY();
7
    wTime--;
8
  }
9
}

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
     case 10:
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 :-)

von Falk B. (falk)


Lesenswert?

@ 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

von Christian R. (supachris)


Lesenswert?

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.

von Gunb (Gast)


Lesenswert?

@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

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
Noch kein Account? Hier anmelden.