1. Background:
A long time not updated blog, recently due to project requirements, simple use of 430 interface, but because the internal default can use 1MHz frequency cannot meet the demand;
2. Function:
The reference manual found that the film supports DCO multiplier, the frequency can be up to 16M, verified to meet the needs;
3, the premise:
External 32K crystal Oscillator is required as the correction frequency;
4. See the code below: #include <msp430.h>
32khz/8=4096hz, thus calculating octave # # 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
unsigned char cal_data[8]; Temp. Storage for constants
volatile unsigned int i;
Int J;
Char *flash_ptra; Segment A Pointer
void Set_dco (unsigned int Delta);
int main (void)
{
Wdtctl = Wdtpw + wdthold; Stop WDT
for (i = 0; i < 0xFFFE; i++); Delay for XTAL Stabilization
P1out = 0x00; Clear P1 Output Latches
P1sel = 0x10; P1.4 SMCLK Output
P1dir = 0x11; p1.0,4 output
j = 0; Reset pointer
Set_dco (Delta_16mhz); Set DCO and obtain constants
Cal_data[j++] = Dcoctl;
Cal_data[j++] = BCSCTL1;
Set_dco (Delta_12mhz); Set DCO and obtain constants
Cal_data[j++] = Dcoctl;
Cal_data[j++] = BCSCTL1;
Set_dco (Delta_8mhz); Set DCO and obtain constants
Cal_data[j++] = Dcoctl;
Cal_data[j++] = BCSCTL1;
Set_dco (Delta_1mhz); Set DCO and obtain constants
Cal_data[j++] = Dcoctl;
Cal_data[j++] = BCSCTL1;
Flash_ptra = (char *) 0x10c0; Point to beginning of seg A
FCTL2 = Fwkey + FSSEL0 + FN1; MCLK/3 for Flash Timing Generator
FCTL1 = Fwkey + ERASE; Set Erase Bit
FCTL3 = Fwkey + Locka; Clear LOCK & Locka Bits
*flash_ptra = 0x00; Dummy write to erase Flash seg A
FCTL1 = Fwkey + WRT; Set WRT bit for write operation
Flash_ptra = (char *) 0x10f8; Point to beginning of Cal Consts
for (j = 0; J < 8; J + +)
*flash_ptra++ = Cal_data[j]; Re-flash DCO Calibration Data
FCTL1 = Fwkey; Clear WRT Bit
FCTL3 = Fwkey + Locka + LOCK; Set LOCK & Locka Bit
while (1)
{
P1out ^= 0x01; Toggle LED
for (i = 0; i < 0x4000; i++); SW Delay
}
}
Calculate multiplier Frequency
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)/do DCO roll under?
if (BCSCTL1 & 0x0f)
bcsctl1--; Select Lower Rsel
}
Else
{
dcoctl++; DCO is too slow
if (Dcoctl = = 0x00)/do DCO roll over?
if ((BCSCTL1 & 0x0f)! = 0x0f)
bcsctl1++; Sel Higher Rsel
}
}
TACCTL0 = 0; Stop TACCR0
Tactl = 0; Stop timer_a
BCSCTL1 &= ~diva_3; ACLK = LFXT1CLK
}