// Clock4
// Calibrates DCO synced to 32.768 KHz crystal (8MHz)
// MSP430G25531
// Jed Margolin 3/14/2016.
// Built with Code Composer Studio v6
//***************************************************************************************
// main.c
#include <msp430.h>
//#include <msp430G2211.h>
#define DELTA_1MHZ 244 // 244 x 4096Hz = 999.4Hz
#define DELTA_8MHZ 1953 // 1953 x 4096Hz = 7.99MHz
#define DELTA_12MHZ 2930 // 2930 x 4096Hz = 12.00MHz
#define DELTA_16MHZ 3906 // 3906 x 4096Hz = 15.99MHz
#define TIME 100
#define DCOUNT 8
void wait(unsigned int);
void wait2(void);
void Set_DCO(unsigned int Delta);
//================================================
int main(void)
{
unsigned char caldata1, caldata2; // Temp. storage for constants
volatile unsigned int k = 0;
WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer
wait(150); // give the crystal 500ms to stabilize
P1SEL |= BIT0; // ACLK
P1SEL2 &= ~(BIT0);
P1DIR |= BIT0;
P1SEL &= BIT1; // In
P1SEL2 |= BIT1; // not used by msp430g2211
P1REN |= BIT1; // pullup/pulldown enabled
P1OUT |= BIT1; //
P1DIR &= ~(BIT1); // In
P1SEL &= ~(BIT2); // Out
P1SEL2 &= ~(BIT2); // not used by msp430g2211
P1DIR |= BIT2; //
P1SEL &= ~(BIT3); // Out - for testing
P1SEL2 &= ~(BIT3); // not used by msp430g2211
P1DIR |= BIT3; //
P1SEL |= BIT4; // Out for SMCLK so we know it's working
P1SEL2 &= ~(BIT4); // not used by msp430g2211
P1DIR |= BIT4; //
P1SEL &= ~(BIT5); // In
P1SEL2 &= ~(BIT5); // not used by msp430g2211
P1REN |= BIT5; // pullup/pulldown enabled
P1OUT |= BIT5; // pullup
P1DIR &= ~(BIT5); //
P1SEL &= ~(BIT6); // Out
P1SEL2 &= ~(BIT6); // not used by msp430g2211
// P1REN |= BIT6; // pullup/pulldown enabled
// P1OUT |= BIT6; // pullup
P1DIR |= (BIT6); //
P1SEL &= ~(BIT7); // In
P1SEL2 &= ~(BIT7); // not used by msp430g2211
P1REN |= BIT7; // pullup/pulldown enabled
P1DIR &= ~(BIT7); // In
P1OUT |= BIT7; // pullup
// Lock the DCO to the 32768 crystal - 8 MHz
Set_DCO(DELTA_8MHZ); // Set DCO and obtain constants
caldata1 = DCOCTL; // for debugging
caldata2 = BCSCTL1;
while (1) // main loop
{
P1OUT |= BIT6;
wait(TIME);
P1OUT &= ~(BIT6);
wait(TIME);
} // end while main loop
} // end main
//==================================
void wait(unsigned int time) // 500 uS
{
volatile unsigned int i,j;
for(i=time; i>0; i--)
{
for(j=382; j>0; j--);
{
}
}
return;
}
//==========================================================
//==========================================================
void wait2()
{
volatile unsigned int i;
for(i=0; i<48; i++){}
return;
}
//========================================================
void Set_DCO(unsigned int Delta) // Set DCO to selected frequency
{
unsigned int Compare, Oldcapture = 0;
BCSCTL1 |= DIVA_3; // ACLK = LFXT1CLK/8
TACCTL0 = CM_1 + CCIS_1 + CAP; // CAP, ACLK
TACTL = TASSEL_2 + MC_2 + TACLR; // SMCLK, cont-mode, clear
while (1)
{
while (!(CCIFG & TACCTL0)); // Wait until capture occured
TACCTL0 &= ~CCIFG; // Capture occured, clear flag
Compare = TACCR0; // Get current captured SMCLK
Compare = Compare - Oldcapture; // SMCLK difference
Oldcapture = TACCR0; // Save current captured SMCLK
if (Delta == Compare)
break; // If equal, leave "while(1)"
else if (Delta < Compare)
{
DCOCTL--; // DCO is too fast, slow it down
if (DCOCTL == 0xFF) // Did DCO roll under?
if (BCSCTL1 & 0x0f)
BCSCTL1--; // Select lower RSEL
}
else
{
DCOCTL++; // DCO is too slow, speed it up
if (DCOCTL == 0x00) // Did DCO roll over?
if ((BCSCTL1 & 0x0f) != 0x0f)
BCSCTL1++; // Sel higher RSEL
}
}
TACCTL0 = 0; // Stop TACCR0
TACTL = 0; // Stop Timer_A
BCSCTL1 &= 0xCF; // ACLK = LFXT1CLK, DIV 1
}
//=================================================================