MSP43021x1时钟校准

来源:本站
导读:目前正在解读《MSP43021x1时钟校准》的相关信息,《MSP43021x1时钟校准》是由用户自行发布的知识型内容!下面请观看由(电工技术网 - www.9ddd.net)用户发布《MSP43021x1时钟校准》的详细说明。
简介:MSP43021x1时钟校准

//******************************************************************************

//MSP43021x1时钟校准,21x1出厂时,在Info Flash保存了四种时钟的调整参数

// 分别是 1MHz,8MHz,12MHz,16MHz

// 由于用户在下载程序的时候,会将Info Flash擦除,或芯片出厂校准参数不正确

// 就需要用户自己校准时钟。

// 有两种方法可以校准系统时钟,1;在用户程序初始化时校准,

// 2: 单独运行校准程序,将校准参数保存到InfoFlash

// 中,用户程序直接调用。由于21X1系列的内部时钟

// 精度在整个温度范围内已经达到了2.5%,因此可以

// 用这种方法,减少应用程序占用Flash。

// 要保证CPU供电在3。3V以上

//

// 毛武斌

// 杭州冰河奥特使电子有限公司

// 2006.3.23

// 本程序由TI的例子程序修改而来,使用IAREW430 V3。40A

//******************************************************************************

#include <MSP430x21x1.h>

#define DELTA_1M 245

#define DELTA_8M 1954

#define DELTA_12M 2930

#define DELTA_16M 3906

char *pInfoFlash_A;

char AdjBCSCTL1_1M;

char AdjpDCOCTL_1M;

char AdjBCSCTL1_8M;

char AdjpDCOCTL_8M;

char AdjBCSCTL1_12M;

char AdjpDCOCTL_12M;

char AdjBCSCTL1_16M;

char AdjpDCOCTL_16M;

char tmpBCSCTL1;

char tmpDCOCTL;

void Set_DCO (unsigned int delta, char *pBcsctl1_, char *pDcoct_);

void softwareDelay(unsigned int time);

void timeAdelay(unsigned int time);

void main(void)

{

WDTCTL = WDTPW + WDTHOLD;// Stop WDT

// 测试时钟输出

P1OUT = 0;

P1DIR |= BIT3 + BIT4;; // P1.3,4 output

P1SEL |= BIT4; // P1.4 SMCLK output

_DINT();

tmpBCSCTL1 = BCSCTL1;

tmpDCOCTL = DCOCTL;

Set_DCO(DELTA_1M, &AdjBCSCTL1_1M, &AdjpDCOCTL_1M);

Set_DCO(DELTA_8M, &AdjBCSCTL1_8M, &AdjpDCOCTL_8M);

Set_DCO(DELTA_12M, &AdjBCSCTL1_12M, &AdjpDCOCTL_12M);

Set_DCO(DELTA_16M, &AdjBCSCTL1_16M, &AdjpDCOCTL_16M);

BCSCTL1 = tmpBCSCTL1;

DCOCTL = tmpDCOCTL;

FCTL2 = FWKEY + FSSEL0 + FN1;// MCLK/3 for Flash Timing Generator

FCTL1 = FWKEY + ERASE; // Set Erase bit, allow interrupts

if(FCTL3 & LOCKA)

{

FCTL3 = FWKEY + LOCKA; // Clear LOCK & LOCKA bits

}

pInfoFlash_A = (char *) 0x10C0; // Initialize Flash pointer

*pInfoFlash_A = 0; // Dummy write to erase Flash segment A

FCTL1 = FWKEY + WRT; // Set WRT bit for write operation

pInfoFlash_A = (char *) CALDCO_16MHZ_; // Initialize Flash pointer

*pInfoFlash_A++ = AdjpDCOCTL_16M;

*pInfoFlash_A++ = AdjBCSCTL1_16M;

*pInfoFlash_A++ = AdjpDCOCTL_12M;

*pInfoFlash_A++ = AdjBCSCTL1_12M;

*pInfoFlash_A++ = AdjpDCOCTL_8M;

*pInfoFlash_A++ = AdjBCSCTL1_8M;

*pInfoFlash_A++ = AdjpDCOCTL_1M;

*pInfoFlash_A = AdjBCSCTL1_1M;

FCTL1 = FWKEY; // Clear WRT bit

FCTL3 = FWKEY + LOCKA + LOCK; // Set LOCK & LOCKA bit // Set LOCK bit

P1OUT |= BIT3;

for (;;)

{ // 隔四秒钟输出SMCLK

BCSCTL1 = CALBC1_1MHZ;

DCOCTL = CALDCO_1MHZ;

timeAdelay(2);

P1OUT ^= BIT3;

softwareDelay(50000);

P1OUT ^= BIT3;

BCSCTL1 = CALBC1_8MHZ;

DCOCTL = CALDCO_8MHZ;

timeAdelay(2);

P1OUT ^= BIT3;

softwareDelay(50000);

P1OUT ^= BIT3;

BCSCTL1 = CALBC1_12MHZ;

DCOCTL = CALDCO_12MHZ;

timeAdelay(2);

P1OUT ^= BIT3;

softwareDelay(50000);

P1OUT ^= BIT3;

BCSCTL1 = CALBC1_16MHZ;

DCOCTL = CALDCO_16MHZ;

timeAdelay(2);

P1OUT ^= BIT3;

softwareDelay(50000);

P1OUT ^= BIT3;

}

}

