官方例程如下:
void InitPll(Uint16 val, Uint16 divsel)
{
//
// Make sure the PLL is not running in limp mode
//
if (SysCtrlRegs.PLLSTS.bit.MCLKSTS != 0) //检测到时钟信号不好,直接退出
{
//
// Missing external clock has been detected
// Replace this line with a call to an appropriate
// SystemShutdown(); function.
//
asm(" ESTOP0");
}
//
// DIVSEL MUST be 0 before PLLCR can be changed from
// 0x0000. It is set to 0 by an external reset XRSn
// This puts us in 1/4
//
if (SysCtrlRegs.PLLSTS.bit.DIVSEL != 0) //分频部分先设定为4分频,在PLLCR改变之前,DIVSEL 必须为0
{
EALLOW;
SysCtrlRegs.PLLSTS.bit.DIVSEL = 0;
EDIS;
}
//
// Change the PLLCR
//
if (SysCtrlRegs.PLLCR.bit.DIV != val)
{
EALLOW;
//
// Before setting PLLCR turn off missing clock detect logic
//
SysCtrlRegs.PLLSTS.bit.MCLKOFF = 1; //改变PLL倍频系数时,要把丢失时钟检测关闭
SysCtrlRegs.PLLCR.bit.DIV = val;
EDIS;
//
// Optional: Wait for PLL to lock. //在对时钟分频时,要保证PLL已经入锁
// During this time the CPU will switch to OSCCLK/2 until //pLL稳定之前,内核时钟为OSCCLK/2 =15M
// the PLL is stable. Once the PLL is stable the CPU will
// switch to the new PLL value. //PLL一旦稳定下来,内核时钟转变为新的值
//
// This time-to-lock is monitored by a PLL lock counter.
//
// Code is not required to sit and wait for the PLL to lock. //代码不需要等待PLL入锁,但是,如何代码在做一些关键的事情时,需要正确的时钟
// However, if the code does anything that is timing critical, //入锁,最好等待时钟转换完成
// and requires the correct clock be locked, then it is best to
// wait until this switching has completed.
//
//
// Wait for the PLL lock bit to be set.
//
//
// The watchdog should be disabled before this loop, or fed within //在循环之前,要保证开门狗关闭,或者喂狗
// the loop via ServiceDog().
//
//
// Uncomment to disable the watchdog //打开看门狗
//
DisableDog();
while(SysCtrlRegs.PLLSTS.bit.PLLLOCKS != 1) //等待PLL入锁
{
//
// Uncomment to service the watchdog
//
//ServiceDog();
}
EALLOW;
SysCtrlRegs.PLLSTS.bit.MCLKOFF = 0; //振荡器时钟丢失检测使能
EDIS;
}
//
// If switching to 1/2
//
if((divsel == 1)||(divsel == 2))
{
EALLOW;
SysCtrlRegs.PLLSTS.bit.DIVSEL = divsel;
EDIS;
}
//
// NOTE: ONLY USE THIS SETTING IF PLL IS BYPASSED (I.E. PLLCR = 0) OR OFF
// If switching to 1/1
// * First go to 1/2 and let the power settle
// The time required will depend on the system, this is only an example
// * Then switch to 1/1
//
if(divsel == 3) //??????????????????????不明白为什么要这样来,不是直接赋成3就行了,,求解,我看网上有说是为了防止两个
{ //分频器同时分频出现错误,可是这样先分成2分频,再分成1分频就行了??????不是太懂,还望大神指点
EALLOW;
SysCtrlRegs.PLLSTS.bit.DIVSEL = 2;
DELAY_US(50L);
SysCtrlRegs.PLLSTS.bit.DIVSEL = 3;
EDIS;
}
}
|