时钟图
HC的时钟可以分为外部时钟和内部时钟。
外部时钟有分为外部高速时钟(XTAL)和外部低速时钟(XTAL32),外部的高速时钟的范围为4~24M ,外部的低速时钟时钟频率为特定的32.768K。
内部时钟可以根据选择的频率分内部高中低振荡器,分别为HRC、MRC、LRC,
- HRC
HRC的频率在16M到20M之间,用户可以通过寄存器进行更改。 - MRC
MRC的频率8M,用户可以通过寄存器进行更改。 - LRC
LRC的频率的32.768kHz。
单片机在上电后,如果不进行时钟切换,默认使用内部的中速时钟8MHZ。
PLLH 时钟:
- 输入时钟:外部高速振荡器或者内部高速振荡器
- PLLH 输入时钟分频: 1~4 任意分频可选
- PFD 输入时钟频率=输入时钟/PLLH 输入时钟分频,频率范围
8MHz~24MHz - **PLLH 倍频系数: 25~150 倍
- VCO 振荡频率: 600MHz~1200MHz**
- PLLHQ 输出分频比: 2~16 任意分频
- PLLHP 输出分频比: 2~16 任意分频
- PLLHR 输出分频比: 2~16 任意分频
- PLLHP 输出频率=(输入时钟/PLLH 输入时钟分频) *PLLH 倍频系
数/PLLHP 输出分频比 - PLLHQ 输出频率=(输入时钟/PLLH 输入时钟分频) *PLLH 倍频
系数/PLLHQ 输出分频比 - PLLHR 输出频率=(输入时钟/PLLH 输入时钟分频) *PLLH 倍频系
数/PLLHR 输出分频比
注意1:PLLH的倍频系数必须在范围之内,不然在库函数的判断是会报错,并且倍频后范围必须在VCO 振荡频率: 600MHz~1200MHz的范围内。
- PLLA
- 输入时钟:外部高速振荡器或者内部高速振荡器
- PLLA 输入时钟分频: 1~24 任意分频可选
- PFD 输入时钟频率=输入时钟/PLLA 输入时钟分频,频率范围
1MHz~24MHz - PLLA 倍频系数: 20~480 倍
- VCO 振荡频率: 240MHz~480MHz
- PLLAP 输出分频比: 2~16 任意分频
- PLLAQ 输出分频比: 2~16 任意分频
- PLLAR 输出分频比: 2~16 任意分频
- PLLAP 输出频率=(输入时钟/PLLA 输入时钟分频) *PLLA 倍频系
数/PLLAP 输出分频比 - PLLAQ 输出频率=(输入时钟/PLLA 输入时钟分频) *PLLA 倍频
系数/PLLAQ 输出分频比 - PLLAR 输出频率=(输入时钟/PLLA 输入时钟分频) *PLLA 倍频系
数/PLLAR 输出分频比
PLLH 和PLLA时钟在输入的分频系数、PFD的输入时钟频率、倍频系数和倍频后的振荡频率范围是存在差异的在进行配置的是后要注意各自的范围,否则在库函数中的ASSert中报错。
HC的工作时钟
不同外部时钟的初始化
/**
* @brief Xtal initialize
* @param None
* @retval None
*/
en_result_t XtalInit(void)
{
stc_clk_xtal_init_t stcXtalInit;
/* Xtal config */
CLK_XtalStrucInit(&stcXtalInit);
stcXtalInit.u8XtalState = CLK_XTAL_ON;
stcXtalInit.u8XtalDrv = CLK_XTALDRV_LOW;
stcXtalInit.u8XtalMode = CLK_XTALMODE_OSC;
stcXtalInit.u8XtalStb = CLK_XTALSTB_499US;
return CLK_XtalInit(&stcXtalInit);
}
/**
* @brief Xtal32 initialize
* @param None
* @retval None
*/
en_result_t Xtal32Init(void)
{
stc_clk_xtal32_init_t stcXtal32Init;
/* Xtal32 config */
CLK_Xtal32StrucInit(&stcXtal32Init);
stcXtal32Init.u8Xtal32State = CLK_XTAL32_ON;
stcXtal32Init.u8Xtal32Drv = CLK_XTAL32DRV_MID;
stcXtal32Init.u8Xtal32NF = CLK_XTAL32NF_FULL;
return CLK_Xtal32Init(&stcXtal32Init);
}
/**
* @brief PLLH initialize
* @param uPLLM: 分频
uPLLN 备频
uPLLR 分频
uPLLQ 分配
uPLLP 分频
* @retval None
*/
en_result_t PLLHInit(uint16 uPLLM, uint16 uPLLN, uint16 uPLLR, uint16 uPLLQ, uint16 uPLLP)
{
stc_clk_pllh_init_t stcPLLHInit;
/* PCLK0, HCLK Max 240MHz */
/* PCLK1, PCLK4 Max 120MHz */
/* PCLK2, PCLK3 Max 60MHz */
/* EX BUS Max 120MHz */
CLK_ClkDiv(CLK_CATE_ALL, \
(CLK_PCLK0_DIV1 | CLK_PCLK1_DIV2 | CLK_PCLK2_DIV4 | \
CLK_PCLK3_DIV4 | CLK_PCLK4_DIV2 | CLK_EXCLK_DIV2 | \
CLK_HCLK_DIV1));
/* Highspeed SRAM set to 1 Read/Write wait cycle */
SRAM_SetWaitCycle(SRAM_SRAMH, SRAM_WAIT_CYCLE_1, SRAM_WAIT_CYCLE_1);
/* SRAM1_2_3_4_backup set to 2 Read/Write wait cycle */
SRAM_SetWaitCycle((SRAM_SRAM123 | SRAM_SRAM4 | SRAM_SRAMB), SRAM_WAIT_CYCLE_2, SRAM_WAIT_CYCLE_2);
EFM_SetWaitCycle(EFM_WAIT_CYCLE_5);
/* PLLH config */
CLK_PLLHStrucInit(&stcPLLHInit);
/*
8MHz/M*N = 8/1*120/4 =240MHz
*/
stcPLLHInit.u8PLLState = CLK_PLLH_ON;
stcPLLHInit.PLLCFGR = 0UL;
stcPLLHInit.PLLCFGR_f.PLLM = (uPLLM - 1UL);
stcPLLHInit.PLLCFGR_f.PLLN = (uPLLN - 1UL);
stcPLLHInit.PLLCFGR_f.PLLR = (uPLLR - 1UL);//60MHZ
stcPLLHInit.PLLCFGR_f.PLLQ = (uPLLQ - 1UL);
stcPLLHInit.PLLCFGR_f.PLLP = (uPLLP - 1UL);
stcPLLHInit.PLLCFGR_f.PLLSRC = CLK_PLLSRC_XTAL; /* Xtal = 8MHz */
return CLK_PLLHInit(&stcPLLHInit);
}
真正对时钟起到最终选择的是CLK_SetSysClkSrc(CLK_SYSCLKSOURCE_PLLH);函数,通过该函数决定了最终的运行频率。
CLK_GetPllClockFreq() 函数能够获取当前系统的市政频率状况。