Hallo, im Datenblatt der MSP430 uCs steht in der allgemeinen Beschreibung, dass die Taktversorgung auch aus einer externen Taktquelle (z.B. externer Quarzoszillator) erfolgen kann. Allerdings kann ich in den Detailbeschreibungen nichts über diesen Anwendungsfall finden, weder, wo diese Quelle angeklemmt wird, noch wie in diesem Fall die Steuerregister konfiguriert werden müssen. Ich habe jetzt mal angenommen, dass der Takt an XIN angeschlossen wird und Xout dann offen bleibt. Stimmt dass so? Hat schon mal jemand eine entsprechende Schaltung aufgebaut und kann mir etwas über die Registerkonfiguration berichten?
Hi, Takt (bis 8Mhz) kannst du an X2IN anschließen. Der Code sieht dann so aus: WDTCTL = WDTPW + WDTHOLD; // Disable Watchdog BCSCTL1 &= ~XT2OFF; // Turn on XT2 (8MHz) // wait until crystal sattled do { IFG1 &= ~OFIFG; for (i = 0; i < 1000; i++) _NOP(); } while(IFG1 & OFIFG); BCSCTL2 |= SELM_2 + SELS; // XT2 is used for MCLK and SMCLK
>Ich habe jetzt mal angenommen, dass der Takt an XIN angeschlossen wird >und Xout dann offen bleibt. Stimmt dass so? Wenn Du einen Oszillator meinst und nicht "nur" einen Quarz... JA! >Registerkonfiguration Dieselbe, wie für einen Quarz.
Die Initialisierung mit Warteschleife von michiB braucht man bei einem externen Oszillator natürlich nicht. Nur die Register passend beschreiben und gut. Die Konfiguration ist die gleiche, wie mit Quarz. Ich hab immer einen 32,768kHz TCXO von Epson an XIN für den ACLK, klappt bestens, muss man gar nix einstellen.
Danke schon mal für die schnellen Antworten. Eine Frage hätte ich noch: Wenn mein Taktsignal Rechteckform hat, wie kann ich dann sicherstellen, dass der uC wirklich die Grundfrequenz und nicht eine Oberwelle als Taktquelle benutzt? Wäre es evtl. sinnvoll, ein RC-Glied zwischen Taktgeber und MSP430 zu schalten?
>Die Initialisierung mit Warteschleife von michiB braucht man bei einem >externen Oszillator natürlich nicht. Wieso denn nicht? Auch ein Oszillator muss sich einschwingen! >Wenn mein Taktsignal Rechteckform hat, wie kann ich dann sicherstellen, >dass der uC wirklich die Grundfrequenz und nicht eine Oberwelle als >Taktquelle benutzt? Passt schon! >Wäre es evtl. sinnvoll, ein RC-Glied zwischen >Taktgeber und MSP430 zu schalten? Nein, braucht es nicht!
Stefan wrote: >>Die Initialisierung mit Warteschleife von michiB braucht man bei einem >>externen Oszillator natürlich nicht. > Wieso denn nicht? > Auch ein Oszillator muss sich einschwingen! Sicher, aber der ist ja schon vorher aktiviert. Mit Start der Betriebsspannung liegt der externe Oszillator ja an Spannung und startet. Die Verzögerung ist nur für den internen Oszillator, wen man mit BCSCTL1 &= ~XT2OFF; aktiviert zuständig. Klar muss man aufpassen, dass der auch stabil ist, wenn man ihn dann aktiviert, aber in aller Regel ist der dann längst hochgefahren. Zumal am MSP430 ja sowieso ein kleiner Reset-Schaltkreis mit Verzögerung dran sollte (TPS3838). Je nachdem, wo im Programm dann der Oszillator aktiviert wird, kann es natürlich passieren, dass der Oszillator noch nicht stabil ist, das ist aber im Einzelfall zu klären.
Christian wrote: >> Auch ein Oszillator muss sich einschwingen! >Sicher, aber der ist ja schon vorher aktiviert. Das lese ich hier nirgends raus! >Mit Start der Betriebsspannung liegt der externe Oszillator ja an Spannung Genau wie der µC! >aber in aller Regel ist der dann längst hochgefahren. hmm..., da würde ich jetzt nicht drauf wetten! Ich würde mal sagen, das bisschen Warteschleife verschwendet weder Unmegen an Codespeicher noch an Rechenleistung. Also zur Sicherheit würde ich's deshalb immer reinmachen! >Zumal am MSP430 ja sowieso ein kleiner Reset-Schaltkreis mit Verzögerung dran >sollte (TPS3838). Auch so'ne endlose Diskussion... vielleicht auch Geschmackssache. Ich habe jedenfalls mit meinen MSP's mit BOR nie mehr Reset-Probleme gehabt, auch ohne externen Reset-Schaltkreis!
Hallo, mittlerweile habe ich doch ein bisschen Information im "Familienhandbuch" bei TI gefunden und habe mir die Initialisierung folgendermaßen zusammengebastelt: //---------------------------------------------------------------------- --------------------- // initialisiert den MSP430F2274 // // Uebergabe : keine // Rueckgabe : keine // Verwendete globale Variablen : keine // aufgerufene Funktionen : keine // Beeinflusste Register : WDTCTL : Watchdog // BCSCTL1 : Basic Clock System Control 1 // BCSCTL2 : Basic Clock System Control 2 // BCSCTL3 : Basic Clock System Control 3 //---------------------------------------------------------------------- --------------------- void msp_init(void) { int i; WDTCTL = WDTPW + WDTHOLD; // halte watchdog an BCSCTL1 |= XTS; // ACLK = LFXT1 = HF XTAL BCSCTL2 = 0x0c8; // initialisiere auf externen Takt mit 8 MHz BCSCTL3 |= LFXT1S_3; // und initialisiere Oszilatoren do { IFG1 & ~OFIFG; // loesche OSCFault Flag for (i=0; i<256; i++) _NOP(); // Zeit zum setzen des Flags } while((IFG1) & OFIFG != 0); // warte, bis externer Quars angeschwungen (OSCFault Flag noch gesetzt?) P1DIR |= 0x01; // Set P1.0 to output direction } Sieht das soweit OK aus? Testen kann ich das Programm leider erst, wenn mein Entwicklungskit eingetrudelt ist. P.S. Wie war nochmal der Befehl zur Codedarstellung im Forum?
Das ist bissl verkehrt rum. Du musst erst warten, bis das Oszillator stabil ist und dann die Takte umschalten. Solange der Oszillaor sein Fault-Flag gesetzt hat, musst du noch mit dem DCO-Takt arbeiten. Außerdem musst du vorher die Zweitfunktion für den Quarz-Eingang aktivieren, beim F2274 ist das meines Wissens sonst ein normaler I/O.
>P.S. Wie war nochmal der Befehl zur Codedarstellung im Forum? [ c ] ... [ /c ] ohne die Leerzeichen! >BCSCTL2 = 0x0c8; Gewöhne Dir besser mal an, konsequent die Register- / Bit-Definitionen aus dem Headerfile deines MSP's zu verwenden! Also:
1 | BCSCTL2 = SELM_3 + SELS; |
Macht den Code wesentlich besser lesbar und fördert eine erfolgreiche Fehlersuche, falls nötig ;-) >...Sieht das soweit OK aus? Nö! Warum schaust Du Dir nicht mal die Code-Beispiele von TI für Deinen F22x4 an? Christian wrote: >Außerdem musst du vorher die Zweitfunktion für den Quarz-Eingang >aktivieren, beim F2274 ist das meines Wissens sonst ein normaler I/O. Nö, muss man nicht. P2SEL = 0xC0 nach PUC. D.h. die "Oszillatorfunktion" für P2.6/2.7 ist standardmäßig schon aktiv!
OK, ich habe meine Denkfehler jetzt hoffentlich alle korrigiert und mir auch noch einmal die Beispiele aus slac123 angesehen (bei denen leider keine mit externer Taktversorgung dabei sind). Sieht der Code jetzt besser aus?
1 | void msp_init(void) |
2 | {
|
3 | unsigned int i; |
4 | |
5 | WDTCTL = WDTPW + WDTHOLD; // halte watchdog an |
6 | BCSCTL1 |= XTS; // ACLK = LFXT1 = HF XTAL |
7 | BCSCTL3 |= LFXT1S_3; // ext. Taktquelle fuer LFXT1 |
8 | BCSCTL3 &= ~XCAP0; // XCAP ~ 1pF |
9 | do { |
10 | IFG1 &= ~OFIFG; // loesche OSCFault Flag |
11 | for (i=0; i<256; i++) _NOP(); // Zeit zum setzen des Flags |
12 | } while((IFG1) & OFIFG != 0); // warte, bis externer Quars angeschwungen (OSCFault Flag noch gesetzt?) |
13 | BCSCTL2 = SELM_3 + SELS; // schalte auf externen Takt |
14 | }
|
>Beispiele aus slac123 angesehen (bei denen leider >keine mit externer Taktversorgung dabei sind) Aber sicher: "msp430x22x4_hfxtal.c", "msp430x22x4_hfxtal_nmi.c" >Sieht der Code jetzt besser aus? Ja, bis auf die Klammern in der while-Schleife:
1 | while((IFG1) & OFIFG != 0); --> while((IFG1 & OFIFG) != 0); |
Das _NOP() kannst Du auch weglassen, stört aber auch nicht!
Hallo Stefan, danke nochmal für die Korrektur. Das mit dem nop stand irgendwo in der Compilerbeschreibung, um wegoptimieren zu verhindern. Die genannten Beispiele beziehen sich aber auf externe Quarze, nicht auf externe Oszillatoren.
>Die genannten Beispiele beziehen sich aber auf externe Quarze, nicht auf >externe Oszillatoren. Die Frage hatten wir schon zu Anfang geklärt, dem MSP ist das wurscht! Noch ein Hinweis im Allgemeinen: Bei (Warte-)Schleifen, die eine Bedingung abfragen, müssen immer die Alarmglocken läuten und man muss sich fragen, was passiert wenn die Bedingung nie erfüllt wird! Ansonsten endet man in einer Endlosschleife. Im speziellen Fall also, wenn z.B. der Quarz/Oszillator defekt sein sollte. Du könntest als Übung mal versuchen, in die "do-while" einen Timeout einzubauen, der nach einer definierten Zeit dem Drama ein Ende setzt und entweder einen Fehler ausgibt (LED-Blinken oder was auch immer) oder als fall-back mit dem DCO weiterarbeitet.
Die Endlosschleife ist hier erwünscht, wenn nämlich der Oszillator defekt ist, funktioniert auch der Rest der Schaltung nicht, dann ist es egal, was der uC macht, da er sich dann nicht betriebsbereit melden kann. Im Rest vom Programm werden Endlosschleifen verhindert.
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.