口天土立口 发表于 2025-10-15 18:51

APM32E030的时钟切换

本帖最后由 口天土立口 于 2025-10-15 18:57 编辑



APM32E030的系统时钟可配置为不同的时钟源,时钟最大72MHz;
部分应用场景可根据功耗需要使用不同的主频运行;
但给系统时钟切换时钟前,必须先把待切入的时钟配置稳定才能切入,否则可能异常;

驱动代码如下:
/*
* @brief       时钟引脚初始化
*
* @param       None
*
* @retval      None
*
*/
static void bsp_clk_gpio_init(void)
{
    GPIO_Config_T gpioConfig;
   
    RCM_EnableAHBPeriphClock(RCM_AHB_PERIPH_GPIOA);
    GPIO_ConfigStructInit(&gpioConfig);
    gpioConfig.pin   = GPIO_PIN_8;
    gpioConfig.mode    = GPIO_MODE_AF;
    gpioConfig.outtype = GPIO_OUT_TYPE_PP;
    gpioConfig.speed   = GPIO_SPEED_50MHz;
    gpioConfig.pupd    = GPIO_PUPD_NO;
    GPIO_Config(GPIOA, &gpioConfig);
    GPIO_ConfigPinAF(GPIOA, GPIO_PIN_SOURCE_8, GPIO_AF_PIN0);
}/*
* @brief       时钟初始化
*
* @param       None
*
* @retval      None
*
*/
void bsp_clk_init(void)
{
    bsp_clk_gpio_init();
    /* SYSCLK 作为时钟输出 */
    RCM_ConfigCOC(RCM_COC_SYSCLK);
}/*
* @brief       系统时钟切为HSI
*
* @param       None
*
* @retval      None
*
*/
void bsp_clk_sysclk_to_hsi(void)
{
    /* 使能HSI并等待稳定 */
    RCM_EnableHSI();
    while (RCM_ReadStatusFlag(RCM_FLAG_HSIRDY) == RESET);
    /* 系统时钟切换为HSI */
    RCM_ConfigSYSCLK(RCM_SYSCLK_SEL_HSI);
    while (RCM_ReadSYSCLKSource() != RCM_SYSCLK_SEL_HSI);
}/*
* @brief       系统时钟切为HSE
*
* @param       None
*
* @retval      None
*
*/
void bsp_clk_sysclk_to_hse(void)
{
    /* 使能HSE并等待稳定 */
    RCM_ConfigHSE(RCM_HSE_OPEN);
    while (RCM_ReadStatusFlag(RCM_FLAG_HSERDY) == RESET);
    /* 系统时钟切换为HSE */
    RCM_ConfigSYSCLK(RCM_SYSCLK_SEL_HSE);
    while (RCM_ReadSYSCLKSource() != RCM_SYSCLK_SEL_HSE);
}/*
* @brief       系统时钟切为PLL 12MHz
*
* @param       None
*
* @retval      None
*
*/
void bsp_clk_sysclk_to_pll_12MHz(void)
{
    /* 先关闭PLL */
    RCM_DisablePLL();
    while (RCM_ReadStatusFlag(RCM_FLAG_PLLRDY) == SET);   
    /* 使能HSE并等待稳定 */
    RCM_ConfigHSE(RCM_HSE_OPEN);
    while (RCM_ReadStatusFlag(RCM_FLAG_HSERDY) == RESET);
    /* 配置PLL */
    RCM_ConfigCLKDIV(RCM_CLK_DIV_2);                /* 8 / 2 = 4MHz */
    RCM_ConfigPLL(RCM_PLL_SEL_HSE, RCM_PLLMF_3);    /* 4 * 3 = 12MHz */
    /* 使能PLL */
    RCM_EnablePLL();
    while (RCM_ReadStatusFlag(RCM_FLAG_PLLRDY) != SET);
    /* 系统时钟切换为PLL */
    RCM_ConfigSYSCLK(RCM_SYSCLK_SEL_PLL);
    while (RCM_ReadSYSCLKSource() != RCM_SYSCLK_SEL_PLL);
}

测试代码如下:
void delay(uint32_t n)
{
    volatile uint32_t d = n;
    while (--d);
}

// 应用初始化
void app_init(void)
{
    bsp_clk_init();
    bsp_clk_sysclk_to_hsi();
}// 应用任务
void app_task(void)
{
    delay(0xFFFFF);
    bsp_clk_sysclk_to_pll_12MHz();
    delay(0xFFFFF);
    bsp_clk_sysclk_to_hse();
    delay(0xFFFFF);
    bsp_clk_sysclk_to_hsi();
}


详细代码,请查看附件!




神秘低语 发表于 2025-10-20 16:11

这是系统时钟动态切换呀

观星者宁静 发表于 2025-10-22 09:20

这种切换要关闭其余外设,或者重启系统吧

口天土立口 发表于 2025-10-22 13:33

观星者宁静 发表于 2025-10-22 09:20
这种切换要关闭其余外设,或者重启系统吧

系统不用重启,外设使用的时钟源主频不一样就要重新初始化外设即可

霜咬回响 发表于 2025-10-22 14:34

系统时钟源更换? 这个在什么场景下有这个应用啊?

口天土立口 发表于 2025-10-22 16:15

霜咬回响 发表于 2025-10-22 14:34
系统时钟源更换? 这个在什么场景下有这个应用啊?

电池供电或其他需要精妙功耗控制的产品

霜咬回响 发表于 2025-11-3 14:18

还真没有对比过降低主频和进入低功耗,哪个整体的功耗会更低

转瞬回声 发表于 2025-11-3 19:10

暂时还没有遇到 需要切换时钟的场景
页: [1]
查看完整版本: APM32E030的时钟切换