mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik MSP430 Timing Probleme


Autor: Frank H. (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht 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

Autor: Stefan (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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"

Autor: Rufus Τ. Firefly (rufus) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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").

Autor: Frank H. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich habe den Timer A wie folgt intialisiert:
TACTL = TASSEL_1 | ID_0;   //SourceClock = ACLK

damit habe ich ACLK als Clock gewaehlt.

Autor: Rufus Τ. Firefly (rufus) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Frank H. (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: Rufus Τ. Firefly (rufus) (Moderator) Benutzerseite
Datum:

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

Autor: Frank H. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
doch,

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

ok so?

Autor: Christian R. (supachris)
Datum:

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

Autor: Rufus Τ. Firefly (rufus) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Stefan (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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!

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.