MSP430 32kHz Quarz / Crystal

32khz_02Vor ein paar Tagen habe ich einmal den mitgelieferten Quarz (Launchpad, MS3V-T1R) getestet und ein paar Messungen durchgeführt. Weiterhin wurde ein 32kHz Uhrenquarz von Pollin getestet (CFS-206). Eine kurze Einführung für die Benutzung eines 32kHz Quarz und die Initialisierung für den MSP430.

 

 

Wer es sich nicht zutraut den mitgelieferten Quarz auf das Launchpad zu löten, dem empfehle ich den Quarz von Pollin. Dieser lässt sich einfach an die Stiftleiste löten, oder per Buchsen anschließen. Der MSP430(G) hat zwei interene Ladekapazitäten CL1 und CL2, die per Software ausgewählt werden können (BSCTL3 Register -> ~1pF bis 12.5pF, siehe User-Guide). Es können aber auch externe Kondensatoren angeschlossen werden, falls nötig.

Daten mitgelieferter Quarz:

MS3V-T1R (32.768kHz)
Load Capacitance: 12.5pF
Frequency Tolerance:+/-20ppm (ppm=parts per million)
SMD Metal Package
Datasheet

32khz_01 32khz_02

Daten Uhrenquarz von Pollin:

CFS-206 (32.768 kHz)
Load Capacitance: 12,5 pF
Frequency Tolerance: +/-20ppm
Datasheet

32khz_uhr

(Diese Methode funktioniert zwar, ist aber nicht zu empfehlen, der Quarz muss so nah wie möglich am Controller gelötet werden)

Quarz Initialisierung

Wer sich näher mit der Thematik beschäftigen will, findet im UserGuide ab Seite 273 alle nötigen Informationen.

BCSCTL3|=XCAP_3;

do
{
    IFG1&=~OFIFG;
    __delay_cycles(1000);
}
while(IFG1&OFIFG);

In der ersten Zeile werden Einstellungen am BCSCTL3 Register (Basic Clock System Control Register 3) vorgenommen. Hier können die Frequenzen und Ladekapazitäten ausgewählt werden. In diesem Fall reicht es Bit 3-2 -> XCAP_3 (~12.5pF) zu setzen. XT2Sx (00 = 0.4 bis 1MHz) und LFXT1Sx (00 = 32768Hz LFXT1) sind standardmäßig nicht gesetzt. Im BCSCTL1 (Basic Clock System Control Register 1) ist standardmäßig das Bit XTS (0 = Low-frequency mode) nicht gesetzt. In diesem Register kann noch ein Vorteiler für ACLK ausgewählt werden (1,2,4,8), in diesem Fall werden die Bits DIVAx nicht gesetzt (00 = /1).

In der do-while Schleife wird zuerst das OFIFG (Oscillator fault interrupt flag) Bit im IFG1 Register (Interrupt Flag Register 1) auf 0 gesetzt (no interrupt pending). Danach wird 1000 Zyklen gewartet (Einschwingzeit, sollte vielleicht höher sein ~10ms) und geprüft ob das OFIFG Bit immer noch gesetzt ist. Falls ja, wird nochmal gewartet.

Timer-Initialisierung

Als CLK-Source für den TImer soll der 32kHz Quarz dienen.

TACTL|=TASSEL_1+ID_0; //ACLK, 1x divider

Im TACTL Register werden die Bits TASSEL_1 (01 = ACLK) gesetzt und der Vorteiler bleibt auf “/1” (nicht nötig ID_0 zu schreiben). In diesem Fall entsprechen 32768 Zyklen genau eine Sekunde ( (32768Hz*1,0s)/1=32768).

Messung

Im Test-Programm blinkt eine LED mit 2Hz (250ms ON, 250ms OFF => T=500ms => f=2Hz). Benutzt wurde der mitgelieferte Quarz (SMD Metal Package).

Auto-Measurement (P1.6, LED)

32khz_auto

Manuell (P1.6, LED)

32khz_manuell

Auto-Measurement (ACLK, P1.0)

32khz_aclk

C-Programm

FILE: main.c

/*************************************************
 *     ___       _             _     
 *    |   |_ _ _| |___ ___   _| |___
 *    | | |_'_| . | -_|  _|_| . | -_|
 *    |___|_,_|___|___|___|_|___|___|
 *
 * FILE:     main.c
 * Author:   declis (xdec.de)
 ************************************************/

#include <msp430g2231.h>
#include "timer.h"

void main(void)
{
    WDTCTL=WDTPW+WDTHOLD;       // stop watchdog timer
    BCSCTL1=CALBC1_1MHZ;
    DCOCTL=CALDCO_1MHZ;
    BCSCTL3|=XCAP_3;

    do
    {
        IFG1&=~OFIFG;
        __delay_cycles(1000);
    }
    while(IFG1&OFIFG);

    P1DIR|=BIT6;                //P1.6 (LED2) -> output
    P1OUT&=~BIT6;               //clear P1.6 (LED2 off)
    P1SEL|=BIT0;                //ACLK on P1.0
    P1DIR|=BIT0;

    init_TimerA();              //initialize TimerA
    _EINT();                    //enable interrupt

    while(1);
}

FILE: timer.c

/*************************************************
 *     ___       _             _     
 *    |   |_ _ _| |___ ___   _| |___
 *    | | |_'_| . | -_|  _|_| . | -_|
 *    |___|_,_|___|___|___|_|___|___|
 *
 * FILE:     timer.c
 * Author:   declis (xdec.de)
 ************************************************/

#include <msp430g2231.h>
#include "timer.h"

#define cycles 8192         // 250ms ACLK=32kHz Quarz
//#define cycles 31250      // 250ms SMCLK=1MHz

/* cycles=(seconds*Frequency_Hz)/divider */
/* seconds=(divider*cycles)/Frequency_Hz  */
void init_TimerA(void)
{
    TACTL|=TASSEL_1+ID_0;   // ACLK, 1x divider
    //TACTL|=TASSEL_2+ID_3; // SMCLK, 8x divider
    TACCR0=cycles;
    TACCTL0|=CCIE;          // enable TimerA interrupt
    TACTL|=MC_1;            // start timer in up-mode
}

/* Timer_A ISR */
#pragma INTERRUPT (ISR_TimerA);
#pragma vector=TIMERA0_VECTOR
void ISR_TimerA(void)
{
    P1OUT^=BIT6;        // toggle P1.6
}

FILE: timer.h

/*************************************************
 *     ___       _             _     
 *    |   |_ _ _| |___ ___   _| |___
 *    | | |_'_| . | -_|  _|_| . | -_|
 *    |___|_,_|___|___|___|_|___|___|
 *
 * FILE:     timer.h
 * Author:   declis (xdec.de)
 ************************************************/

#ifndef TIMER_H_
#define TIMER_H_

void init_TimerA(void);

#endif /*TIMER_H_*/

Leave a Reply

Your email address will not be published. Required fields are marked *

This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

This site uses Akismet to reduce spam. Learn how your comment data is processed.