//-------------------------------------------------------------------------*
//函数名: pll_init *
//功 能: pll初始化 *
//参 数: clk_option:时钟选项 *
// crystal_val:时钟值 *
//返 回: 时钟频率值 *
//说 明: *
//-------------------------------------------------------------------------*
unsigned char pll_init(unsigned char clk_option, unsigned char crystal_val)
{
unsigned char pll_freq;
if (clk_option > 3) {return 0;} //如果没有选择可用的选项则返回0
if (crystal_val > 15) {return 1;} // 如果如果可用的晶体选项不可用则返回1
//这里处在默认的FEI模式
//首先移动到FBE模式
#if (defined(K60_CLK) || defined(ASB817))
MCG_C2 = 0;
#else
//使能外部晶振
MCG_C2 = MCG_C2_RANGE(2) | MCG_C2_HGO_MASK | MCG_C2_EREFS_MASK;
#endif
//初始化晶振后释放锁定状态的振荡器和GPIO
SIM_SCGC4 |= SIM_SCGC4_LLWU_MASK;
LLWU_CS |= LLWU_CS_ACKISO_MASK;
//选择外部晶振,参考分频器,清IREFS来启动外部晶振
MCG_C1 = MCG_C1_CLKS(2) | MCG_C1_FRDIV(3);
//等待晶振稳定
#if (!defined(K60_CLK) && !defined(ASB817))
while (!(MCG_S & MCG_S_OSCINIT_MASK)){};
#endif
//等待参考时钟状态位清零
while (MCG_S & MCG_S_IREFST_MASK){};
//等待时钟状态位显示时钟源来自外部参考时钟
while (((MCG_S & MCG_S_CLKST_MASK) >> MCG_S_CLKST_SHIFT) != 0x2){};
//进入FBE模式
#if (defined(K60_CLK))
MCG_C5 = MCG_C5_PRDIV(0x18);
#else
//配置PLL分频器来匹配所用的晶振
MCG_C5 = MCG_C5_PRDIV(crystal_val);
#endif
//确保MCG_C6处于复位状态,禁止LOLIE、PLL、和时钟控制器,清PLL VCO分频器
MCG_C6 = 0x0;
//选择PLL VCO分频器,系统时钟分频器取决于时钟选项
switch (clk_option) {
case 0:
//设置系统分频器
//MCG=PLL, core = MCG, bus = MCG, FlexBus = MCG, Flash clock= MCG/2
set_sys_dividers(0,0,0,1);
//设置VCO分频器,使能PLL为50MHz, LOLIE=0, PLLS=1, CME=0, VDIV=1
MCG_C6 = MCG_C6_PLLS_MASK | MCG_C6_VDIV(1); //VDIV = 1 (x25)
pll_freq = 50;
break;
case 1:
//设置系统分频器
//MCG=PLL, core = MCG, bus = MCG/2, FlexBus = MCG/2, Flash clock= MCG/4
set_sys_dividers(0,1,1,3);
//设置VCO分频器,使能PLL为100MHz, LOLIE=0, PLLS=1, CME=0, VDIV=26
MCG_C6 = MCG_C6_PLLS_MASK | MCG_C6_VDIV(26); //VDIV = 26 (x50)
pll_freq = 100;
break;
case 2:
//设置系统分频器
//MCG=PLL, core = MCG, bus = MCG/2, FlexBus = MCG/2, Flash clock= MCG/4
set_sys_dividers(0,1,1,3);
//设置VCO分频器,使能PLL为96MHz, LOLIE=0, PLLS=1, CME=0, VDIV=24
MCG_C6 = MCG_C6_PLLS_MASK | MCG_C6_VDIV(24); //VDIV = 24 (x48)
pll_freq = 96;
break;
case 3:
//设置系统分频器
//MCG=PLL, core = MCG, bus = MCG, FlexBus = MCG, Flash clock= MCG/2
set_sys_dividers(0,0,0,1);
//设置VCO分频器,使能PLL为48MHz, LOLIE=0, PLLS=1, CME=0, VDIV=0
MCG_C6 = MCG_C6_PLLS_MASK; //VDIV = 0 (x24)
pll_freq = 48;
break;
}
while (!(MCG_S & MCG_S_PLLST_MASK)){}; // wait for PLL status bit to set
while (!(MCG_S & MCG_S_LOCK_MASK)){}; // Wait for LOCK bit to set
//进入PBE模式
//通过清零CLKS位来进入PEE模式
// CLKS=0, FRDIV=3, IREFS=0, IRCLKEN=0, IREFSTEN=0
MCG_C1 &= ~MCG_C1_CLKS_MASK;
//等待时钟状态位更新
while (((MCG_S & MCG_S_CLKST_MASK) >> MCG_S_CLKST_SHIFT) != 0x3){};
//开始进入PEE模式
return pll_freq;
}
|