Bootstrap

stm8s单片机(三)时钟系统与时钟切换

一个单片机系统要正常运行应包括四个部分: 电源,晶振,复位电路,下载电路。
晶振就是时钟。
stm8有四种时钟源

  1. HSE (High Speed External clock signal)
  2. HSE user-ext (High Speed External clock signal user external)
  3. HSI (High Speed Internal clock signal)
  4. LSI (Low Speed Internal clock signal )

HSE

由外部晶振产生,输入占空比50%的方波,三角波,正弦波,频率1~24MHZ

HSI

HSI信号由内部16MHz RC 振荡器与一个可编程分频器产生

LSI

128kHz LSI RC 时钟,低功耗,低成本的可选主时钟源

时钟安全CCS

当CPU使用HSE作为时钟源时,当HSE失效时会自动切换到HSI。

相关API

/**
  * @brief  Starts or Stops manually the clock switch execution.
  * @par Full description:
  * NewState parameter set the SWEN.
  * @param   NewState new state of SWEN, value accepted ENABLE, DISABLE.
  * @retval None
  */
void CLK_ClockSwitchCmd(FunctionalState NewState);
/**
  * @brief  configures the Switch from one clock to another
  * @param   CLK_SwitchMode select the clock switch mode.
  * It can be set of the values of @ref CLK_SwitchMode_TypeDef
  * @param   CLK_NewClock choice of the future clock.
  * It can be set of the values of @ref CLK_Source_TypeDef
  * @param   NewState Enable or Disable the Clock Switch interrupt.
  * @param   CLK_CurrentClockState current clock to switch OFF or to keep ON.
  * It can be set of the values of @ref CLK_CurrentClockState_TypeDef
  * @note LSI selected as master clock source only if LSI_EN option bit is set.
  * @retval ErrorStatus this shows the clock switch status (ERROR/SUCCESS).
  */
ErrorStatus CLK_ClockSwitchConfig(CLK_SwitchMode_TypeDef CLK_SwitchMode, CLK_Source_TypeDef CLK_NewClock, FunctionalState ITState, CLK_CurrentClockState_TypeDef CLK_CurrentClockState);

切换的步骤

A时钟源切换到B时钟源

  1. B 时钟起振
  2. 等待B时钟就绪
  3. 使能时钟切换
  4. 配置时钟切换B
  5. 等待系统不忙
  6. 关闭切换
  7. 关闭时钟源A

例子

/*******************************************************************************
**函数名称:void ClockSwitch_HSE()
**功能描述:将系统时钟切换到外部高速晶振时钟
**入口参数:无
**输出:无
*******************************************************************************/
void ClockSwitch_HSE(void)
{
  //启用外部高速晶振,外部晶振1-16MHz
 
  CLK_HSECmd(ENABLE);//使能HSE起振
  while(CLK_GetFlagStatus(CLK_FLAG_HSERDY)== RESET);  //等待HSE准备就绪
  CLK_ClockSwitchCmd(ENABLE);   //使能时钟切换
  CLK_ClockSwitchConfig(CLK_SWITCHMODE_AUTO ,    //
                CLK_SOURCE_HSE ,            //选择外部16M晶振作为系统时钟源
                DISABLE ,                   //不开启时钟切换中断
                CLK_CURRENTCLOCKSTATE_ENABLE //振荡器使能
                );
  
  while(CLK_GetFlagStatus(CLK_FLAG_SWBSY) != RESET);
  CLK_SYSCLKConfig(CLK_PRESCALER_CPUDIV1);   //如果切换成功,则设置CPU时钟为1分频,让外部16M时钟作为系统时钟
  
  CLK_ClockSwitchCmd(DISABLE);     //关闭切换
  
  CLK_HSICmd(DISABLE);    //关闭内部高速HSI
}
/*******************************************************************************
**函数名称:void ClockSwitch_LSI()
**功能描述:将系统时钟切换到内部低速晶振时钟
**入口参数:无
**输出:无
*******************************************************************************/
void ClockSwitch_LSI(void)
{
  //启用内部低速晶振,128KHz
 
  CLK_LSICmd(ENABLE);//使能LSI起振
  while(CLK_GetFlagStatus(CLK_FLAG_LSIRDY)== RESET);  //等待LSI准备就绪
  CLK_ClockSwitchCmd(ENABLE);   //使能时钟切换
  CLK_ClockSwitchConfig(CLK_SWITCHMODE_AUTO ,    //
                CLK_SOURCE_LSI ,            //选择内部低速振荡器128K振作为系统时钟源
                DISABLE ,                   //不开启时钟切换中断
                CLK_CURRENTCLOCKSTATE_ENABLE //振荡器使能
                );
  
  while(CLK_GetFlagStatus(CLK_FLAG_SWBSY) != RESET);
  CLK_SYSCLKConfig(CLK_PRESCALER_CPUDIV1);   //如果切换成功,则设置CPU时钟为1分频,让128KHZ时钟作为系统时钟
  
  CLK_ClockSwitchCmd(DISABLE);     //关闭切换
  
  CLK_HSICmd(DISABLE);    //关闭内部高速HSI
}
;