Forum: Mikrocontroller und Digitale Elektronik MSP430 Timing Probleme


von Frank H. (Gast)


Angehängte Dateien:

Lesenswert?

Hallo,

ich habe grosse Probleme mit dem Timing meines Programmes, die 
Timerlaenge schwankt aus mir nicht erklaerbaren gruenden unregelmaessig 
hin und her.
Das Programm laeuft wie folgt ab:
Timer A wird gestartet und ruft Timer B aus, der vier mal innerhalb 
Timer A durchlaufen wird. Innerhalb Timer B wird die ADC Routine 
ausgefuehrt und nach dem viermaligen durchlaufen ein Mittelwert gebildet 
der dann via Serieller Schnittstelle(9600baud) verschickt wird.
Auch wenn ich das versenden abschalte, das Timing stimmt einfach nicht..
Sieht jemand von euch den Fehler?

Vielen Dank
Frank

von Stefan (Gast)


Lesenswert?

Also das kommt mir sooooo bekannt vor, dass ich ja fast Troll-Alarm 
auslösen möchte. Aber wie immer, denke ich ja zuerst mal nur das Beste:

Alles schon dagewesen:
Beitrag "[MSP430] Probleme mit dem Mikrocontroller"

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Es fehlt die gesamte Initialisierung der Takterzeugung. Ohne die wird 
der MSP430 vom internen RC-Oszillator "DCO" mit einem Takt von irgendwas 
um 1 MHz versorgt.

Du musst klären, was die Taktquelle sein soll

  DCO
  LFXT1 im NF- oder HF-Modus
  XT2

und entsprechend die Register BCSCTL1 und BCSCTL2 initialisieren.
Außerdem musst Du auf das Einschwingen des Oszillators warten; 
Beispielcode findet sich im User's Manual im Abschnitt 4 ("Basic Clock 
Module").

von Frank H. (Gast)


Lesenswert?

Ich habe den Timer A wie folgt intialisiert:
1
TACTL = TASSEL_1 | ID_0;   //SourceClock = ACLK

damit habe ich ACLK als Clock gewaehlt.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Das ist ja schön und gut, aber bevor Du dem Timer_A irgendeinen Takt 
zuführst, musst Du den erstmal erzeugen. Auch den Takt, mit dem der 
Controller selber läuft, und den Takt, mit dem Du die UART versorgen 
willst.

Und dafür ist beim MSP430 das "Basic Clock Module" zuständig, das im 
Abschnitt 4 des "User's Manual" beschrieben wird.

Ohne Initialisierung wird ACLK vom LFXT1 im NF-Modus versorgt; hängt da 
überhaupt ein Quarz dran?

MCLK und SMCLK hingegen werden vom DCO mit irgendwas um 1 MHz versorgt.

von Frank H. (Gast)


Lesenswert?

Den Fehler hab ich gefunden, der ADC wurde mit dem falschen Takt 
gespeist.
ADC12SSEL_0

Das Taktspiel funktioniert nun tadellos, jedoch machen mir die Werte des 
ADC ein wenig sorgen. Ich haben an einen der Eingaenge einen 
Funktionsgenerator angeschlossen und die anderen beiden abzutastenden 
Kanaele auf Masse gelegt. Ab und zu tauchen extreme Messspitzen auf, 
welche foellig aus dem Rahmen fallen. Bei dem Signal handelt es sich um 
einen Sinus, 20hz, Amplitude  20mv-1V. Die Fehlmessungen liegen immer 
bei Maximalauschlag(3.3V). Mit sample an hold ich auch schon versucht 
die Messungen zu verbessern, jedoch ohne Erfolg. Hat jemand eine Idee?

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Nein, den Fehler hast Du nach wie vor nicht gefunden. Oder 
initialisierst Du mittlerweile die Register des "Basic Clock Module"?

von Frank H. (Gast)


Lesenswert?

doch,

 DCOCTL = DCO0 + DCO1 + DCO2;
 BCSCTL1 = RSEL0 + RSEL1 + RSEL2;
 BCSCTL2 = SELM_0 + DIVM_0 + DIVS_0;

