打印
[demo程序]

NV32F100x 库文件ics.c中文注释

[复制链接]
1239|1
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
jp_chen|  楼主 | 2017-7-26 16:43 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
/*****************************************************************************
* [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
}

相关帖子

沙发
jp_chen|  楼主 | 2017-7-26 16:44 | 只看该作者
/*****************************************************************************//**
*
* @ 将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

粉丝