// ============================================================================= // 功能:PLL初始化部分,主要对PLL和晶振初始化,是时间从内部时钟切换到外部时钟的主要部 // 分,此处使用PLL0和OSC0作为内部时钟源,经分频和倍频,使内核时钟达到150M // 参数:crystal_fre_hz,外部晶振频率 // prdiv,PLL分频参数 // vdiv,PLL倍频参数 // 返回:实际配置的MCG输出频率 // ============================================================================= u32 PLL_Init(u32 crystal_fre_hz, u8 prdiv, u8 vdiv) { //reset后,系统处于FEI模式,时钟配置过程为: //FEI--->FBE--->PBE--->PEE(手册640页table25-22) //默认使用振荡器0,设置振荡器0 // 配置控制寄存器MCG_C2 // 先清bit位,配置高速晶振,high-gain operation,外部晶振 MCG->C2 &= ~(MCG_C2_RANGE0_MASK | MCG_C2_HGO0_MASK | MCG_C2_EREFS0_MASK); MCG->C2 |= (MCG_C2_RANGE0(1) | (0 << MCG_C2_HGO0_SHIFT) | (0 << MCG_C2_EREFS0_SHIFT)); // 配置控制寄存器MCG_C1 //先清bit位,CLK为外部时钟,FRDIV为5时,配置分频为1024,即配置FLL处于 //31.25-39.0625 kHz 之间 MCG->C1 &= ~(MCG_C1_CLKS_MASK | MCG_C1_FRDIV_MASK | MCG_C1_IREFS_MASK); MCG->C1 = MCG_C1_CLKS(2) | MCG_C1_FRDIV(5); while((MCG->S & MCG_S_IREFST_MASK)); //等待FLL时钟转为外部源 while(((MCG->S & MCG_S_CLKST_MASK) >> MCG_S_CLKST_SHIFT) != 0x2); // Now in FBE MCG->C6 |= MCG_C6_CME0_MASK; // start Configure PLL0 MCG->C5 &= ~MCG_C5_PLLREFSEL0_MASK; // ensure OSC0 MCG->C11 &= ~MCG_C11_PLLCS_MASK; // select PLL0 // Configure MCG_C5 MCG->C5 &= ~MCG_C5_PRDIV0_MASK; // clear settings MCG->C5 |= MCG_C5_PRDIV0(prdiv - 1); //set PLL ref divider // Configure MCG_C6 MCG->C6 &= ~MCG_C6_VDIV0_MASK; // clear settings MCG->C6 |= MCG_C6_PLLS_MASK | MCG_C6_VDIV0(vdiv - 16); // write new VDIV while(!(MCG->S & MCG_S_PLLST_MASK)); // wait for PLLST status bit to set while(!(MCG->S & MCG_S_LOCK0_MASK)); // Wait for LOCK bit to set // Use actual PLL settings to calculate PLL frequency prdiv = ((MCG->C5 & MCG_C5_PRDIV0_MASK) + 1); vdiv = ((MCG->C6 & MCG_C6_VDIV0_MASK) + 16); // now in PBE MCG->C1 &= ~MCG_C1_CLKS_MASK; // 清CLKS,选择MCG_OUT源为PLL while(((MCG->S & MCG_S_CLKST_MASK) >> MCG_S_CLKST_SHIFT) != 0x3); // start Configure PLL1 if needed, for DDR,so, CLK = 100MHz #if (CN_CFG_DDR_USED == 1) // Configure MCG_C12 MCG->C11 &= ~MCG_C11_PLLREFSEL1_MASK; // Clear select bit to choose OSC0 MCG->C11 &= ~MCG_C11_PRDIV1_MASK; MCG->C11 |= MCG_C11_PRDIV1(5 - 1); MCG->C12 &= ~MCG_C12_VDIV1_MASK; // clear VDIV settings MCG->C12 |= MCG_C12_VDIV1(24 - 16); // write new VDIV and enable PLL // Now enable the PLL MCG->C11 |= MCG_C11_PLLCLKEN1_MASK; // Set PLLCLKEN2 to enable PLL1 while(!(MCG->S2 & MCG_S2_LOCK1_MASK)); // Wait for PLL1 locked #endif //MCGOUT equals PLL output frequency/2 return (((crystal_fre_hz / prdiv) * vdiv) / 2); }
/*lint -esym(765,Cpu_Interrupt) Disable MISRA rule (8.10) checking for symbols (Cpu_Interrupt). */ void __init_hardware(void) { /*** !!! Here you can place your own code before PE initialization using property "User code before PE initialization" on the build options tab. !!! ***/ /*** ### MK70FN1M0VMJ12 "Cpu" init code ... ***/ /*** PE initialization code after reset ***/ SCB_VTOR = (uint32_t)(&__vect_table); /* Set the interrupt vector table position */ /* Disable the WDOG module */ /* WDOG_UNLOCK: WDOGUNLOCK=0xC520 */ WDOG_UNLOCK = WDOG_UNLOCK_WDOGUNLOCK(0xC520); /* Key 1 */ /* WDOG_UNLOCK: WDOGUNLOCK=0xD928 */ WDOG_UNLOCK = WDOG_UNLOCK_WDOGUNLOCK(0xD928); /* Key 2 */ /* WDOG_STCTRLH: ??=0,DISTESTWDOG=0,BYTESEL=0,TESTSEL=0,TESTWDOG=0,??=0,??=1,WAITEN=1,STOPEN=1,DBGEN=0,ALLOWUPDATE=1,WINEN=0,IRQRSTEN=0,CLKSRC=1,WDOGEN=0 */ WDOG_STCTRLH = WDOG_STCTRLH_BYTESEL(0x00) | WDOG_STCTRLH_WAITEN_MASK | WDOG_STCTRLH_STOPEN_MASK | WDOG_STCTRLH_ALLOWUPDATE_MASK | WDOG_STCTRLH_CLKSRC_MASK | 0x0100U; /* System clock initialization */ /* SIM_CLKDIV1: OUTDIV1=0,OUTDIV2=1,OUTDIV3=3,OUTDIV4=3,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0 */ SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIV1(0x00) | SIM_CLKDIV1_OUTDIV2(0x01) | SIM_CLKDIV1_OUTDIV3(0x03) | SIM_CLKDIV1_OUTDIV4(0x03); /* Set the system prescalers to safe value */ /* SIM_SCGC5: PORTE=1,PORTA=1 */ SIM_SCGC5 |= (SIM_SCGC5_PORTE_MASK | SIM_SCGC5_PORTA_MASK); /* Enable clock gate for ports to enable pin routing */ if ((PMC_REGSC & PMC_REGSC_ACKISO_MASK) != 0x0U) { /* PMC_REGSC: ACKISO=1 */ PMC_REGSC |= PMC_REGSC_ACKISO_MASK; /* Release IO pads after wakeup from VLLS mode. */ } /* SIM_CLKDIV1: OUTDIV1=0,OUTDIV2=0,OUTDIV3=1,OUTDIV4=1,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0 */ SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIV1(0x00) | SIM_CLKDIV1_OUTDIV2(0x00) | SIM_CLKDIV1_OUTDIV3(0x01) | SIM_CLKDIV1_OUTDIV4(0x01); /* Update system prescalers */ /* SIM_SOPT2: PLLFLLSEL=0 */ SIM_SOPT2 &= (uint32_t)~(uint32_t)(SIM_SOPT2_PLLFLLSEL(0x03)); /* Select FLL as a clock source for various peripherals */ /* SIM_SOPT1: OSC32KSEL=0 */ SIM_SOPT1 &= (uint32_t)~(uint32_t)(SIM_SOPT1_OSC32KSEL_MASK); /* System oscillator drives 32 kHz clock for various peripherals */ /* SIM_SCGC1: OSC1=1 */ SIM_SCGC1 |= SIM_SCGC1_OSC1_MASK; /* Switch to FEI Mode */ /* MCG_C1: CLKS=0,FRDIV=0,IREFS=1,IRCLKEN=1,IREFSTEN=0 */ MCG_C1 = MCG_C1_CLKS(0x00) | MCG_C1_FRDIV(0x00) | MCG_C1_IREFS_MASK | MCG_C1_IRCLKEN_MASK; /* MCG_C2: LOCRE0=0,??=0,RANGE0=0,HGO0=0,EREFS0=0,LP=0,IRCS=0 */ MCG_C2 = MCG_C2_RANGE0(0x00); /* MCG_C4: DMX32=0,DRST_DRS=0 */ MCG_C4 &= (uint8_t)~(uint8_t)((MCG_C4_DMX32_MASK | MCG_C4_DRST_DRS(0x03))); /* OSC0_CR: ERCLKEN=1,??=0,EREFSTEN=0,??=0,SC2P=0,SC4P=0,SC8P=0,SC16P=0 */ OSC0_CR = OSC_CR_ERCLKEN_MASK; /* MCG_C10: LOCRE2=0,??=0,RANGE1=0,HGO1=0,EREFS1=0,??=0,??=0 */ MCG_C10 = MCG_C10_RANGE1(0x00); /* OSC1_CR: ERCLKEN=1,??=0,EREFSTEN=0,??=0,SC2P=0,SC4P=0,SC8P=0,SC16P=0 */ OSC1_CR = OSC_CR_ERCLKEN_MASK; /* MCG_C7: OSCSEL=0 */ MCG_C7 &= (uint8_t)~(uint8_t)(MCG_C7_OSCSEL_MASK); /* MCG_C5: PLLREFSEL0=0,PLLCLKEN0=0,PLLSTEN0=0,??=0,??=0,PRDIV0=0 */ MCG_C5 = MCG_C5_PRDIV0(0x00); /* MCG_C6: LOLIE0=0,PLLS=0,CME0=0,VDIV0=0 */ MCG_C6 = MCG_C6_VDIV0(0x00); /* MCG_C11: PLLREFSEL1=0,PLLCLKEN1=0,PLLSTEN1=0,PLLCS=0,??=0,PRDIV1=0 */ MCG_C11 = MCG_C11_PRDIV1(0x00); /* MCG_C12: LOLIE1=0,??=0,CME2=0,VDIV1=0 */ MCG_C12 = MCG_C12_VDIV1(0x00); /* 3 */ while((MCG_S & MCG_S_IREFST_MASK) == 0x00U) { /* Check that the source of the FLL reference clock is the internal reference clock. */ } while((MCG_S & 0x0CU) != 0x00U) { /* Wait until output of the FLL is selected */ } /*** End of PE initialization code after reset ***/ /*** !!! Here you can place your own code after PE initialization using property "User code after PE initialization" on the build options tab. !!! ***/ }