1. 选择CK_HXTAL做PLL时钟源时,GD LIB SystemInit处理如下
注意红框内注释部分为GD LIB库处理代码,此处风险为当外挂晶振故障时,代码在此处陷入死循环
2. 处理方式
注意:MCU上电时默认使用IRC 8M做CK_SYS
2.1 修改GD LIB库system_clock_120m_hxtal函数,当HXTAL故障处理时不进行死循环,直接return
2.2 在main函数检测HXTAL是否故障,如果故障,则启用IRC 8M做PLL时钟源进行倍频至120M,如果倍频失败则
更新SystemCoreClock,此时SystemCoreClock为IRC 8M
2.3 system_clock_120m_irc8m代码如下
static void system_clock_120m_irc8m(void)
{
uint32_t timeout = 0U;
uint32_t stab_flag = 0U;
/* enable IRC8M */
RCU_CTL |= RCU_CTL_IRC8MEN; /* wait until IRC8M is stable or the startup time is longer than IRC8M_STARTUP_TIMEOUT */
do{
timeout++;
stab_flag = (RCU_CTL & RCU_CTL_IRC8MSTB);
}while((0U == stab_flag) && (IRC8M_STARTUP_TIMEOUT != timeout)); /* if fail */
if(0U == (RCU_CTL & RCU_CTL_IRC8MSTB)){//做同样处理
// while(1){
// }
return;//neoway add
} /* LDO output voltage high mode */
RCU_APB1EN |= RCU_APB1EN_PMUEN;
PMU_CTL |= PMU_CTL_LDOVS; /* IRC8M is stable */
/* AHB = SYSCLK */
RCU_CFG0 |= RCU_AHB_CKSYS_DIV1;
/* APB2 = AHB/1 */
RCU_CFG0 |= RCU_APB2_CKAHB_DIV1;
/* APB1 = AHB/2 */
RCU_CFG0 |= RCU_APB1_CKAHB_DIV2; /* CK_PLL = (CK_IRC8M/2) * 30 = 120 MHz */
RCU_CFG0 &= ~(RCU_CFG0_PLLMF | RCU_CFG0_PLLMF_4 | RCU_CFG0_PLLMF_5);
RCU_CFG0 |= RCU_PLL_MUL30; /* enable PLL */
RCU_CTL |= RCU_CTL_PLLEN; /* wait until PLL is stable */
while(0U == (RCU_CTL & RCU_CTL_PLLSTB)){
}
/* enable the high-drive to extend the clock frequency to 120 MHz */
PMU_CTL |= PMU_CTL_HDEN;
while(0U == (PMU_CS & PMU_CS_HDRF)){
}
/* select the high-drive mode */
PMU_CTL |= PMU_CTL_HDS;
while(0U == (PMU_CS & PMU_CS_HDSRF)){
}
/* select PLL as system clock */
RCU_CFG0 &= ~RCU_CFG0_SCS;
RCU_CFG0 |= RCU_CKSYSSRC_PLL; /* wait until PLL is selected as system clock */
while(0U == (RCU_CFG0 & RCU_SCSS_PLL)){
}
} 2.4 IRC 48M也可作为PLL时钟源,未进行测试
|