【嵌入式学习笔记】嵌入式基础10——STM32时钟配置

1.认识时钟树

简单来说,时钟是具有周期性的脉冲信号,最常用的是占空比50%的方波

1.1.F1的时钟树

【嵌入式学习笔记】嵌入式基础10——STM32时钟配置_第1张图片
【嵌入式学习笔记】嵌入式基础10——STM32时钟配置_第2张图片
【嵌入式学习笔记】嵌入式基础10——STM32时钟配置_第3张图片

1.2.F4的时钟树(407为例)

【嵌入式学习笔记】嵌入式基础10——STM32时钟配置_第4张图片
【嵌入式学习笔记】嵌入式基础10——STM32时钟配置_第5张图片

1.3.F7的时钟树

【嵌入式学习笔记】嵌入式基础10——STM32时钟配置_第6张图片
【嵌入式学习笔记】嵌入式基础10——STM32时钟配置_第7张图片

1.4.H7的时钟树

【嵌入式学习笔记】嵌入式基础10——STM32时钟配置_第8张图片
【嵌入式学习笔记】嵌入式基础10——STM32时钟配置_第9张图片

2.配置系统时钟(F1为例)

2.1.系统时钟配置步骤

  1. 配置HSE VALUE:告诉HAL库外部晶振频率,stm32xxxx_hal_conf.h
  2. 调用Systemlnit()函数(可选):在启动文件中调用,在system_stm32xxxx.c定义
  3. 选择时钟源,配置PLL:通过HAL_RCC_OscConfig()函数设置
  4. 选择系统时钟源,配置总线分频器:通过HAL_RCC_ClockConfig()函数设置
  5. 配置扩展外设时钟(可选):通过HAL_RCCEx_PeriphCLKConfig()函数设置

【注】SystemInit 主要进行外部存储器配置和中断向量表地址配置。但是并没有用到,只是保留接口。HAL库的SystemInit 函数并没有任何时钟相关配置,所以后续的初始化步骤,我们还必须编写自己的时钟配置函数。

  • HAL_RCC_OscConfig()函数重要参数
    【嵌入式学习笔记】嵌入式基础10——STM32时钟配置_第10张图片
  • HAL_RCC_ClockConfig()函数重要参数
    【嵌入式学习笔记】嵌入式基础10——STM32时钟配置_第11张图片

第3,4,5步可由sys_stm32_clock_init() 函数完成

void sys_stm32_clock_init(uint32_t plln)
{
    HAL_StatusTypeDef ret = HAL_ERROR;
    RCC_OscInitTypeDef rcc_osc_init = {0};
    RCC_ClkInitTypeDef rcc_clk_init = {0};

    rcc_osc_init.OscillatorType = RCC_OSCILLATORTYPE_HSE;       /* 选择要配置HSE */
    rcc_osc_init.HSEState = RCC_HSE_ON;                         /* 打开HSE */
    rcc_osc_init.HSEPredivValue = RCC_HSE_PREDIV_DIV1;          /* HSE预分频系数 */
    rcc_osc_init.PLL.PLLState = RCC_PLL_ON;                     /* 打开PLL */
    rcc_osc_init.PLL.PLLSource = RCC_PLLSOURCE_HSE;             /* PLL时钟源选择HSE */
    rcc_osc_init.PLL.PLLMUL = plln;                             /* PLL倍频系数 */
    ret = HAL_RCC_OscConfig(&rcc_osc_init);                     /* 初始化 */

    if (ret != HAL_OK)
    {
        while (1);                                              /* 时钟初始化失败,之后的程序将可能无法正常执行,可以在这里加入自己的处理 */
    }

    /* 选中PLL作为系统时钟源并且配置HCLK,PCLK1和PCLK2*/
    rcc_clk_init.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2);
    rcc_clk_init.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;        /* 设置系统时钟来自PLL */
    rcc_clk_init.AHBCLKDivider = RCC_SYSCLK_DIV1;               /* AHB分频系数为1 */
    rcc_clk_init.APB1CLKDivider = RCC_HCLK_DIV2;                /* APB1分频系数为2 */
    rcc_clk_init.APB2CLKDivider = RCC_HCLK_DIV1;                /* APB2分频系数为1 */
    ret = HAL_RCC_ClockConfig(&rcc_clk_init, FLASH_LATENCY_2);  /* 同时设置FLASH延时周期为2WS,也就是3个CPU周期。 */

    if (ret != HAL_OK)
    {
        while (1);                                              /* 时钟初始化失败,之后的程序将可能无法正常执行,可以在这里加入自己的处理 */
    }
}

2.2.外设时钟使能和失能

我们要使用某个外设,必需先使能该外设时钟

  • HAL库使能某个外设时钟的方法,如:
__HAL_RCC_GPIOA_CLK_ENABLE();      		/* 使能 GPIOA 时钟 */
  • HAL库禁止某个外设时钟的方法,如:
__HAL_RCC_GPIOA_CLK_DISABLE();      	/* 禁止 GPIOA 时钟 */

你可能感兴趣的:(嵌入式学习专栏(STM32),学习,笔记,stm32)