ok so?

von Christian R. (supachris)


Lesenswert?

Damit stellst du den DCO auf irgendeine Frequenz ein, die wohl bei 
etwa 5MHz liegen könnte.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Das bedeutet, daß Du einen Uhrenquarz oder dergleichen an LFXT1 
angeschlossen hast und den als Quelle für ACLK verwendest. Das scheinen 
bei Dir 32 kHz zu sein, damit versorgst Du sowohl den Timer_A als auch 
den Baudratengenerator Deiner UART.

Für MCLK und SMCLK verwendest Du hingegen den DCO. Und den ADC steuerst 
Du mit einem weiteren internen Oszillator, dem ADC12OSC an.

Wenn der ADC-Takt, der Prozessortakt und der Timertakt nicht aus einem 
gemeinsamen Taktsignal abgeleitet werden, dann kann es zu sehr 
"interessanten" Nebeneffekten in Form von Schwebungen auf dem 
ADC-Ergebnis kommen. Um saubere Messergebnisse zu erhalten, sollten alle 
Takte sich auf einen Referenztakt beziehen. ACLK ist bei Deiner 
Anwendung dafür zu langsam, der DCO zu ungenau, vor allem eignet er sich 
nicht als Baudratengenerator.

Es gibt zwar eine AppNote von TI, die beschreibt, wie man mit einem 
32kHz-ACLK den DCO permanent nachjustieren kann, der resultierende 
DCO-Takt ist, gemittelt über alles, auch ausreichend genau. Für eine 
ADC-Ansteuerung taugt aber auch das nicht, weil die DCO-Umschaltung 
durchaus auch während eines Sample-Vorganges des ADC geschehen kann, was 
wieder interessante Nebeneffekte hervorrufen kann.

Um wirklich stabil stehende und saubere Messwerte zu erhalten, sollte 
man obendrein eine Netzbrummkompensation vorsehen. Diese funktioniert 
so, daß während einer Netzfrequenzperiode (in Europa 20 msec) in 
gleichmäßigen Abständen mehrere Messungen durchgeführt werden und 
deren Mittelwert gebildet wird.

So erhält man bei halbwegs sauberen Schaltungsdesign (Layout, 
Entkopplungskondensatoren etc.) ein bis aufs letzte Bit ruhig stehendes 
ADC-Ergebnis.

Die hierfür erforderliche Takterzeugung lässt sich am einfachsten mit 
einem 8MHz-Quarz an XT2 oder LFXT1 aufbauen.
Wird LFXT1 im HF-Modus verwendet, dann werden MCLK und ACLK daraus 
abgeleitet; SMCLK kann dann nicht verwendet werden.
Wird hingegen XT2 verwendet, werden MCLK und SMCLK daraus abgeleitet; 
ACLK kann nicht genutzt werden.

Das macht aber nichts, weil alle Peripheriemodule wahlweise ihren 
Referenztakt aus ACLK oder SMCLK beziehen können.

von Stefan (Gast)


Lesenswert?

Also wie ich schon ganz am Anfang erwähnte, ist Dein Problem ähnlich 
gelagert wie hier:
Beitrag "[MSP430] Probleme mit dem Mikrocontroller"
Wenn auch diesmal in die serielle Datenübertragung verlagert!

Rechne doch mal nach:
Dein Timer_A feuert alle 15,625ms
Dein Timer_B alle 2,93ms (passt locker 4x in Timer_A Intervall -> OK)

ABER:
Pro Timer_B Intervall werden 3 Bytes per UART versendet. Wenn ich 
richtig rechne, dauert eine Datenübertragung (1 Start, 8 Daten, 1 Stop, 
9600bd) 1,042ms. das ganze 3x macht 3,125ms! Du hast pro 
Timer_B-Intervall aber nur 2,93ms zur Verfügung, d.h. Dein Timing 
überholt sich irgendwann selbst und führt zu undefinierten Zuständen!
Und dabei sind ADC-Wandlungszeit und Mittelwertbildung noch gar nicht 
mit eingerechnet!

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.