【修订记录】
1、20210805,第一版
2、20210806,添加目录,追加 修改HSE_Value文字段落
3、20230206,表述简化
STM8S的时钟源
芯片的主时钟有4种时钟源可选:
- HSE:1~16MHz高速的外部晶体
- HSE:最高16MHz的外部时钟信号
- HSI:16MHz内部高速RC振荡器
- LSI:128KHz的低速内部RC振荡器
上电复位后
上电复位(POR)后,MCU自动运行于HSI下,分频系数是8。习惯上,我们在进入main函数后,优先配置时钟系统,以满足项目需求;除非HSI分频得到的2MHz已足够。
那么,问题也就来了:
- 时钟源切换
- 分频设置
时钟设置代码
1、HSE→SYSCLK分频→SYSCLK:当HSE为系统时钟源时,分频系数只有1个,即SYSCLK分频系数;
2、HSI→HSI分频→SYSCLK分频→SYSCLK:当HSI为系统时钟源时,还多出1个分频系数可设定,也就是HSI分频系数
3、关于LSI:切换到LSI的函数读者可自己仿写,软件流程和切换到HSI的方式相同。LSI的有点是功耗最低。
/**
******************************************************************************
* @file clk_hal.c
* @author
* @version V1.0.0
* @date DD-MM-YYYY
* @brief
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#include "clk_hal.h"
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Variables -----------------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
/* Functions -----------------------------------------------------------------*/
/**
* @brief Switch system clock to HSE
* @param CLK_Prescaler : CPU clock divider to apply
* @retval None
*/
void CLK_HAL_SwitchToHSE(CLK_Prescaler_TypeDef CLK_Prescaler)
{
CLK_HSECmd(ENABLE); /* Enable HSE */
/* Configures the Switch from one clock to another */
while (CLK_ClockSwitchConfig(CLK_SWITCHMODE_AUTO, /* automatic clock switching mode */
CLK_SOURCE_HSE, /* Clock Source HSE */
DISABLE, /* Disable IT */
CLK_CURRENTCLOCKSTATE_DISABLE) != SUCCESS);/* Disable current clock */
while (CLK_GetFlagStatus(CLK_FLAG_HSERDY) != SET); /* Wait for the-new-clock's stability */
CLK_ClockSwitchCmd(ENABLE); /* Starts manually the clock switch execution. */
CLK_ClockSecuritySystemEnable(); /* Enables the Clock Security System. */
CLK_SYSCLKConfig(CLK_Prescaler); /* Write CPU clock divider. */
}
/**
* @brief Switch system clock to HSI
* @param HSIPrescaler : HSI clock divider to apply.
* @param CLK_Prescaler : CPU clock divider to apply.
* @retval None
*/
void CLK_HAL_SwitchToHSI(CLK_Prescaler_TypeDef HSIPrescaler, CLK_Prescaler_TypeDef CLK_Prescaler)
{
CLK_HSICmd(ENABLE); /* Enable HSI */
/* Configures the Switch from one clock to another */
while (CLK_ClockSwitchConfig(CLK_SWITCHMODE_AUTO, /* automatic clock switching mode */
CLK_SOURCE_HSI, /* Clock Source HSI */
DISABLE, /* Disable IT */
CLK_CURRENTCLOCKSTATE_DISABLE) != SUCCESS);/* Disable current clock */
while (CLK_GetFlagStatus(CLK_FLAG_HSIRDY) != SET); /* Wait for the-new-clock's stability */
CLK_ClockSwitchCmd(ENABLE); /* Starts manually the clock switch execution. */
CLK_HSIPrescalerConfig(HSIPrescaler); /* Write HSI clock divider. */
CLK_SYSCLKConfig(CLK_Prescaler); /* Write CPU clock divider. */
}
/******************************************************************************/