Hi! ich versuche z.Z. verzweifelt einen MSP430 mit einem 32khz Uhrenquarz zum Laufen zu bewegen (MSP430F1121). Ich hab, wie im Datenbaltt beschrieben nur den Quarz an XIN/XOUT angeschlossen und verwende folgenden Init-Code : void vClockInit( void ){ WDTCTL = WDTPW + WDTHOLD; /* Watchdog deaktivieren */ BCSCTL1 &= ~0x30;//select low-frequencymode, ACKL-Divider = 1 BCSCTL2 = 0xC8; /* set MCLK=ACLK*/ } kommt ursprünglich aus der c't. Laut Datenblatt ist beim LF-Mode ja das abfragen des Errorbits nicht nötig, oder? Am Oszi bekomm ich zwar ein 32 khz Signal, daß allerdings nur eine Amplitude von 360mV hat (um 2.5V herum, bei 3.6V VCC). Das ist doch nicht normal, oder? Hat jemand vieleicht ein Codesample zur Initialisierung des Clks für den mspgcc bei 32Khz? Oder hat jemand ne Idee, was ich falsch mache? Vielen Dank am Voraus Jan Stumpf
MSP430 LF-XTAL, ich fange gerade mit dem MSP430 an und bin gestern gleich bei der Programmierung der ersten paar Zeilen auf das gleiche Problem gestossen. Ich benötige den Watchdog ebenfalls im Interval-Mode, um den DSO zu synchronisieren, da TimerA für komplett für andere Zwecke benötigt wird. MSP430F1232 läuft mit 3,4V, zweilagiger Platinenaufbau. Uhren- quarz schwang nicht. Erster Augenschein: - Der super-duper Billigquarz tut nicht (möglicherweise auch zu lange gelötet) trotz passender Spezifikation. - Anderer Quarz mit 2 * 3pF parallel tuts... den im Datenblatt empfohlenen 5,1MOhm-Widerstand habe ich mir verkniffen, da VDD>2,5V. - Dummerweise habe ich mich verlayoutet und auf der Rückseite der XIN/XOUT-Pins sind ein Eingang und der korrespondierende Ausgang eines derzeit noch unbeschalteten OPs angeordnet (schwingt natürlich) Möglicherweise gibt es dort einen Einfluß. Das wurde im Layout jetzt berücksichtigt, so daß auch der gegenüberliegenden Seite beim nächsten Mal Masseflächen vorhanden sind, so wie es sein sollte. Fazit: Aufpassen beim Layout, brav Ground-Traces legen und schön Abstand halten von anderen Leitungen. Jetzt noch eine Beobachtung zum MSP-GCC und Watchdog (derzeit noch XY-ungelöst): - Der DSO schwingt sofort an, beim Umschalten des Watchdog auf LFOSC als Taktgeber muß erst eine Weile gewartet werden. Code-Snipped vom anderen Thread hier (TI-Code): do { IFG1 &= ~=OFIFG // Clear OSC-Fault Flag for (i=0xff; i>0; i--); // settle time } while (IFG1 & 0FIFG); // OSC-Fault? - GDB schmiert ab beim Verwendung von ACLK beim Watchdog, beim Verwendung des DSO klappt es -> möglicherweise läuft die LFCLK durch und erzeugt mehrere Interrupts während eines Steps, was den JTAG durcheinanderbringt oder GDB verwendet selbst diese Methode, um SW-Breakpoints zu setzten (weis jemand Rat?) Stand-alone funzt es aber. - Man kann bei den meisten MSPs einen IO-Pin dazu verurteilen, die ACLK gebuffert auszugeben, bei mir wäre das glaube ich P2.0, wenn dort nicht was dranhängen würde. zu Deinem Problem: Der Watchdog muss natürlich auch wieder eingeschaltet werden, sprich WDTHOLD darf beim nächsten Befehl nicht gesetzt sein. 73, Jörg
Self-Re Du hast natürlich recht... Im LF-Mode scheint das Error-Flag nicht gesetzt zu werden (slaa081.pdf) Jörg
Hi Jörg! >Erster Augenschein: >- Der super-duper Billigquarz tut nicht (möglicherweise auch > zu lange gelötet) trotz passender Spezifikation. hmm, vieleicht ist meiner auch nicht gut genug. Ich hatte nur bisher keine Probleme mit Quarzen. >- Anderer Quarz mit 2 * 3pF parallel tuts... den im Datenblatt > empfohlenen 5,1MOhm-Widerstand habe ich mir verkniffen, da > VDD>2,5V. das werde ich mal ausprobieren. >- Dummerweise habe ich mich verlayoutet und auf der Rückseite > der XIN/XOUT-Pins sind ein Eingang und der korrespondierende > Ausgang eines derzeit noch unbeschalteten OPs angeordnet (schwingt > natürlich) Möglicherweise gibt es dort einen Einfluß. > Das wurde im Layout jetzt berücksichtigt, so daß auch der > gegenüberliegenden Seite beim nächsten Mal Masseflächen > vorhanden sind, so wie es sein sollte. also wenn das mit 32khz nicht funktioniert, ist das doch schon ein ziemlicher Nachteil des MSP430. ich achte bei meinen designs auch immer auf EMV, aber sowas muss bei 32khz schon möglich sein. >zu Deinem Problem: > Der Watchdog muss natürlich auch wieder eingeschaltet werden, > sprich WDTHOLD darf beim nächsten Befehl nicht gesetzt sein. aha, da könnte mein fehler noch liegen. Könntest du deinen Initcode mal posten? Wäre super! danke Jan
Hi Jan, die ersten Schritte mit dem MSP430 sind gemacht und das "Gerippe" für meine Applikation steht. Ich brauche eine relativ hohe quarzstabile Frequenz. Der Timer A ist durch eine PWM komplett belegt, d.h. ich muß auf den WDT-Timer im Intervall-Modus zurückgreifen. Statt einer FLL habe ich jedoch in Anlehnung an SLAA074 eine PLL gebastelt. Da diese bei mir alle 24kHz einrasten kann ist zunächst eine schnelle Auswahl des benötigten Frequenzbereichs nötig. Das Programmlauf sieht derzeit wie folgt aus: - Auf den LFXTCLK warten mittel TimerA, da kein OSC-Fault generiert wird. Dauert bei mir ca. 200ms! (Billigquarz) - Der WDT wird nun mit ACLK gespeist mit einer Periode von ca. 15ms. Timer A zählt nun DCO-Zyklen. - Die RSEl-Einstellungen werden (mit DCOCTL=0) so lange ausgehend vom Maximalwert verringert, bis eine zu geringe Frequenz ermittelt wird. - Danach kann es nur noch aufwärts gehen und eine passende Einstellung von DCOx und MODx wird mit successiver Approximation wiederum unter Verwendung von TMRA und des WDT ermittelt. - Danach geht die Kontrolle an die PLL über. Es wird dabei jeweils nur ein Frequenzschritt gemacht. Frage: Weiss jemand, ob die einzelnen RSel-Bereiche sich überlappen? Und wenn ja, was sind die passenden DCOCTL- Einstellungen? zum langsamen Anschwingen des Quarzes: bei mir ist das Ding jetzt stabil. Und Du willst doch auch "Low Power", oder? sorry, daß noch keine vernünftige Dokumentation vorhanden ist. Der Code kann sicherlich auch noch deutlich verbessert werden hinsichtlich der Größe, für mich reichts aber erstmal. Schreib kurz, wenn Du Fragen hast... Achja.. ist für GCC. bis dann, Jörg
ich habe auch ein Problem mit meinem 32kHz Quarz. Er schwingt mit relativ kleiner Amplitudenänderung, aber korrekter Frequenz. Ich habe ihn mit und ohne zusätzliche Kondensatoren angeschlossen (der MSP hat ja schon intern 12pF). Ich arbeite mit dem MSP430F1232, nutze den DCO bei max. Frequenz für MCLK und möchte den 32kHz für ACLK und zum synchronosieren nutzen. Den Schnippsel habe ich aus einem TI Beispiel. BCSCTL1 &= ~OSCOFF; do { IFG1 &= ~OFIFG; for (w = 0xff; w>0; w--); } while ((IFG1 & OFIFG) != 0); BCSCTL2 = 0x88; Leider komme ich nicht weiter, MSP verlässt die Schleife nicht. Gruß m@is
Hi, > Ich arbeite mit dem MSP430F1232, nutze den DCO bei max. > Frequenz für MCLK und möchte den 32kHz für ACLK und > zum synchronosieren nutzen. > Den Schnippsel habe ich aus einem TI Beispiel. > BCSCTL1 &= ~OSCOFF; meiner Meinung nach ist OSCOFF-Flag im Status Register und dient zur Einstellung des Low-Power modes (LPM4). An der Stelle im BCSCTL1 steht das höherwertige Bit des ACLK-Vorteilers (DIVA1), den Du hiermit löscht und den Teiler damit in Abhängigkeit von DIVA0 auf /1 oder /2 einstellst. > do { > IFG1 &= ~OFIFG; > for (w = 0xff; w>0; w--); > } > while ((IFG1 & OFIFG) != 0); bin ich auch zunächst drauf reingefallen. Da Du den 32kHz-Quarz verwendest wird der Oszillator im LFXT-Modus betrieben. Das Oszillator-Fault-Interrupt-Flag wird in diesem Modus nicht gesetzt, d.h. die CPU wartet sich einen Ast... > BCSCTL2 = 0x88; Hiermit wird auf XT2 (nicht präsent) für MCLK und SMCLK umgeschaltet. Die Zeile kannst Du rauswerfen, da diese Clocks defaultmäßig mit dem internen DCO laufen. Ich benutzt Timer A, um auf den LFXT-Quarz zu warten... Meine defines sind: #define DCO_FREQ 2457600 #define TAR_TICKS (DCO_FREQ/64) // with WDT: 38,4kHz/8192 #define DCO_SETTLE 20 // settle time for DCO #define LFXT_RETRY 40000 #define WDTCTL_INIT WDTPW|WDTCNTCL|WDTTMSEL|WDTIS1|WDTSSEL #define BCSCTL1_INIT XT2OFF|RSEL2|RSEL1|RSEL0 die Funktion die(xxx) blinkt xxx mal mit einer Leuchtdiode und hält die CPU bei Fehlern an. Momentan sieht mein Code so aus: [..schnipp..] u16 retry=LFXT_RETRY; // retry counter // wait for LFXT1CLK using Timer A TACTL = TASSEL0+MC1+TACLR; // start timer A using ACLK, // clear Interrupt flag WDTCTL = WDTPW|WDTCNTCL|WDTHOLD; // clear and stop // watchdogbefore interval // change do { retry--; // ACLK works if timer // starts counting; loop // ~10cycles } while ((TAR<4096)&&retry); // wait some clock cycles // or retry if (!retry) // timer A not working // -> die with postcode 4; die(PNOXT); // blink LED 8-) [...schnapp...] und dann weiter um den DCO auf eine definierte Startfrequenz zu stellen (laufende Synchronisation noch nicht fertig... aber Du kannst den Code aus SLAA074 nehmen, wenn Du Timer A frei hast): [...schnipp...] // since we have now a stable ACLK change // the WDT timer with 15,625ms period in // interval mode and use timer A in continous // mode to adjust DCO frequency. DCOCTL = 0x00; BCSCTL1 = BCSCTL1_INIT; // choose high frequency // range retry = 8; signed int adjust; do { retry--; if ((adjust=wdt_poll(DCO_SETTLE))<0) // timer A too fast? BCSCTL1 -=1; // yes -> decrease RSEL // value } while ((adjust<0)&&retry); // until DCO frequency // too low if (!retry) // R-Selection failed die(PNOPLL); // successive approximation for DCOCTL int i; for (i=15; i>=0;i--) { // process DCOx and MODx // Bits adjust = wdt_poll(DCO_SETTLE>>1); DCOCTL |= (1<<i); // try setting a higher // frequency if (adjust<0) { // too fast? DCOCTL &= ~(1<<(i+1)); // undo last frequency change } } [...schnapp...] was noch fehlt ist die Routine wdt_poll... diese hier ist für GCC (aufpassen mit TABs): [...schnipp...] int wdt_poll(u16 t_settle) { int adjust = 0; NOP_WAIT(t_settle); // stabilize clock // well well, gcc is too clever.. // force setting of TACTL(0x160) and WDTCTL(0x120) using // registers in a timely manner // force fast polling of WDT_Flag and capture of Timer A (0x170) asm (" mov %[wdc], &0x120 \n\t"\ " mov %[tac], &0x160 \n\t"\ " bic #1, &0x002 \n\t"\ " mov %[tic], %[adj] \n\t"\ "1: bit.b #1, &0x002 \n\t"\ " jz 1b \n\t"\ " sub &0x170, %[adj] \n\t"\ : [adj] "=r" (adjust)\ : [wdc] "i" (WDTCTL_INIT), [tac]"r"(TACLR+TASSEL1+MC1+ID0),[tic] "i" (TAR_TICKS>>1)); return adjust; } [...schnapp...] danach kann man Timer A wieder benutzen... WDT ist natürlich auch verkonfiguriert. Den DCO sollte mann gelegentlich wieder nachstellen... bin da aber noch dran. Achja, das "r" für [tac] ist kein Fehler... der Code oben funktioniert (im Gegensatz zu meinem vorherigen Posting 8-)) und ist getestet auf MSP430F1232... schreib mal, ob's geklappt hat oder wenn ich was vergessen haben sollte... 73, Jörg
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.