stm8s003_切换时钟流程分析、配置外部晶振(库函数调用)

1、stm8s003的时钟

stm8s003_切换时钟流程分析、配置外部晶振(库函数调用)_第1张图片

复位后,默认使用内部高速时钟HSI(16MHz)的8分频,也就是2MHz.

代码开始运行,也就是运行到main函数,我们就可以修改时钟源为外部晶振。

2、切换时钟流程分析,参考官方应用手册

stm8s003_切换时钟流程分析、配置外部晶振(库函数调用)_第2张图片

9.2.2,介绍了主时钟切换的流程,分为自动切换和手动切换,这里只看自动切换。

1)开启切换时钟源使能;

2)选择目标时钟源,也就是外部晶振,这一步是写到CLK_SWR,S代表选择,并不是真正的切换时钟源;

        此时SWBSY硬件置位,虽然外部晶振开启,但是旧的时钟源仍然运行;

3)等待外部晶振稳定;

4)第四步是自动硬件自动切换的,在SWBSY硬件清零之后,刚才CLK_SWR的值被硬件写入CLK_CMSR,系统切换到外部晶振;

再补充一个流程图,可以看得更清楚:

stm8s003_切换时钟流程分析、配置外部晶振(库函数调用)_第3张图片

3、代码

我使用的是库函数,调用CLK_ClockSwitchConfig一句话就行。

这个函数内部我也进去看了,步骤都有,等待稳定的超时是0x491(十进制1169)个时钟周期,并且可以选择是否关掉旧的时钟;

    clk_return_status = CLK_ClockSwitchConfig(CLK_SWITCHMODE_AUTO, CLK_SOURCE_HSE, DISABLE, CLK_CURRENTCLOCKSTATE_DISABLE);
    if (clk_return_status != SUCCESS){          //SUCCESS or ERROR
        //开启失败的一些操作
    }

4、CLK_ClockSwitchConfig最后一个参数,是否关闭旧的时钟

疑问,如果外部晶振开启失败了,又关闭了旧的时钟,会不会不能往下运行?

验证:把外部晶振取下,模拟开启失败的情况。

现象:不管是关闭旧时钟CLK_CURRENTCLOCKSTATE_DISABLE,还是不关闭旧时钟CLK_CURRENTCLOCKSTATE_ENABLE,程序都能继续往下执行,并且时钟频率为旧的时钟频率。

注:如果在开启外部晶振前,把内部时钟的分频调成1(16MHz),那么外部晶振开启失败后时钟频率还是16MHz;

设置这个用处就是,可以先把内部时钟频率调成和外部一样的,比如分频2调成8MHz,这样即使外部晶振没有起振,程序也不会有较大的影响(可以留一个信息让自己知道外部晶振是没有成功开启的);

验证代码如下:

void main(void)
{
    u8 i;
    ErrorStatus clk_return_status;  
      
    /* Initialize I/Os in Output Mode */
    GPIO_Init(LED_GPIO_PORT, (GPIO_Pin_TypeDef)LED_GPIO_PINS, GPIO_MODE_OUT_PP_LOW_FAST); 
 
    //默认8分频,内部2MHz,翻转10次,慢速
    for(i=0;i<10;i++){
        /* Toggles LEDs */
        GPIO_WriteReverse(LED_GPIO_PORT, (GPIO_Pin_TypeDef)LED_GPIO_PINS);
        Delay(0xffff);  
    }
    GPIO_WriteHigh(LED_GPIO_PORT,LED_GPIO_PINS);
  
    //2分频,内部8MHz
    CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV2);
    for(i=0;i<10;i++){
        /* Toggles LEDs */
        GPIO_WriteReverse(LED_GPIO_PORT, (GPIO_Pin_TypeDef)LED_GPIO_PINS);
        Delay(0xffff);  
    }
    GPIO_WriteHigh(LED_GPIO_PORT,LED_GPIO_PINS); 
  
    //开启外部8MHz晶振
    clk_return_status = CLK_ClockSwitchConfig(CLK_SWITCHMODE_AUTO, CLK_SOURCE_HSE, DISABLE, CLK_CURRENTCLOCKSTATE_DISABLE);
    if (clk_return_status != SUCCESS){          //SUCCESS or ERROR
        //开启失败,常亮一会提示
        GPIO_WriteLow(LED_GPIO_PORT,LED_GPIO_PINS);
        for(i=0;i<30;i++){
            Delay(0xffff);
        }
    }  
    
    while (1){   
        GPIO_WriteReverse(LED_GPIO_PORT, (GPIO_Pin_TypeDef)LED_GPIO_PINS);
        Delay(0xffff);         
    } 
}

你可能感兴趣的:(STM8/STM32,单片机,嵌入式硬件,stm8,时钟,外部晶振)