| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109 |
- /*************************************************************!
- * 技术讨论:QQ群 123763203
- * 官网 :www.navota.com
- *
- * @file ics.c
- * @brief 时钟模块(ICS)函数库
- * @author Navota
- * @date 2017-1-1
- ****************************************************************/
- #include "common.h"
- #include "ics.h"
- /* 复位后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
- /*****************************************************************************//*!
- *
- * @ 概要 ICS的工作模式由当前的FEI模式切换为FEE模式,对选中的时钟源做1分频
- * 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)
- /*对选中的ICS输出时钟源做1分频*/
- if(((ICS->C2 & ICS_C2_BDIV_MASK)>>5) == 1)
- {
- ICS->C2 = (ICS->C2 & ~(ICS_C2_BDIV_MASK)) | ICS_C2_BDIV(0);
- }
- #else
- ICS->C2 = (ICS->C2 & ~(ICS_C2_BDIV_MASK)) | ICS_C2_BDIV(0);
- #endif
-
- /*
- * 完成对选中的时钟源做1分频,系统/总线时钟时频率为设置的目标频率
- */
- /*LOLS清0*/
- ICS->S |= ICS_S_LOLS_MASK;
- }
- /*****************************************************************************//*!
- *
- * @ 概要 ICS的工作模式由当前的FEI模式转变成FBI模式,对选中的ICS输出时钟源
- * 进行2分频
- *
- * @ 参数 pConfig 指向ICS配置结构体.
- *
- * @ 无返回
- *
- * @ 成功/失败的标准 :无
- * @ 参看 ICS_ConfigType
- *****************************************************************************/
- void FEI_to_FBI(ICS_ConfigType *pConfig)
- {
- /*ICS输出时钟源选择内部参考时钟*/
- ICS->C1 = (ICS->C1 & ~(ICS_C1_CLKS_MASK)) | ICS_C1_CLKS(1);
- ICS->C2 = ICS->C2 & ~(ICS_C2_LP_MASK);
- /*等待内部时钟成为ICS输出时钟源*/
- #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输出时钟源
- */
- #if defined(BUS_CLK_EQU_CORE_DIVIDE_BY_2)||defined(CPU_NV32)
- /*对选中的ICS输出时钟源做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模式,对选中的ICS输出时钟源做2分频
- * OSC模块的输出时钟选择振荡器时钟源
- *
- * @ 参数 pConfig 指向ICS的配置结构体 .
- *
- * @ 无返回
- *
- * @ 成功/失败的标准 :无
- * @ 参看 ICS_ConfigType
- *****************************************************************************/
- 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->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参考时钟成为外部时钟*/
-
- /*
- * 现在外部时钟成为ICS输出时钟源
- */
- #if defined(CPU_NV32)
- /*对选中的ICS输出时钟源做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输出时钟频率为选中的输出时钟源的2分频
- */
- /* LOLS清零 */
- ICS->S |= ICS_S_LOLS_MASK;
- }
- /*****************************************************************************//*!
- *
- * @ 概要 ICS的工作模式由当前的FEI模式转换成FBE模式,对选中的输出时钟源做2分频
- * OSC输出时钟选择EXTAL引脚的外部时钟源
- *
- * @ 参数 pConfig 指向配置结构体.
- *
- * @ 无返回
- *
- * @ 成功/失败的标准 :无
- * @ 参看 ICS_ConfigType
- *****************************************************************************/
- void FEI_to_FBE_OSC(ICS_ConfigType *pConfig)
- {
-
- OSC_Init(&pConfig->oscConfig); /* 初始化OSC */
- /*
- * 设置外部参考时钟的分频系数,将参考时钟的分频结果设定在FLL可以锁定的31.25k~39.0625k范围内,
- */
- ICS_SetClkDivider(pConfig->u32ClkFreq);
-
- /*改变参考时钟源,将FLL的参考时钟设置为而外部时钟*/
- 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)
- /*对选中的ICS输出时钟源做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的输出时钟频率,为外部参考时钟的2分频
- */
- /*LOLS 清零*/
- ICS->S |= ICS_S_LOLS_MASK;
- }
- /*****************************************************************************//*!
- *
- * @ 概要 ICS的工作模式由当前的FEI模式转换FEE模式,对选中的ICS输出时钟源做2分频
- * OSC输出时钟选择EXTAL引脚的外部时钟源
- *
- * @ 参数 pConfig 指向配置结构体
- *
- * @ 无返回
- *
- * @ 成功/失败的标准 :无
- * @ 参看 ICS_ConfigType
- *****************************************************************************/
- void FEI_to_FEE_OSC(ICS_ConfigType *pConfig)
- {
- OSC_Init(&pConfig->oscConfig); /* 初始化OSC */
- /*
- * 设置外部参考时钟的分频系数,将参考时钟的分频结果设定在FLL可以锁定的31.25k~39.0625k范围内
- */
- 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成为ICS输出时钟源 */
- 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
- /*
- * 现在ICS输出时钟频率,成为要设置的目标频率
- */
- /* LOLS清零 */
- ICS->S |= ICS_S_LOLS_MASK;
- }
- /*****************************************************************************//*!
- *
- * @ 概要 将ICS的工作模式由当前的FEE模式转换成FEI模式.
- *
- * @ 参数 pConfig 指向配置结构体
- *
- * @ 无返回
- *
- * @ 成功/失败的标准 :无
- * @ 参看 ICS_ConfigType
- *****************************************************************************/
- 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)
- /*对选中的ICS输出时钟源做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 指向配置结构体
- *
- * @ 无返回
- *
- * @ 成功/失败的标准 :无
- * @ 参看 ICS_ConfigType
- *****************************************************************************/
- void FEE_to_FBI(ICS_ConfigType *pConfig)
- {
- /*LOLS清零*/
- ICS->S |= ICS_S_LOLS_MASK;
-
- /* 选择内部时钟作为ICS输出时钟源 */
- /* 选择内部时钟作为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)
- /*对所选中的ICS输出时钟源做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 指向配置结构体
- *
- * @ 无返回
- *
- * @ 成功/失败的标准 :无
- * @ 参看 ICS_ConfigType
- *****************************************************************************/
- void FEE_to_FBE(ICS_ConfigType *pConfig)
- {
- /*LOLS清零*/
- ICS->S |= ICS_S_LOLS_MASK;
-
-
- /* LP = 0 */
- /*选择外部时钟作为ICS输出时钟源*/
- /* 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输出时钟源选择外部时钟源
- * 注释: 确保外部时钟频率在20MHz以内
- */
- #if defined(CPU_NV32)
- /*对选择的ICS输出时钟源做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 指向配置结构体.
- *
- * @ 无返回
- *
- * @ 成功/失败的标准 :无
- * @ 参看 ICS_ConfigType
- *****************************************************************************/
- 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); /*外部时钟成为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
- }
- /*****************************************************************************//**
- *
- * @ 概要 将ICS的工作模式由当前的FBI模式转换成FEE模式
- *
- * @ 参数 pConfig 指向配置结构体
- *
- * @ 无返回
- *
- * @ 成功/失败的标准 :无
- * @ 参看 ICS_ConfigType
- *****************************************************************************/
- 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 输出指向配置结构体
- *
- * @ 无返回
- *
- * @ 成功/失败的标准 :无
- * @ 警告 必须运行在调试接口没有没有接线的状态下
- * @ 参看 ICS_ConfigType
- *****************************************************************************/
- void FBI_to_FBILP(ICS_ConfigType *pConfig)
- {
- /*
- * 假设外部晶振时8MHz或者4MHz
- */
- ICS->C2 |= ICS_C2_LP_MASK; /*进入低功耗模式 */
- }
- /*****************************************************************************//*!
- *
- * @ 概要 将ICS的工作模式由当前的FBI模式转变为FEI模式
- *
- * @ 参数 pConfig 指向配置结构体.
- *
- * @ 无返回
- *
- * @ 成功/失败的标准 :无
- * @ 参看 ICS_ConfigType
- *****************************************************************************/
- 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的参考时钟选择为外部时钟*/
-
- /*
- * 现在ICS输出时钟源为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 指向配置结构体
- *
- * @ 无返回
- *
- * @ 成功/失败的标准 :无
- * @ 参看 ICS_ConfigType
- *****************************************************************************/
- 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的参考时钟*/
-
- /*
- * 现在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
-
- /*
- * 禁用OSC模块
- */
- OSC_Disable();
- }
- /*****************************************************************************//*!
- *
- * @ 概要 将ICS的工作模式由当前的FBE模式转换成FEE模式
- *
- * @ 参数 pConfig 指向配置结构体.
- *
- * @ 无返回
- *
- * @ 成功/失败的标准 :无
- * @ 参看 ICS_ConfigType
- *****************************************************************************/
- void FBE_to_FEE(ICS_ConfigType *pConfig)
- {
-
- /*选择FLL输出作为输出时钟源*/
- ICS->C1 = (ICS->C1 & ~(ICS_C1_CLKS_MASK));
-
- /*等待ICS输出时钟源发生改变*/
- #if defined(IAR)
- asm(
- "nop \n"
- "nop \n"
- );
- #elif defined(__MWERKS__)
- asm{
- nop
- nop
- };
- #endif
- while(ICS->S & ICS_S_CLKST_MASK);
-
- /*
- * 现在ICS输出时钟源为FLL输出
- * 注释: 外部时钟频率 <= 20MHz
- */
- #if defined(CPU_NV32)
- /*对选中的ICS输出时钟源做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 指向配置结构体
- *
- * @ 无返回
- *
- * @ 成功/失败的标准 :无
- * @ 参看 ICS_ConfigType
- *****************************************************************************/
- 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输出成为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
- /*LOLS清零*/
- ICS->S |= ICS_S_LOLS_MASK;
-
- /*
- *禁用OSC模块
- */
- OSC_Disable();
- }
- /*****************************************************************************//*!
- *
- * @ 概要 将ICS的工作模式由当前的FBE模式转变为FBELP模式
- *
- * @ 参数 pConfig 指向配置结构体.
- *
- * @ 无返回
- *
- * @ 成功/失败的标准 :无
- * @ 参看 ICS_ConfigType
- *****************************************************************************/
- void FBE_to_FBELP(ICS_ConfigType *pConfig)
- {
- /* enter low power mode */
- /*进入低功耗模式*/
- ICS->C2 = ICS->C2 | (ICS_C2_LP_MASK);
- }
- /*****************************************************************************//*!
- *
- * @ 概要 将ICS的工作模式由当前的FBELP模式转换成FBE模式
- *
- * @ 参数 pConfig 指向配置结构体.
- *
- * @ 无返回
- *
- * @ 成功/失败的标准 :无
- * @ 参看 ICS_ConfigType
- *****************************************************************************/
- void FBELP_to_FBE(ICS_ConfigType *pConfig)
- {
- /* enter low power mode */
- /*禁用低功耗模式*/
- ICS->C2 = ICS->C2 & ~(ICS_C2_LP_MASK);
- }
- /*****************************************************************************//*!
- *
- * @ 概要 将ICS的工作模式由当前的FBILP转换到FBI模式
- *
- * @ 参数 pConfig 指向配置结构体.
- *
- * @ 无返回
- *
- * @ 成功/失败的标准 :无
- * @ 参看 ICS_ConfigType
- *****************************************************************************/
- void FBILP_to_FBI(ICS_ConfigType *pConfig)
- {
- /* enter low power mode */
- /*禁用低功耗模式*/
- ICS->C2 = ICS->C2 & ~(ICS_C2_LP_MASK);
- }
- /*****************************************************************************//*!
- *
- * @ 概要 调整内部内部时钟 (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));
- }
- /*****************************************************************************//*!
- *
- * @ 概要 对外部参考时钟进行分频,使得分频结果在FLL可以锁定的31.25k~39.0625k内
- *
- * @ 参数 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);
- /*8MHz分频结果是 8000/256 = 31.25K */
- /*10MHz分频结果是 8000/256 = 31.25K*/
- break;
- case 4000L:
- /* 4MHz */
- ICS->C1 = (ICS->C1 & ~(ICS_C1_RDIV_MASK)) | ICS_C1_RDIV(2);
- /*4MHz分频结果是 4000/128 = 31.25K*/
- break;
- case 12000L:
- /* 12MHz */
- ICS->C1 = (ICS->C1 & ~(ICS_C1_RDIV_MASK)) | ICS_C1_RDIV(3);
- /*12MHz分频结果是12000/512 = 23.43K*/
- break;
- case 16000L:
- /* 16MHz */
- ICS->C1 = (ICS->C1 & ~(ICS_C1_RDIV_MASK)) | ICS_C1_RDIV(4);
- /* 16MHz分频结果是 16000/512 = 31.25K */
- break;
- case 20000L:
- /* 20MHz */
- ICS->C1 = (ICS->C1 & ~(ICS_C1_RDIV_MASK)) | ICS_C1_RDIV(4);
- /*20MHz分频结果是 20000/512 = 39.0625K */
- break;
- case 32L:
- /* 32KHz */
- ICS->C1 &= ~(ICS_C1_RDIV_MASK);
- break;
- default:
- break;
- }
- }
- /*****************************************************************************//*!
- *
- * @ 概要 初始化ICS模块根据定义所需要的总线时钟频率.
- *
- * @ 参数 pConfig 指向配置结构体.
- *
- * @ 无返回
- *
- * @ 成功/失败的标准 :无
- * @ 参看 ICS_ConfigType
- *****************************************************************************/
- void ICS_Init(ICS_ConfigType *pConfig)
- {
- if(pConfig->u8ClkMode == ICS_CLK_MODE_FEE)
- {
- pConfig->oscConfig.bIsCryst = 1; /* OSC的输出选择选择振动器时钟源 */
- pConfig->oscConfig.bWaitInit = 1; /* 等待振荡器初始化化完成 */
-
- /*选择FEE模式,OSC输出选择振荡器时钟源*/
- FEI_to_FEE(pConfig);
- }
- else if (pConfig->u8ClkMode == ICS_CLK_MODE_FEE_OSC)
- {
- pConfig->oscConfig.bIsCryst = 0; /*OSC输出时钟选择EEXTAL引脚的外部时钟源*/
- /*选择FEE工作模式;OSC输出时钟选择EEXTAL引脚的外部时钟源*/
- FEI_to_FEE_OSC(pConfig);
- }
- else if (pConfig->u8ClkMode == ICS_CLK_MODE_FBE_OSC)
- {
- pConfig->oscConfig.bIsCryst = 0; /* is clock:OSC输出时钟选择EXTAL引脚的外部时钟源 */
- /* 选择FBE工作模式;OSC输出时钟选择EXTAL引脚的外部时钟源*/
- FEI_to_FBE_OSC(pConfig);
- }
- else if(pConfig->u8ClkMode == ICS_CLK_MODE_FBELP )
- {
- pConfig->oscConfig.bIsCryst = 1; /* OSC的输出时钟选择选择振动器时钟源 */
- pConfig->oscConfig.bWaitInit = 1; /*等待振荡器初始化化完成 */
- /* 选择FBE模式,OSC的输出时钟选择选择振动器时钟源*/
- 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 )
- {
-
- /* OSC输出时钟选择EXTAL引脚的外部时钟源*/
- pConfig->oscConfig.bIsCryst = 0;
-
- /* 选择FBE模式,OSC输出时钟选择EXTAL引脚的外部时钟源*/
- FEI_to_FBI(pConfig);
- FBI_to_FBILP(pConfig);
- ICS->C2 = (ICS->C2 & ~(ICS_C2_BDIV_MASK)) | ICS_C2_BDIV(0);
- }
- else
- {
-
- /*ICS默认工作模式FEI模式*/
- #if defined(CPU_NV32)
- if(((ICS->C2 & ICS_C2_BDIV_MASK)>>5) == 1)
- {
- ICS->C2 = (ICS->C2 & ~(ICS_C2_BDIV_MASK)) | ICS_C2_BDIV(0);
- }
- #else
- ICS->C2 = (ICS->C2 & ~(ICS_C2_BDIV_MASK)) | ICS_C2_BDIV(0);
- #endif
- }
- }
- /*****************************************************************************//*!
- *
- * @ 概要 对ICS模块各寄存器进行复位.
- *
- * @ 无参数
- *
- * @ 无返回
- *
- * @ 成功/失败的标准 :无
- * @ 参看 ICS_Init
- *****************************************************************************/
- 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)
- ;
- }
- /*****************************************************************************//*!
- *
- * @ 概要 通过设定的参数初始化XOSC
- *
- * @ 参数 pConfig 指向osc配置结构体
- *
- * @ 无返回
- *
- * @ 成功/失败的标准 :无
- *****************************************************************************/
- void OSC_Init(OSC_ConfigType *pConfig)
- {
- uint8 cr = 0;
- /*
- *
- */
- if(pConfig->bGain) /*高增益振荡器选择*/
- {
- /* high gain:选择高增益模式 */
- cr |= OSC_CR_HGO_MASK ;
- }
-
- 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)
- {
- /*
- *等待初始化完成
- */
- while(!(OSC->CR & OSC_CR_OSCINIT_MASK));
-
- }
- }
- /*****************************************************************************//*!
- *
- * @ 概要 重置OSC模块,使其恢复到默认状态.
- *
- * @ 无输参数
- *
- * @ 无返回
- *
- * @ 成功/失败的标准 :无
- * @ 参看 ICS_Init
- *****************************************************************************/
- void OSC_DeInit(void)
- {
- OSC->CR = OSC_CR_DEFAULT;
- }
-
|