1.当 HSE 故障的时候,如果 PLL 的时钟来源是 HSE,那么当 HSE 故障的时候,不仅
HSE 不能使用,连 PLL 也会被关闭,这个时候系统会自动切换 HSI 作为系统时钟,此时
SYSCLK=HSI=8M,如果没有开启 CSS 和 CSS 中断的话,那么整个系统就只能在低速率运
行,这是系统跟瘫痪没什么两样。如果开启了 CSS 功能的话,那么可以当 HSE 故障时,在
CSS 中断里面采取补救措施,使用 HSI,并把系统时钟设置为更高的频率,最高是 64M,
64M 的频率足够一般的外设使用,如:ADC 、SPI、I2C 等。但是这里就又有一个问题了,
原来 SYSCLK=72M,现在因为故障改成 64M,那么那些外设的时钟肯定被改变了,那么外
设工作就会被打乱,那我们是不是在设置 HSI 时钟的时候,也重新调整外设总线的分频因
子,即 AHB,APB2 和 APB1 的分频因子,使外设的时钟达到跟 HSE 没有故障之前一样。
但是这个也不是最保障的办法,毕竟不能一直使用 HSI,所以当 HSE 故障时还是要采取报
警措施。下面我们给出个使用 HSI 配置系统时钟例子。
2.使用 HSI 配置系统时钟
void SetSysClock(void)
{
__IO uint32_t HSIStartUpStatus = 0;
RCM_Reset();
RCM_EnableHSI();
HSIStartUpStatus = RCM->CTRL_B.HSIRDY**;
if (HSIStartUpStatus == SUCCESS)
{
FMC_EnablePrefetchBuffer();
FMC_ConfigLatency(FMC_LATENCY_2);
RCM_ConfigAHB(RCM_AHB_DIV_1);
RCM_ConfigAPB2(RCM_APB_DIV_1);
RCM_ConfigAPB1(RCM_APB_DIV_2);
RCM_ConfigPLL(RCM_PLLSEL_HSI_DIV_2, RCM_PLLMF_16);//16倍频
RCM_EnablePLL();
while (RCM_ReadStatusFlag(RCM_FLAG_PLLRDY) == RESET);
RCM_ConfigSYSCLK(RCM_SYSCLK_SEL_PLL);
while (RCM_ReadSYSCLKSource() != RCM_SYSCLK_SEL_PLL);
}
else
{
while (1);
}
}
3.注意点:
(1) RCM_ConfigPLL(RCM_PLLSEL_HSI_DIV_2, RCM_PLLMF_16);//16倍频
此条语句使用了最大的16倍频,HSI是2分频之后才被选择作为PLL时钟源的,接着后面再经过倍频,
倍频可以是根据自己选择,最大是16倍频,所以HSI的最大频率是64M,使用的时候要特别注意一点。
(2) FMC_ConfigLatency(FMC_LATENCY_2);
此条语句是作为等待周期的设置的,当频率在0 ~24MHZ的时候,使用0等待周期,在24~48MHZ的时候,
使用1等待周期,在48~72MHZ的时候,使用2等待周期,我们设置的HSI是64MHZ,使用2等待周期就可以了,
如果HSI改为48MHZ,建议改为1等待周期。
(3)else 语句后面可以自己添加一些语句。
如果 HSI 开启失败,那么程序就会来到这里,用户可在这里添加出错的代码处理,比如做一个标志位,当
HSI失败的时候,就可以检查这个标志位。 |