HC32F460 内部高速时钟(HRC)的使用
HRC 时钟
HRC时钟信号由内部高速振荡器生成,可直接用作系统时钟,或者用作MPLL/UPLL输入。HRC的频率可由 ICG1. HRCFREQSEL配置成16MHz 或者 20MHz。
在前文中我们使用了xtal作为时钟输入,xtal精度高,但是需要使用外部晶振。既然HC32内部提供了数个时钟,直接使用内部时钟更方便。
输入MPLL
HRC时钟虽然可以直接提供时钟,但是其最大仅有20Mhz,若想芯片最大频率运行,还是需要MPLL分频在倍频使用。
配置代码如下,主要是修改了XTAL为HRC。
ClkHrcInit
/**
*******************************************************************************
** \brief Initialize Clock, use HRC.
**
** \param [in] None
**
** \retval None
**
******************************************************************************/
void ClkHrcInit(void)
{
stc_clk_mpll_cfg_t stcMpllCfg;
en_clk_sys_source_t enSysClkSrc;
stc_clk_sysclk_cfg_t stcSysClkCfg;
MEM_ZERO_STRUCT(enSysClkSrc);
MEM_ZERO_STRUCT(stcSysClkCfg);
MEM_ZERO_STRUCT(stcMpllCfg);
/* Set bus clk div. */
stcSysClkCfg.enHclkDiv = ClkSysclkDiv1;
stcSysClkCfg.enExclkDiv = ClkSysclkDiv2;
stcSysClkCfg.enPclk0Div = ClkSysclkDiv1;
stcSysClkCfg.enPclk1Div = ClkSysclkDiv2;
stcSysClkCfg.enPclk2Div = ClkSysclkDiv4;
stcSysClkCfg.enPclk3Div = ClkSysclkDiv4;
stcSysClkCfg.enPclk4Div = ClkSysclkDiv2;
CLK_SysClkConfig(&stcSysClkCfg);
/* Switch system clock source to MPLL. */
CLK_HrcCmd(Enable);//使能HRC时钟
/* MPLL config. */
stcMpllCfg.pllmDiv = 16u; /* HRC 16M / 16=1M */
stcMpllCfg.plln = 400u; /* 4M*100 = 400M */
stcMpllCfg.PllpDiv = 2u; /* MLLP = 200M */
stcMpllCfg.PllqDiv = 2u; /* MLLQ = 200M */
stcMpllCfg.PllrDiv = 2u; /* MLLR = 200M */
CLK_SetPllSource(ClkPllSrcHRC);
CLK_MpllConfig(&stcMpllCfg);
/* flash read wait cycle setting */
EFM_Unlock();
EFM_SetLatency(EFM_LATENCY_4);
EFM_Lock();
/* Enable MPLL. */
CLK_MpllCmd(Enable);
/* Wait MPLL ready. */
while (Set != CLK_GetFlagStatus(ClkFlagMPLLRdy))
{
}
/* Switch system clock source to MPLL. */
CLK_SetSysClkSource(CLKSysSrcMPLL);
}
配置HRC
HRC时钟频率为16Mhz或20Mhz,默认为16Mhz。如果要使用20Mhz的话,需要根据手册要求,修改ICG1. HRCFREQSEL
SDK使用hc32f46x_icg.c
文件配置该寄存器,因此在hc32f46x_icg.h
中修改定义即可。
在334-350行中定义了HRC。
/**
*******************************************************************************
** \brief HRC hardware start configuration
******************************************************************************/
/*!< Enable or disable HRC hardware start */
#define ICG1_HRC_HARDWARE_START (ICG_FUNCTION_OFF)
/*!< HRC register config */
#define ICG1_HRC_FREQSEL (HRC_FREQUENCY_16MHZ)
#define ICG1_HRC_STOP (HRC_OSCILLATION_START)
/*!< HRC register config value */
#if ICG1_HRC_HARDWARE_START == ICG_FUNCTION_ON
#define ICG1_HRC_REG_CONFIG (ICG1_HRC_FREQSEL | ICG1_HRC_STOP)
#else
#define ICG1_HRC_REG_CONFIG ((uint16_t)0xFFFF)
#endif
默认HRC宏定义是关闭的,需要修改ICG_FUNCTION_OFF
为ICG_FUNCTION_ON
来开启,然后修改HRC_FREQUENCY_16MHZ
为·
HRC_FREQUENCY_20MHZ
即可切换到20Mhz。
然后修改分频系数,运行,一切正常。
示波器抓下串口数据,稳定12.5Mhz
如果需要微调时钟,可以在进行修改。
#if !defined (HRC_16MHz_VALUE)
#define HRC_16MHz_VALUE ((uint32_t)16000000UL) /*!< Internal high speed RC freq.(16MHz) */
#endif
#if !defined (HRC_20MHz_VALUE)
#define HRC_20MHz_VALUE ((uint32_t)20000000UL) /*!< Internal high speed RC freq.(20MHz) */
#endif
甚至在这里直接将16Mhz值修改为20Mhz,不进行ICG配置,也能以20Mhz频率使用,串口也很稳,但是会产生什么Bug就不清楚了。