HAL 库配置 STM32F1 时钟系统

  1. 配置时钟源,以及相关参数:调用 HAL_RCC_OscConfig 函数

  2. 配置系统时钟源,以及 SYSCLK、AHB、APB1、APB2 相关参数:调用 HAL_RCC_ClockConfig 函数


一、HAL_RCC_OscConfig 函数

1、基本介绍
  • HAL_RCC_OscConfig 函数位于 stm32f1xx_hal_rcc.c
HAL_StatusTypeDef HAL_RCC_OscConfig(RCC_OscInitTypeDef  *RCC_OscInitStruct)
参数 说明
RCC_OscInitStruct 指向一个 RCC_OscInitTypeDef
返回值 说明
HAL_OK 操作成功
HAL_ERROR 操作发生错误
HAL_BUSY 资源正忙
HAL_TIMEOUT 操作超时
2、RCC_OscInitTypeDef 结构体
  • RCC_OscInitTypeDef 结构体位于 stm32f1xx_hal_rcc_ex.h
  1. 第 1 ~ 7 个参数主要用于配置振荡器

  2. 例如,开启 HSE,则设置为 RCC_OSCILLATORTYPE_HSE,然后设置 HSEState 为 RCC_HSE_ON

  3. LSE、HIS、LSI,配置方法类似

  4. 第 8 个参数是 RCC_PLLInitTypeDef 结构体,用于配置 PLL

typedef struct
{
  uint32_t OscillatorType;       /*!< The oscillators to be configured.
                                       This parameter can be a value of @ref RCC_Oscillator_Type */

#if defined(STM32F105xC) || defined(STM32F107xC)
  uint32_t Prediv1Source;       /*!<  The Prediv1 source value.
                                       This parameter can be a value of @ref RCCEx_Prediv1_Source */
#endif /* STM32F105xC || STM32F107xC */

  uint32_t HSEState;              /*!< The new state of the HSE.
                                       This parameter can be a value of @ref RCC_HSE_Config */

  uint32_t HSEPredivValue;       /*!<  The Prediv1 factor value (named PREDIV1 or PLLXTPRE in RM)
                                       This parameter can be a value of @ref RCCEx_Prediv1_Factor */

  uint32_t LSEState;              /*!<  The new state of the LSE.
                                        This parameter can be a value of @ref RCC_LSE_Config */

  uint32_t HSIState;              /*!< The new state of the HSI.
                                       This parameter can be a value of @ref RCC_HSI_Config */

  uint32_t HSICalibrationValue;   /*!< The HSI calibration trimming value (default is RCC_HSICALIBRATION_DEFAULT).
                                       This parameter must be a number between Min_Data = 0x00 and Max_Data = 0x1F */

  uint32_t LSIState;              /*!<  The new state of the LSI.
                                        This parameter can be a value of @ref RCC_LSI_Config */

  RCC_PLLInitTypeDef PLL;         /*!< PLL structure parameters */

#if defined(STM32F105xC) || defined(STM32F107xC)
  RCC_PLL2InitTypeDef PLL2;         /*!< PLL2 structure parameters */
#endif /* STM32F105xC || STM32F107xC */
} RCC_OscInitTypeDef;
编号 参数 说明
1 OscillatorType 振荡器类型
2 HSEState HSE 状态
3 HSEPredivValue HSE 预分频值
4 LSEState LSE 状态
5 HSIState HIS 状态
6 HSICalibrationValue HIS 校准值
7 LSIState LSI 状态
8 PLL PLL 配置
  1. OscillatorType 可供选择的值如下
说明
RCC_OSCILLATORTYPE_NONE 不配置
RCC_OSCILLATORTYPE_HSE 配置 HSE
RCC_OSCILLATORTYPE_HSI 配置 HSI
RCC_OSCILLATORTYPE_LSE 配置 LSE
RCC_OSCILLATORTYPE_LSI 配置 LSI
  1. HSEState 可供选择的值如下
说明
RCC_HSE_OFF 关闭 HSE
RCC_HSE_ON 开启 HSE
RCC_HSE_BYPASS 使用外部旁路时钟
  1. HSEPredivValue 可供选择的值如下
说明
RCC_HSE_PREDIV_DIV1 不分频
RCC_HSE_PREDIV_DIV2 2 分频
3、RCC_PLLInitTypeDef 结构体
  • RCC_PLLInitTypeDef 结构体位于 stm32f1xx_hal_rcc.h
typedef struct
{
  uint32_t PLLState;      /*!< PLLState: The new state of the PLL.
                              This parameter can be a value of @ref RCC_PLL_Config */

  uint32_t PLLSource;     /*!< PLLSource: PLL entry clock source.
                              This parameter must be a value of @ref RCC_PLL_Clock_Source */

  uint32_t PLLMUL;        /*!< PLLMUL: Multiplication factor for PLL VCO input clock
                              This parameter must be a value of @ref RCCEx_PLL_Multiplication_Factor */
} RCC_PLLInitTypeDef;
参数 说明
PLLState PLL 状态
PLLSource PLL 时钟源
PLLMUL PLL 倍频系数 M
  1. PLLState 可供选择的值如下
说明
RCC_PLL_NONE 不配置 PLL
RCC_PLL_OFF 关闭 PLL
RCC_PLL_ON 开启 PLL
  1. PLLSource 可供选择的值如下
说明
RCC_PLLSOURCE_HSI_DIV2 选择 HSI 经过 2 分频后作为 PLL 的输入时钟源
RCC_PLLSOURCE_HSE 选择 HSE 作为 PLL 的输入时钟源
  1. PLLMUL 可供选择的值如下
