UCS_initFLL函数定义如下:
fsystem is the target frequency for MCLK in kHz
ratio is the ratio x/y, where x = fsystem and y = FLL reference frequency.
void UCS_initFLL(uint16_t fsystem,
uint16_t ratio)
{
uint16_t d, dco_div_bits;
uint16_t mode = 0;
//Save actual state of FLL loop control, then disable it. This is needed to
//prevent the FLL from acting as we are making fundamental modifications to
//the clock setup.
uint16_t srRegisterState = __get_SR_register() & SCG0;
d = ratio;
//Have at least a divider of 2
dco_div_bits = FLLD__2;
if(fsystem > 16000)
{
d >>= 1;
mode = 1;
}
else
{
//fsystem = fsystem * 2
fsystem <<= 1;
}
while(d > 512)
{
//Set next higher div level
dco_div_bits = dco_div_bits + FLLD0;
d >>= 1;
}
// Disable FLL
__bis_SR_register(SCG0);
//Set DCO to lowest Tap
HWREG8(UCS_BASE + OFS_UCSCTL0_H) = 0x0000;
//Reset FN bits
HWREG16(UCS_BASE + OFS_UCSCTL2) &= ~(0x03FF);
HWREG16(UCS_BASE + OFS_UCSCTL2) = dco_div_bits | (d - 1);
if(fsystem <= 630) //fsystem < 0.63MHz
{
HWREG8(UCS_BASE + OFS_UCSCTL1) = DCORSEL_0;
}
else if(fsystem < 1250) //0.63MHz < fsystem < 1.25MHz
{
HWREG8(UCS_BASE + OFS_UCSCTL1) = DCORSEL_1;
}
else if(fsystem < 2500) //1.25MHz < fsystem < 2.5MHz
{
HWREG8(UCS_BASE + OFS_UCSCTL1) = DCORSEL_2;
}
else if(fsystem < 5000) //2.5MHz < fsystem < 5MHz
{
HWREG8(UCS_BASE + OFS_UCSCTL1) = DCORSEL_3;
}
else if(fsystem < 10000) //5MHz < fsystem < 10MHz
{
HWREG8(UCS_BASE + OFS_UCSCTL1) = DCORSEL_4;
}
else if(fsystem < 20000) //10MHz < fsystem < 20MHz
{
HWREG8(UCS_BASE + OFS_UCSCTL1) = DCORSEL_5;
}
else if(fsystem < 40000) //20MHz < fsystem < 40MHz
{
HWREG8(UCS_BASE + OFS_UCSCTL1) = DCORSEL_6;
}
else
{
HWREG8(UCS_BASE + OFS_UCSCTL1) = DCORSEL_7;
}
// Re-enable FLL
__bic_SR_register(SCG0);
while(HWREG8(UCS_BASE + OFS_UCSCTL7_L) & DCOFFG)
{
//Clear OSC flaut Flags
HWREG8(UCS_BASE + OFS_UCSCTL7_L) &= ~(DCOFFG);
//Clear OFIFG fault flag
HWREG8(SFR_BASE + OFS_SFRIFG1) &= ~OFIFG;
}
// Restore previous SCG0
__bis_SR_register(srRegisterState);
if(mode == 1)
{
//fsystem > 16000
//Select DCOCLK
HWREG16(UCS_BASE + OFS_UCSCTL4) &= ~(SELM_7 + SELS_7);
HWREG16(UCS_BASE + OFS_UCSCTL4) |= SELM__DCOCLK + SELS__DCOCLK;
}
else
{
//Select DCODIVCLK
HWREG16(UCS_BASE + OFS_UCSCTL4) &= ~(SELM_7 + SELS_7);
HWREG16(UCS_BASE + OFS_UCSCTL4) |= SELM__DCOCLKDIV + SELS__DCOCLKDIV;
}
}
如果想将32768Hz做为源生成16MHz的主频,调用
UCS_initFLLSettle(16000, 488);时
执行HWREG16(UCS_BASE + OFS_UCSCTL2) = dco_div_bits | (d - 1);后
UCSCTL2 中 FLLD 为2分频,FLLN 为487(488倍频),
则fsystem = 32768*488/2 =8MHz,并不是16MHz,
不知道我哪里分析错了,求指教。