//****************************************************************************** // MSP430x21x1 Demo - Basic Clock, Implement Auto RSEL SW FLL // // Description: Set DCO clock to (Delta)*(4096) using software FLL. DCO clock // is output on P1.4 as SMCLK. DCO clock, which is the selected SMCLK source // for Timer_A is integrated over LFXT1/8 (4096) until SMCLK is is equal // to Delta. CCR2 captures ACLK. To use, Set_DCO Timer_A must be // operating in continuous mode. Watch crystal for ACLK is required for // this example. Delta must be kept in a range that allows possible // DCO speeds. Minimum Delta must ensure that Set_DCO loop can complete // within capture interval. Maximum delta can be calculated be // f(DCOx7) / 4096. f(DCOx7) can be found in device specific datasheet. // ACLK = LFXT1/8 = 32768/8, MCLK = SMCLK = target DCO // [] To measure SMCLK on P1.4 with the FET, use "Release JTAG on Go" // in the debugger to have access to the port. Then run the code. // //* External watch crystal installed on XIN XOUT is required for ACLK *// / H. Grewal / A. Dannenberg // Texas Instruments Inc. // June 2005 // Built with IAR Embedded Workbench Version: 3.30A //****************************************************************************** //****************************************************************************** // MSP43021x1時鐘校準,21x1出廠時,在Info Flash保存了四種時鐘的調(diào)整參數(shù) // 分別是 1MHz,8MHz,12MHz,16MHz // 由于用戶在下載程序的時候,會將Info Flash擦除,或芯片出廠校準參數(shù)不正確 // 就需要用戶自己校準時鐘。 // 有兩種方法可以校準系統(tǒng)時鐘,1;在用戶程序初始化時校準, // 2: 單獨運行校準程序,將校準參數(shù)保存到InfoFlash // 中,用戶程序直接調(diào)用。由于21X1系列的內(nèi)部時鐘 // 精度在整個溫度范圍內(nèi)已經(jīng)達到了2.5%,因此可以 // 用這種方法,減少應用程序占用Flash。 // 要保證CPU供電在3。3V以上 // // 毛武斌 // 杭州冰河奧特使電子有限公司 // 2006.3.23 // 本程序由TI的例子程序修改而來,使用IAREW430 V3。40A //******************************************************************************
//------------------------------------------------------------------------------ void Set_DCO (unsigned int delta, char *pBcsctl1_, char *pDcoct_) // Set DCO to selected frequency //------------------------------------------------------------------------------ { unsigned int Compare, Oldcapture = 0;
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); }