说明
RCC_PLL_MUL2 倍频系数为 2
RCC_PLL_MUL3 倍频系数为 3
4、演示
HAL_StatusTypeDef ret = HAL_ERROR;

RCC_OscInitTypeDef rcc_osc_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;			// 选择 HSE 作为 PLL 的输入时钟源
rcc_osc_init.PLL.PLLMUL = plln;							// PLL 倍频系数 M

ret = HAL_RCC_OscConfig(&rcc_osc_init);

if (ret != HAL_OK)
{
    // 操作发生错误的处理
}
  • 这里设置 plln 为 RCC_PLL_MUL9,即倍频系数为 9,那么 PLLCLK = HSE * 9 = 8MHz * 9 = 72MHz

二、HAL_RCC_ClockConfig 函数

1、基本介绍
  • HAL_RCC_ClockConfig 函数位于 stm32f1xx_hal_rcc.c
HAL_StatusTypeDef HAL_RCC_ClockConfig(RCC_ClkInitTypeDef  *RCC_ClkInitStruct, uint32_t FLatency)
参数 说明
RCC_ClkInitStruct 指向一个 RCC_ClkInitTypeDef
FLatency Flash 延迟
返回值 说明
HAL_OK 操作成功
HAL_ERROR 操作发生错误
HAL_BUSY 资源正忙
HAL_TIMEOUT 操作超时
2、RCC_ClkInitTypeDef 结构体
  • RCC_ClkInitTypeDef 结构体位于 stm32f1xx_hal_rcc.h
typedef struct
{
  uint32_t ClockType;             /*!< The clock to be configured.
                                       This parameter can be a value of @ref RCC_System_Clock_Type */

  uint32_t SYSCLKSource;          /*!< The clock source (SYSCLKS) used as system clock.
                                       This parameter can be a value of @ref RCC_System_Clock_Source */

  uint32_t AHBCLKDivider;         /*!< The AHB clock (HCLK) divider. This clock is derived from the system clock (SYSCLK).
                                       This parameter can be a value of @ref RCC_AHB_Clock_Source */

  uint32_t APB1CLKDivider;        /*!< The APB1 clock (PCLK1) divider. This clock is derived from the AHB clock (HCLK).
                                       This parameter can be a value of @ref RCC_APB1_APB2_Clock_Source */

  uint32_t APB2CLKDivider;        /*!< The APB2 clock (PCLK2) divider. This clock is derived from the AHB clock (HCLK).
                                       This parameter can be a value of @ref RCC_APB1_APB2_Clock_Source */
} RCC_ClkInitTypeDef;
参数 说明
ClockType 要配置的时钟类型
SYSCLKSource 系统时钟源选择
AHBCLKDivider AHB 总线分频系数
APB1CLKDivider APB1 总线分频系数
APB2CLKDivider APB2 总线分频系数
  1. ClockType 可供选择的值如下
说明
RCC_CLOCKTYPE_SYSCLK 配置系统时钟(SYSCLK)
RCC_CLOCKTYPE_HCLK 配置 AHB 总线时钟(HCLK)
RCC_CLOCKTYPE_PCLK1 配置 APB1 总线时钟(PCLK1)
RCC_CLOCKTYPE_PCLK2 配置 APB2 总线时钟(PCLK2)
  1. SYSCLKSource 可供选择的值如下
说明
RCC_SYSCLKSOURCE_HSI 选择 HSI
RCC_SYSCLKSOURCE_HSE 选择 HSE
RCC_SYSCLKSOURCE_PLLCLK 选择 PLLCLK
  1. AHBCLKDivider 可供选择的值如下
说明
RCC_SYSCLK_DIV1 不分频
RCC_SYSCLK_DIV2 2 分频
  1. APB1CLKDivider 可供选择的值如下
说明
RCC_HCLK_DIV1 不分频
RCC_HCLK_DIV2 2 分频
  1. APB2CLKDivider 可供选择的值如下
说明
RCC_HCLK_DIV1 不分频
RCC_HCLK_DIV2 2 分频
3、FLatency 可以选择的值
  • FLatency 根据系统时钟频率选择,确保稳定访问 Flash
说明
FLASH_LATENCY_0 0 等待周期(0 < SYSCLK ≤ 24 MHz)
FLASH_LATENCY_1 1 等待周期(24 MHz < SYSCLK ≤ 48 MHz)
FLASH_LATENCY_2 2 等待周期(48 MHz < SYSCLK ≤ 72 MHz)
4、演示
HAL_StatusTypeDef ret = HAL_ERROR;

RCC_ClkInitTypeDef rcc_clk_init = {0};

rcc_clk_init.ClockType = RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2;
rcc_clk_init.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
rcc_clk_init.AHBCLKDivider = RCC_SYSCLK_DIV1;
rcc_clk_init.APB1CLKDivider = RCC_HCLK_DIV2;
rcc_clk_init.APB2CLKDivider = RCC_HCLK_DIV1;

ret = HAL_RCC_ClockConfig(&rcc_clk_init, FLASH_LATENCY_2);

if (ret!= HAL_OK)
{
    // 操作发生错误的处理
}
  • PLLCLK 为 72MHz,那么
  1. SYSCLK = PLLCLK = 72MHz

  2. HCLK = SYSCLK / 1 = 72MHz

  3. PCLK1 = HCLK / 2 = 36MHz

  4. PCLK2 = HCLK / 1 = 72MHz

Logo

openvela 操作系统专为 AIoT 领域量身定制,以轻量化、标准兼容、安全性和高度可扩展性为核心特点。openvela 以其卓越的技术优势,已成为众多物联网设备和 AI 硬件的技术首选,涵盖了智能手表、运动手环、智能音箱、耳机、智能家居设备以及机器人等多个领域。

更多推荐