Other Parts Discussed in Thread: C2000WARE
主题中讨论的其他器件:C2000WARE
你好。
请告诉我在检测到 MISS_CLOCK 时切换到备用时钟的情况。
PLL_INITIAL (6、2)使用20M_XTAL 生成60MHz 系统时钟。
对于切换测试,运行以下代码,该过程将继续执行 NMI_ISR()。
NmiIntruptRegs.NMIFLGFRC.bit.CLOCKFAIL = 1;
我们知道、有必要重新配置 PLL 才能在该函数内切换到内部 OSC1。
这种理解是否正确?
我想使用内部 OSC1并使用 PLL_Initial (12、2)生成一个60MHz 系统时钟。
但是、当执行此函数时、CPU 将停止。
相反、如果未执行此函数、CPU 将继续运行。
XTAL->OSC1在未复位 PLL 的情况下切换是否成功?
祝你一切
__interrupt void nmi_isr(void)
{
PLL_Initial(12, 2); // CLK=10M*12/2=60M XTAL->OSC1
EALLOW;
NmiIntruptRegs.NMIFLGCLR.bit.CLOCKFAIL = 1;
NmiIntruptRegs.NMIFLGCLR.bit.NMIINT = 1;
EDIS;
}
void
PLL_Initial(Uint16 val, Uint16 divsel)
{
volatile Uint16 iVol;
//
// Make sure the PLL is not running in limp mode
//
if (SysCtrlRegs.PLLSTS.bit.MCLKSTS != 0)
{
EALLOW;
//
// OSCCLKSRC1 failure detected. PLL running in limp mode.
// Re-enable missing clock logic.
//
SysCtrlRegs.PLLSTS.bit.MCLKCLR = 1;
EDIS;
//
// Replace this line with a call to an appropriate
// SystemShutdown(); function.
__asm(" ESTOP0"); // Uncomment for debugging purposes
}
//
// 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)
{
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;
SysCtrlRegs.PLLCR.bit.DIV = val;
EDIS;
//
// Optional: Wait for PLL to lock.
//
// During this time the CPU will switch to OSCCLK/2 until
// the PLL is stable. Once the PLL is stable the CPU will
// switch to the new PLL value.
//
// This time-to-lock is monitored by a PLL lock counter.
//
// Code is not required to sit and wait for the PLL to lock.
// 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)
{
//
// 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;
}
//
// 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)
{
EALLOW;
SysCtrlRegs.PLLSTS.bit.DIVSEL = 2;
DELAY_US(50L);
SysCtrlRegs.PLLSTS.bit.DIVSEL = 3;
EDIS;
}
}顺利。 最棒的地方!