//------------------------------------------------------------------------------

void Set_DCO (unsigned int delta, char *pBcsctl1_, char *pDcoct_)// Set DCO to selected frequency

//------------------------------------------------------------------------------

{

unsigned int Compare, Oldcapture = 0;

BCSCTL1 |= DIVA_3;// ACLK= LFXT1CLK/8

BCSCTL3 |= XCAP_3;

CCTL2 = CM_1 + CCIS_1 + CAP;// CAP, ACLK

TACTL = TASSEL_2 + MC_2 + TACLR;// SMCLK, cont-mode, clear

while (1)

{

while (!(CCIFG & CCTL2)); // Wait until capture occured

CCTL2 &= ~CCIFG;// Capture occured, clear flag

Compare = CCR2; // Get current captured SMCLK

Compare = Compare - Oldcapture;// SMCLK difference

Oldcapture = CCR2;// Save current captured SMCLK

if (delta == Compare) break;// If equal, leave "while(1)"

else if (delta < Compare)// DCO is too fast, slow it down

{

DCOCTL--;

if (DCOCTL == 0xFF)

{

if (!(BCSCTL1 == (XT2OFF + DIVA_3)))

BCSCTL1--; // Did DCO roll under?, Sel lower RSEL

}

}

else

{

DCOCTL++;

if (DCOCTL == 0x00)

{

if (!(BCSCTL1 == (XT2OFF + DIVA_3 + 0x0F)))

BCSCTL1++; // Did DCO roll over? Sel higher RSEL

}

}

softwareDelay(20);

}

CCTL2 = 0; // Stop CCR2

TACTL = 0; // Stop Timer_A

*pBcsctl1_ = BCSCTL1 & (~DIVA_3);

*pDcoct_ = DCOCTL;

}

void softwareDelay(unsigned int time)

{

while(--time);

}

void timeAdelay(unsigned int time)

{

TACTL = TASSEL_1 + MC_2 + TACLR;// SMCLK, cont-mode, clear

while(time)

{

while(!(TACTL &TAIFG));

TACTL &= ~TAIFG;

time--;

}

TACTL = 0;

}

提醒:《MSP43021x1时钟校准》最后刷新时间 2024-03-14 01:13:46,本站为公益型个人网站,仅供个人学习和记录信息,不进行任何商业性质的盈利。如果内容、图片资源失效或内容涉及侵权,请反馈至,我们会及时处理。本站只保证内容的可读性,无法保证真实性,《MSP43021x1时钟校准》该内容的真实性请自行鉴别。