/***************************************************************************** * [url=home.php?mod=space&uid=247401]@brief[/url] providing APIs for configuring internal clock sources (ICS). * ******************************************************************************* * * provide APIs for configuring internal clock sources (ICS) ******************************************************************************/ #include "common.h" #include "ics.h" /****************************************************************************** * Global variables ******************************************************************************/ /****************************************************************************** * Constants and macros ******************************************************************************/ /*ICS与OSC模块各寄存器的复位值*/ #define ICS_C1_DEFAULT 0x04 #define ICS_C2_DEFAULT 0x20 #define ICS_C3_DEFAULT 0x54 #define ICS_C4_DEFAULT 0x00 #define ICS_S_DEFAULT 0x50 #define OSC_CR_DEFAULT 0 /****************************************************************************** * Local types ******************************************************************************/ /****************************************************************************** * Local function prototypes ******************************************************************************/ /****************************************************************************** * Local variables ******************************************************************************/ /****************************************************************************** * Local functions ******************************************************************************/ /****************************************************************************** * Global functions ******************************************************************************/ /*****************************************************************************//*! * * [url=home.php?mod=space&uid=72445]@[/url] ICS的工作模式由当前的FEI模式切换为FEE模式,对选中的时钟源做2分频 * * @ OSC模块的输出时钟选择振荡器时钟源 * * @ 输入 pConfig 指向ICS配置结构体 * * @ 无返回 * *****************************************************************************/ void FEI_to_FEE(ICS_ConfigType *pConfig) { /* 使能OSC * */ OSC_Init(&pConfig->oscConfig); /*OSC模块初始化*/ /* 对外部参考时钟进行分频,可将外部时钟分频到31.25k~39.0625k之间 * */ ICS_SetClkDivider(pConfig->u32ClkFreq); /*将FLL的参考时钟选择为外部时钟*/ ICS->C1 = ICS->C1 & ~ICS_C1_IREFS_MASK; /*等待FLL参考时钟变为外部时钟*/ #if defined(IAR) asm( "nop \n" "nop \n" ); #elif defined(__MWERKS__) asm{ nop nop }; #endif while(ICS->S & ICS_S_IREFST_MASK); /* 等待FLL时钟成为ICS输出时钟源*/ while(!(ICS->S & ICS_S_LOCK_MASK)); /* 现在FLL输出时钟变时钟频率等于FLL参考时钟分频结果乘以FLL的倍频系数 * FLL的倍频系数请参考参考手册 */ #if defined(CPU_NV32) /*对选中的是时钟源做2分频*/ if(((ICS->C2 & ICS_C2_BDIV_MASK)>>5) != 1) { ICS->C2 = (ICS->C2 & ~(ICS_C2_BDIV_MASK)) | ICS_C2_BDIV(1); } #else ICS->C2 = (ICS->C2 & ~(ICS_C2_BDIV_MASK)) | ICS_C2_BDIV(0); #endif /* 完成对选中的时钟源做2分频,系统/总线时钟时频率为设置的目标频率 * */ /*lols清0*/ ICS->S |= ICS_S_LOLS_MASK; } /*****************************************************************************//*! * * @ ICS的工作模式由当前的FEI模式转变成FBI模式,内部时钟源分频参数设置为2 * * @ 输入 pConfig 指向ICS配置结构体. * * @ 无返回 * *****************************************************************************/ void FEI_to_FBI(ICS_ConfigType *pConfig) { /*输出时钟源选择内部参考时钟*/ ICS->C1 = (ICS->C1 & ~(ICS_C1_CLKS_MASK)) | ICS_C1_CLKS(1); ICS->C2 = ICS->C2 & ~(ICS_C2_LP_MASK); /*在bypass模式FLL不会被禁止*/ /*等待内部时钟成为时钟输出源*/ #if defined(IAR) asm( "nop \n" "nop \n" ); #elif defined(__MWERKS__) asm{ nop nop }; #endif while(((ICS->S & ICS_S_CLKST_MASK) >> ICS_S_CLKST_SHIFT) !=1); /* 现在内部参考时钟为输出时钟源 * */ #if defined(BUS_CLK_EQU_CORE_DIVIDE_BY_2)||defined(CPU_NV32) /*对选中的时钟源做2分频*/ if(((ICS->C2 & ICS_C2_BDIV_MASK)>>5) != 1) { ICS->C2 = (ICS->C2 & ~(ICS_C2_BDIV_MASK)) | ICS_C2_BDIV(1); } #else ICS->C2 = (ICS->C2 & ~(ICS_C2_BDIV_MASK)); #endif /*LOLS清零*/ ICS->S |= ICS_S_LOLS_MASK; } /*****************************************************************************//*! * * @ ICS的工作模式由当前的FEI模式转换成FBE模式,对选中的内部时钟源做2分频 * * @ OSC模块的输出时钟选择振荡器时钟源 * * @ pConfig 指向ICS的配置结构体 . * * @ 无返回 * *****************************************************************************/ void FEI_to_FBE(ICS_ConfigType *pConfig) { OSC_Init(&pConfig->oscConfig); /* 初始化OSC 模块*/ /*设置FLL的参考时钟为外部时钟*/ ICS->C1 = ICS->C1 & ~(ICS_C1_IREFS_MASK); ICS->C1 = (ICS->C1 & ~(ICS_C1_CLKS_MASK)) | ICS_C1_CLKS(2); /*外部时钟做为ICS输出时钟源*/ ICS->C2 = ICS->C2 & ~(ICS_C2_LP_MASK); /*在bypass模式FLL不会被禁止*/ /*等在参考时钟发生改变*/ #if defined(IAR) asm( "nop \n" "nop \n" ); #elif defined(__MWERKS__) asm{ nop nop }; #endif while(((ICS->S & ICS_S_CLKST_MASK) >> ICS_S_CLKST_SHIFT) !=2); /*外部时钟成为ICS时钟输出源*/ while(ICS->S & ICS_S_IREFST_MASK); /*FLL参考时钟成为外部时钟*/ /* 现在外部时钟成为时钟输出源 * */ #if defined(CPU_NV32) /*对选中的时钟源做2分频*/ if(((ICS->C2 & ICS_C2_BDIV_MASK)>>5) != 1) { ICS->C2 = (ICS->C2 & ~(ICS_C2_BDIV_MASK)) | ICS_C2_BDIV(1); } #else ICS->C2 = (ICS->C2 & ~(ICS_C2_BDIV_MASK)) | ICS_C2_BDIV(0); #endif /* 现在系统/总线时钟变为外部参考时钟的2分频 * */ /* lols清零 */ ICS->S |= ICS_S_LOLS_MASK; } /*****************************************************************************//*! * * @ ICS的工作模式由当前的FEI模式转换成FBE模式? * * @ OSC输出时钟选择EEXTAL引脚的外部时钟源 * * @ 对选中的内部时钟源做2分频 * * @ 输入 pConfig 指向配置结构体. * * @ 无返回 * *****************************************************************************/ void FEI_to_FBE_OSC(ICS_ConfigType *pConfig) { OSC_Init(&pConfig->oscConfig); /* 初始化OSC */ /*设置参考时钟的分频系数,将参考时钟的分频结果设定在26K~40K内 * */ ICS_SetClkDivider(pConfig->u32ClkFreq); /* 假设外部晶振为8Mhz/4Mhz * */ /*改变参考时钟源*/ ICS->C1 = ICS->C1 & ~(ICS_C1_IREFS_MASK);/*将FLL的参考时钟设置为而外部参考时钟*/ ICS->C1 = (ICS->C1 & ~(ICS_C1_CLKS_MASK)) | ICS_C1_CLKS(2); /*输出时钟源选择外部时钟*/ ICS->C2 = ICS->C2 & ~(ICS_C2_LP_MASK); /* 等待参考时钟发生改变*/ #if defined(IAR) asm( "nop \n" "nop \n" ); #elif defined(__MWERKS__) asm{ nop nop }; #endif while(((ICS->S & ICS_S_CLKST_MASK) >> ICS_S_CLKST_SHIFT) !=2);/*外部时钟成为ICS时钟输出时钟源*/ while(ICS->S & ICS_S_IREFST_MASK); /*外部时钟成为FLL参考时钟*/ /* 现在外部时钟成为FLL参考时钟和ICS输出时钟源 * */ #if defined(CPU_NV32) /*对选中的时钟源做2分频*/ if(((ICS->C2 & ICS_C2_BDIV_MASK)>>5) != 1) { ICS->C2 = (ICS->C2 & ~(ICS_C2_BDIV_MASK)) | ICS_C2_BDIV(1); } #else ICS->C2 = (ICS->C2 & ~(ICS_C2_BDIV_MASK)) | ICS_C2_BDIV(0); #endif /* 现在系统/系统总线时钟为选中时钟源的2分频 * */ /*lols 清零*/ ICS->S |= ICS_S_LOLS_MASK; } /*****************************************************************************//*! * * @ ICS的工作模式由当前的FEI模式转换FEE模式? * * @ 对选中的内部时钟源做2分频 * * @ OSC输出时钟选择EEXTAL引脚的外部时钟源 * * @ 输入 pConfig 指向配置结构体 * * @ 无返回 * *****************************************************************************/ void FEI_to_FEE_OSC(ICS_ConfigType *pConfig) { OSC_Init(&pConfig->oscConfig); /*初始化OSC */ /* 设置参考时钟的分频系数,将参考时钟的分频结果设定在26K~40K * */ ICS_SetClkDivider(pConfig->u32ClkFreq); /* 将FLL的参考时钟设置为外部时钟 */ ICS->C1 = ICS->C1 & ~(ICS_C1_IREFS_MASK); /*等待参考时钟变化*/ #if defined(IAR) asm( "nop \n" "nop \n" ); #elif defined(__MWERKS__) asm{ nop nop }; #endif while(ICS->S & ICS_S_IREFST_MASK); /*FLL参考时钟变为外部时钟*/ /*等待FLL成为时钟输出源 */ while(!(ICS->S & ICS_S_LOCK_MASK)); #if defined(CPU_NV32) /*对选中的时钟源做2分频*/ if(((ICS->C2 & ICS_C2_BDIV_MASK)>>5) != 1) { ICS->C2 = (ICS->C2 & ~(ICS_C2_BDIV_MASK)) | ICS_C2_BDIV(1); } #else ICS->C2 = (ICS->C2 & ~(ICS_C2_BDIV_MASK)) | ICS_C2_BDIV(0); #endif /* 现在系统/总线时钟为选中时钟源的2分频 * */ /* LOLS清零 */ ICS->S |= ICS_S_LOLS_MASK; } /*****************************************************************************//*! * * @ 将ICS的工作模式由当前的FEE模式转换成FEI模式. * * @ 输入 pConfig 指向配置结构体 * * @ 无返回 * *****************************************************************************/ void FEE_to_FEI(ICS_ConfigType *pConfig) { /*选择内部时钟作为FLL的参考时钟*/ ICS->C1 = ICS->C1 | (ICS_C1_IREFS_MASK); /*等待参考时钟发生改变*/ #if defined(IAR) asm( "nop \n" "nop \n" ); #elif defined(__MWERKS__) asm{ nop nop }; #endif while(!(ICS->S & ICS_S_IREFST_MASK));/*FLL参考时钟成为内部时钟*/ /*FLL时钟做为ICS输出时钟源 */ while(!(ICS->S & ICS_S_LOCK_MASK)); /*LOLS清零*/ ICS->S |= ICS_S_LOLS_MASK; /* 现在FLL输出成为ICS输出时钟源? * */ #if defined(CPU_NV32) /*对选中的时钟源做2分频*/ if(((ICS->C2 & ICS_C2_BDIV_MASK)>>5) != 1) { ICS->C2 = (ICS->C2 & ~(ICS_C2_BDIV_MASK)) | ICS_C2_BDIV(1); } #else ICS->C2 = (ICS->C2 & ~(ICS_C2_BDIV_MASK)) | ICS_C2_BDIV(0); #endif /* 现在系统/总线时钟大约为 16MHz * */ ICS->C2 = (ICS->C2 & ~(ICS_C2_BDIV_MASK)) | ICS_C2_BDIV(0); OSC_Disable(); /* 禁用 OSC */ } /*****************************************************************************//*! * * @ 将ICS的工作模式由当前的FEE模式转换成FBI模式. * * @ 输入 pConfig 指向配置结构体 * * @ 无返回 * *****************************************************************************/ void FEE_to_FBI(ICS_ConfigType *pConfig) { /*LOLS清零*/ ICS->S |= ICS_S_LOLS_MASK; /* 选择内部时钟作为输出时钟源 */ /* 选择内部时钟作为FLL参考时钟 */ /* LP = 0 在bypass模式FLL不会被禁止*/ ICS->C1 = ICS->C1 | (ICS_C1_IREFS_MASK); ICS->C1 = (ICS->C1 & ~(ICS_C1_CLKS_MASK)) | ICS_C1_CLKS(1); ICS->C2 = ICS->C2 & ~(ICS_C2_LP_MASK); /* 等待参考时钟发生改变 */ #if defined(IAR) asm( "nop \n" "nop \n" ); #elif defined(__MWERKS__) asm{ nop nop }; #endif while(!(ICS->S & ICS_S_IREFST_MASK)); /*FLL参考时钟成为内部时钟*/ while(((ICS->S & ICS_S_CLKST_MASK) >> ICS_S_CLKST_SHIFT) !=1); /*内部时成为ICS输出时钟源*/ #if defined(BUS_CLK_EQU_CORE_DIVIDE_BY_2)||defined(CPU_NV32) /*对所选时钟源做2分频*/ if(((ICS->C2 & ICS_C2_BDIV_MASK)>>5) != 1) { ICS->C2 = (ICS->C2 & ~(ICS_C2_BDIV_MASK)) | ICS_C2_BDIV(1); } #else ICS->C2 = (ICS->C2 & ~(ICS_C2_BDIV_MASK)); #endif OSC_Disable(); } /*****************************************************************************//*! * * @ 将ICS的工作模式由当前的FEE模式转变成FBE模式 * * @ 输入 pConfig 指向配置结构体 * * @ 无返回 * *****************************************************************************/ void FEE_to_FBE(ICS_ConfigType *pConfig) { /*LOLS清零*/ ICS->S |= ICS_S_LOLS_MASK; /*选择外部时钟作为输出时钟源*/ /* LP = 0 在bypass模式FLL不会被禁止*/ ICS->C1 = (ICS->C1 & ~(ICS_C1_CLKS_MASK)) | ICS_C1_CLKS(2); ICS->C2 = ICS->C2 & ~(ICS_C2_LP_MASK); /*等待输出时钟源发生改变*/ #if defined(IAR) asm( "nop \n" "nop \n" ); #elif defined(__MWERKS__) asm{ nop nop }; #endif while(((ICS->S & ICS_S_CLKST_MASK) >> ICS_S_CLKST_SHIFT) !=2);/*外部时钟成为ICS输出时钟源*/ /* 现在ICS输出时钟源选择外部时钟源 * 注释: 确保外部时钟频率在20Mhz以内 */ #if defined(CPU_NV32) /*对选择的时钟源做2分频*/ if(((ICS->C2 & ICS_C2_BDIV_MASK)>>5) != 1) { ICS->C2 = (ICS->C2 & ~(ICS_C2_BDIV_MASK)) | ICS_C2_BDIV(1); } #else ICS->C2 = (ICS->C2 & ~(ICS_C2_BDIV_MASK)) | ICS_C2_BDIV(0); #endif } /*****************************************************************************//*! * * @ 将ICS的工作模式由当前的FBI模式转换成FBE模式 * * @ 输入 pConfig 指向配置结构体. * * @ 无返回 * *****************************************************************************/ void FBI_to_FBE(ICS_ConfigType *pConfig) { OSC_Init(&pConfig->oscConfig); /* 初始化OSC */ /* 选择外部时钟做为FLL的参考时钟 */ /*选择外部时钟作为输出时钟源*/ ICS->C1 = ICS->C1 & ~(ICS_C1_IREFS_MASK); ICS->C1 = (ICS->C1 & ~(ICS_C1_CLKS_MASK)) | ICS_C1_CLKS(2); /* 等待输出时钟源发生改变 */ #if defined(IAR) asm( "nop \n" "nop \n" ); #elif defined(__MWERKS__) asm{ nop nop }; #endif while(((ICS->S & ICS_S_CLKST_MASK) >> ICS_S_CLKST_SHIFT) !=2); /*外部时钟成为输出时钟源*/ while((ICS->S & ICS_S_IREFST_MASK)); /*外部时钟成为FLL的参考时钟*/ /* 现在系统时钟源是外部参考时钟 * 注释:确保外部时钟源的频率在20Mhz */ #if defined(CPU_NV32) /*对选中的时钟源做2分频*/ if(((ICS->C2 & ICS_C2_BDIV_MASK)>>5) != 1) { ICS->C2 = (ICS->C2 & ~(ICS_C2_BDIV_MASK)) | ICS_C2_BDIV(1); } #else ICS->C2 = (ICS->C2 & ~(ICS_C2_BDIV_MASK)) | ICS_C2_BDIV(0); #endif }
收藏0 举报
/*****************************************************************************//** * * @ 将ICS的工作模式由当前的FBI模式转换成FEE模式 * * @ pConfig 指向配置结构体 * * @ 无返回 * *****************************************************************************/ void FBI_to_FEE(ICS_ConfigType *pConfig) { OSC_Init(&pConfig->oscConfig); /* 初始化OSC */ /* 选择外部时钟作为FLL的参考时钟 */ /* 选择FLL输出作为做为ICS输出时钟源*/ ICS->C1 = ICS->C1 & ~(ICS_C1_IREFS_MASK); ICS->C1 = (ICS->C1 & ~(ICS_C1_CLKS_MASK)); /*等待时钟源改变*/ #if defined(IAR) asm( "nop \n" "nop \n" ); #elif defined(__MWERKS__) asm{ nop nop }; #endif while((ICS->S & ICS_S_CLKST_MASK));/*FLL时钟成为ICS输出时钟源*/ while((ICS->S & ICS_S_IREFST_MASK));/*外部时钟成为FLL参考时钟*/ /* 现在系统时钟源为外部时钟 * 注释: 确保外部时钟源的频率在20Mhz内 */ #if defined(CPU_NV32) /*对选中的时钟源做2分频*/ if(((ICS->C2 & ICS_C2_BDIV_MASK)>>5) != 1) { ICS->C2 = (ICS->C2 & ~(ICS_C2_BDIV_MASK)) | ICS_C2_BDIV(1); } #else ICS->C2 = (ICS->C2 & ~(ICS_C2_BDIV_MASK)) | ICS_C2_BDIV(0); #endif /*lols清零*/ ICS->S |= ICS_S_LOLS_MASK; } /*****************************************************************************//*! * * @ 将ICS的工作模式由当前的FBI模式转换成FBIP模式 * * @ pConfig 输出指向配置结构体 * * @ 无返回 * * @ 警告 必须运行在调试接口没有没有接线 * *****************************************************************************/ void FBI_to_FBILP(ICS_ConfigType *pConfig) { /*假设外部晶振时8mhz或者4mhz * */ ICS->C2 |= ICS_C2_LP_MASK; /*进入低功耗模式*/ } /*****************************************************************************//*! * * @ 将ICS的工作模式由当前的FBI模式转变为FEI模式 * * @ 输入 pConfig 指向配置结构体. * * @ 无返回 * *****************************************************************************/ void FBI_to_FEI(ICS_ConfigType *pConfig) { /* 选择内部时钟为FLL的参考时钟 */ /*选择FLL输出作为ICS输出时钟源*/ ICS->C1 = ICS->C1 | (ICS_C1_IREFS_MASK); ICS->C1 = (ICS->C1 & ~(ICS_C1_CLKS_MASK)); /*等待时钟源发生改变*/ #if defined(IAR) asm( "nop \n" "nop \n" ); #elif defined(__MWERKS__) asm{ nop nop }; #endif while((ICS->S & ICS_S_CLKST_MASK)); /*FLL输出成为ICS输出时钟源*/ while(!(ICS->S & ICS_S_IREFST_MASK));/*FLL的参考时钟选择为外部时钟*/ /* 现在系统时钟源为FLL输出 * */ #if defined(CPU_NV32) /*对选中的时钟源做2分频*/ if(((ICS->C2 & ICS_C2_BDIV_MASK)>>5) != 1) { ICS->C2 = (ICS->C2 & ~(ICS_C2_BDIV_MASK)) | ICS_C2_BDIV(1); } #else ICS->C2 = (ICS->C2 & ~(ICS_C2_BDIV_MASK)) | ICS_C2_BDIV(0); #endif /*LOLS清零 */ ICS->S |= ICS_S_LOLS_MASK; } /*****************************************************************************//*! * * @ 将ICS的工作模式由当前的FBE模式转换成FBI模式 * * @ pConfig 指向配置结构体 * * @ 无返回 * *****************************************************************************/ void FBE_to_FBI(ICS_ConfigType *pConfig) { /*选择内部时钟作为FLL的参考时钟*/ /*选择内部时钟作为ICS输出时钟源*/ ICS->C1 = ICS->C1 | (ICS_C1_IREFS_MASK); ICS->C1 = (ICS->C1 & ~(ICS_C1_CLKS_MASK)) | ICS_C1_CLKS(1); /*等待时钟源发生改变*/ #if defined(IAR) asm( "nop \n" "nop \n" ); #elif defined(__MWERKS__) asm{ nop nop }; #endif while(((ICS->S & ICS_S_CLKST_MASK) >> ICS_S_CLKST_SHIFT) != 1);/*内部时钟成为ICS输出时钟源*/ while(!(ICS->S & ICS_S_IREFST_MASK)); /*内部时钟成为FLL的参考时钟*/ /* 现在系统时钟源时内部时钟 * */ #if defined(CPU_NV32) /*对选中的时钟源做2分频*/ if(((ICS->C2 & ICS_C2_BDIV_MASK)>>5) != 1) { ICS->C2 = (ICS->C2 & ~(ICS_C2_BDIV_MASK)) | ICS_C2_BDIV(1); } #else ICS->C2 = (ICS->C2 & ~(ICS_C2_BDIV_MASK)) | ICS_C2_BDIV(0); #endif /* 禁用OSC */ OSC_Disable(); } /*****************************************************************************//*! * * @ 将ICS的工作模式由当前的FBE模式转换成FEE模式 * * @ 输入 pConfig 指向配置结构体. * * @ 无返回 * *****************************************************************************/ void FBE_to_FEE(ICS_ConfigType *pConfig) { /*选择FLL输出作为输出时钟源*/ ICS->C1 = (ICS->C1 & ~(ICS_C1_CLKS_MASK)); /*等待输出时钟源发生改变*/ #if defined(IAR) asm( "nop \n" "nop \n" ); #elif defined(__MWERKS__) asm{ nop nop }; #endif while(ICS->S & ICS_S_CLKST_MASK); /* 现在系统时钟源为FLL输出 * 注释: 外部时钟频率 <= 20MHz */ #if defined(CPU_NV32) /*对选中的时钟源做2分频*/ if(((ICS->C2 & ICS_C2_BDIV_MASK)>>5) != 1) { ICS->C2 = (ICS->C2 & ~(ICS_C2_BDIV_MASK)) | ICS_C2_BDIV(1); } #else ICS->C2 = (ICS->C2 & ~(ICS_C2_BDIV_MASK)) | ICS_C2_BDIV(0); #endif /* LOLS清零 */ ICS->S |= ICS_S_LOLS_MASK; } /*****************************************************************************//*! * * @ 将ICS的工作模式由当前的FBE模式转变成FEI模式 * * @ 输入 pConfig 指向配置结构体 * * @ 无返回 * *****************************************************************************/ void FBE_to_FEI(ICS_ConfigType *pConfig) { /* 选择内部时钟作为FLL的参考时钟*/ /*选择FLL输出做为ICS输出时钟源*/ ICS->C1 = ICS->C1 | (ICS_C1_IREFS_MASK); ICS->C1 = (ICS->C1 & ~(ICS_C1_CLKS_MASK)); /*等待时钟源改变*/ #if defined(IAR) asm( "nop \n" "nop \n" ); #elif defined(__MWERKS__) asm{ nop nop }; #endif while((ICS->S & ICS_S_CLKST_MASK)); /*FLL输出成为ICS输出时钟源*/ while(!(ICS->S & ICS_S_IREFST_MASK)); /*内部时钟中成为FLL参考时钟*/ /* 现在FLL输出成为输出时钟源 * */ #if defined(CPU_NV32) /*对选中的时钟源做2分频*/ if(((ICS->C2 & ICS_C2_BDIV_MASK)>>5) != 1) { ICS->C2 = (ICS->C2 & ~(ICS_C2_BDIV_MASK)) | ICS_C2_BDIV(1); } #else ICS->C2 = (ICS->C2 & ~(ICS_C2_BDIV_MASK)) | ICS_C2_BDIV(0); #endif /*LOLS清零*/ ICS->S |= ICS_S_LOLS_MASK; /* 禁用OSC */ OSC_Disable(); } /*****************************************************************************//*! * * @ 将ICS的工作模式由当前的FBE模式转变为FBEL模式 * * @ 输入 pConfig 指向配置结构体. * * @ 无返回 * *****************************************************************************/ void FBE_to_FBELP(ICS_ConfigType *pConfig) { /*低功耗使能*/ ICS->C2 = ICS->C2 | (ICS_C2_LP_MASK); } /*****************************************************************************//*! * * @ 将ICS的工作模式由当前的FBELP模式转换成FBE模式 * * @ 输入 pConfig 指向配置结构体. * * @ 无返回 * *****************************************************************************/ void FBELP_to_FBE(ICS_ConfigType *pConfig) { /*禁用低功耗模式*/ ICS->C2 = ICS->C2 & ~(ICS_C2_LP_MASK); } /*****************************************************************************//*! * * @ 将ICS的工作模式由当前的FBILP. * * @ 输入 pConfig 指向配置结构体. * * @ 无返回 * *****************************************************************************/ void FBILP_to_FBI(ICS_ConfigType *pConfig) { /* 禁用功耗*/ ICS->C2 = ICS->C2 & ~(ICS_C2_LP_MASK); } /****************************************************************************** * define ICS API list * *//*! @addtogroup ics_api_list * @{ *******************************************************************************/ /*****************************************************************************//*! * * @ 调整内部内部时钟 (IRC). * * @ 输入 u16TrimValue 调整值 * * @ 无返回 * *****************************************************************************/ void ICS_Trim(uint16_t u16TrimValue) { ICS->C3 = (uint8_t) u16TrimValue; /*将调整值写入寄存器*/ ICS->C4 = (ICS->C4 & ~(ICS_C4_SCFTRIM_MASK)) | ((u16TrimValue>>8) & 0x01); while(!(ICS->S & ICS_S_LOCK_MASK)); } /*****************************************************************************//*! * * @ 对外部参考时钟进行分频,使得分频结果在26k~40k内 * * @ u32ClkFreqKHz 参考时钟频率. * * @ 无返回 * *****************************************************************************/ void ICS_SetClkDivider(uint32_t u32ClkFreqKHz) { switch(u32ClkFreqKHz) { case 8000L: case 10000L: /* 8MHz or 10MHz */ ICS->C1 = (ICS->C1 & ~(ICS_C1_RDIV_MASK)) | ICS_C1_RDIV(3); /* 现在分频结果是 8000/256 = 31.25K */ /* 分频结果 10000/256 = 39.0625K */ break; case 4000L: /* 4MHz */ ICS->C1 = (ICS->C1 & ~(ICS_C1_RDIV_MASK)) | ICS_C1_RDIV(2); /* 分频结果 4000/128 = 31.25K */ break; case 16000L: /* 16MHz */ ICS->C1 = (ICS->C1 & ~(ICS_C1_RDIV_MASK)) | ICS_C1_RDIV(4); /* 分频结果 16000/512 = 31.25K */ break; case 20000L: /* 20MHz */ ICS->C1 = (ICS->C1 & ~(ICS_C1_RDIV_MASK)) | ICS_C1_RDIV(4); /* 分频结果 20000/512 = 39.0625K */ break; case 32L: /* 32KHz */ ICS->C1 &= ~(ICS_C1_RDIV_MASK); break; default: break; } } /*****************************************************************************//*! * * @ 初始化ICS模块定义所需要的总线时钟频率. * * @ pConfig 指向配置结构体. * * @ 无返回 * *****************************************************************************/ void ICS_Init(ICS_ConfigType *pConfig) { if(pConfig->u8ClkMode == ICS_CLK_MODE_FEE) { pConfig->oscConfig.bIsCryst = 1; /*OSC的输出选择选择振动器时钟源*/ pConfig->oscConfig.bWaitInit = 1; /* 等待振荡器初始化化完成 */ FEI_to_FEE(pConfig); /*选择FEE模式,使用振荡器时钟源*/ } else if (pConfig->u8ClkMode == ICS_CLK_MODE_FEE_OSC) { pConfig->oscConfig.bIsCryst = 0; /*OSC输出时钟选择EEXTAL引脚的外部时钟源*/ FEI_to_FEE_OSC(pConfig); /*选择FEE工作模式*/ } else if (pConfig->u8ClkMode == ICS_CLK_MODE_FBE_OSC) { pConfig->oscConfig.bIsCryst = 0; /* OSC输出时钟选择EEXTAL引脚的外部时钟源*/ FEI_to_FBE_OSC(pConfig); /* 选择FBE工作模式*/ } else if(pConfig->u8ClkMode == ICS_CLK_MODE_FBELP ) { pConfig->oscConfig.bIsCryst = 1; /*OSC的输出时钟选择选择振动器时钟源*/ pConfig->oscConfig.bWaitInit = 1; /*等待振荡器初始化化完成 */ FEI_to_FBE(pConfig); /*先选择PBE模式*/ FBE_to_FBELP(pConfig); /*选择FBELP*/ ICS->C2 = (ICS->C2 & ~(ICS_C2_BDIV_MASK)) | ICS_C2_BDIV(0); } else if(pConfig->u8ClkMode == ICS_CLK_MODE_FBILP ) { pConfig->oscConfig.bIsCryst = 0; /* OSC输出时钟选择EXTAL引脚的外部时钟源*/ FEI_to_FBI(pConfig); /*选择FBI工作模式*/ FBI_to_FBILP(pConfig); /*选择FBILP工作模式*/ ICS->C2 = (ICS->C2 & ~(ICS_C2_BDIV_MASK)) | ICS_C2_BDIV(0); } else { /*默认工作模式FEI模式*/ #if defined(CPU_NV32) /*对所选时钟源进行2分频*/ if(((ICS->C2 & ICS_C2_BDIV_MASK)>>5) != 1) { ICS->C2 = (ICS->C2 & ~(ICS_C2_BDIV_MASK)) | ICS_C2_BDIV(1); } #else ICS->C2 = (ICS->C2 & ~(ICS_C2_BDIV_MASK)) | ICS_C2_BDIV(0); #endif ICS->C2 = (ICS->C2 & ~(ICS_C2_BDIV_MASK)) | ICS_C2_BDIV(0); } ICS->C2 = (ICS->C2 & ~(ICS_C2_BDIV_MASK)) | ICS_C2_BDIV(0); } /*****************************************************************************//*! * * @ 对ICS模块各寄存器进行复位. * * @ 无输入 * * @ 无返回 *****************************************************************************/ void ICS_DeInit(void) { ICS->C1 = ICS_C1_DEFAULT; ICS->C2 = ICS_C2_DEFAULT; ICS->C3 = ICS_C3_DEFAULT; ICS->C4 = ICS_C4_DEFAULT; while(ICS->S != ICS_S_DEFAULT) ; } /*! @} End of ics_api_list */ /****************************************************************************** * define OSC API list * *//*! @addtogroup osc_api_list * @{ *******************************************************************************/ /*****************************************************************************//*! * * @ 使用给定的参数初始化XOSC : GAIN, RANGE in control structure. * * @ pConfig 指向osc配置结构体 * * @ 无返回 * *****************************************************************************/ void OSC_Init(OSC_ConfigType *pConfig) { uint8 cr = 0; /* * */ if(pConfig->bGain) /*高增益振荡器选择*/ { /* 选择高增益模式 */ cr |= OSC_CR_HGO_MASK ; /* 变阻器必须增加到200K */ } if(pConfig->bRange) /*频率范围的选择*/ { cr |= OSC_CR_RANGE_MASK; /*选择高频范围*/ } if(pConfig->bStopEnable) /*停止模式下的OSC使能*/ { cr |= OSC_CR_OSCSTEN_MASK; /*OSC在停止模式下保持使能*/ } if(pConfig->bIsCryst) /*OSC输出选择*/ { cr |= OSC_CR_OSCOS_MASK; /*选择振荡器时钟*/ } if(pConfig->bEnable) /*OSC使能*/ { cr |= OSC_CR_OSCEN_MASK; } OSC->CR = cr; /*数值写入控制寄存器*/ if(pConfig->bWaitInit) /*等待出书化完成*/ { /* wait for OSC to be initialized * */ while(!(OSC->CR & OSC_CR_OSCINIT_MASK)); } } /*****************************************************************************//*! * * @ 初始化OSC模块,使其恢复到默认状态. * * @ 无输入 * * @ 无返回 * *****************************************************************************/ void OSC_DeInit(void) { OSC->CR = OSC_CR_DEFAULT; } /*! @} End of osc_api_list */
本版积分规则 发表回复 回帖并转播 回帖后跳转到最后一页
20
113
0
扫码关注 21ic 官方微信
扫码关注嵌入式微处理器
扫码关注电源系统设计
扫码关注21ic项目外包
扫码浏览21ic手机版
本站介绍 | 申请友情链接 | 欢迎投稿 | 隐私声明 | 广告业务 | 网站地图 | 联系我们 | 诚聘英才
京公网安备 11010802024343号