《STM32 HAL库》RCC 相关系列函数详尽解析—— HAL_RCC_OscConfig()

观前提示:函数完整代码在文末,本文梳理了函数HAL_RCC_OscConfig()的主要逻辑和实现方法
f105时钟树详解图

HAL_RCC_OscConfig()

函数介绍:

此函数是一个用于初始化RCC (Reset and Clock Control)振荡器(Oscillators,函数名中Osc为此单词缩写 )的函数。它接受一个指向RCC_OscInitTypeDef结构体的指针 ,结构体的各成员分别包含了RCC振荡器的配置信息。

函数行数为442行,功能性上分为六个部分:

  • HSE配置,外部高速时钟
  • HSI配置,内部高速时钟
  • LSE配置,外部低速时钟
  • LSI配置,内部低速时钟
  • PLL1配置,锁相环1
  • PLL2配置,锁相环2

下文中我们将以功能为线索依次分析此函数

函数分析

复制代码
HAL_StatusTypeDef HAL_RCC_OscConfig(RCC_OscInitTypeDef  *RCC_OscInitStruct)
{
  uint32_t tickstart;
  uint32_t pll_config;

  /* Check Null pointer */
  if (RCC_OscInitStruct == NULL)
  {
    return HAL_ERROR;
  }

  /* Check the parameters */
  assert_param(IS_RCC_OSCILLATORTYPE(RCC_OscInitStruct->OscillatorType));

首先,定义了两个局部变量tickstart和pll_config。

接下来,检查传入的指针RCC_OscInitStruct是否为空,如果为空,则返回HAL_ERROR。

然后,使用assert_param宏来检查RCC_OscInitStruct->OscillatorType参数是否合法。

HSE Configuration部分

复制代码
if (((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_HSE) == RCC_OSCILLATORTYPE_HSE)

这行代码通过按位与运算符将RCC_OscInitStruct->OscillatorTypeRCC_OSCILLATORTYPE_HSE进行按位与操作,并将结果与RCC_OSCILLATORTYPE_HSE进行比较。如果结果等于RCC_OSCILLATORTYPE_HSE,则条件成立。这个条件判断语句的目的是检查是否启用了外部高速时钟(HSE)作为振荡器类型。

复制代码
/* Check the parameters */
assert_param(IS_RCC_HSE(RCC_OscInitStruct->HSEState));

这是一个断言语句,用于检查RCC_OscInitStruct->HSEState的值是否符合要求。IS_RCC_HSE是一个宏,用于验证RCC_OscInitStruct->HSEState是否满足特定的条件。如果断言失败,则会触发断言错误。

复制代码
if ((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_SYSCLKSOURCE_STATUS_HSE)
    || ((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_SYSCLKSOURCE_STATUS_PLLCLK) && (__HAL_RCC_GET_PLL_OSCSOURCE() == RCC_PLLSOURCE_HSE)))

这个条件判断语句检查系统时钟源是否为外部高速时钟(HSE),或者是由HSE驱动的PLL时钟源。如果条件成立,则意味着HSE在系统时钟或PLL时钟源中被使用,此时不允许将其禁用。

复制代码
if ((__HAL_RCC_GET_FLAG(RCC_FLAG_HSERDY) != RESET) && (RCC_OscInitStruct->HSEState == RCC_HSE_OFF))
{
  return HAL_ERROR;
}

这个条件判断语句检查HSE是否已经就绪,并且RCC_OscInitStruct->HSEState的值为禁用状态(RCC_HSE_OFF)。如果这两个条件都满足,函数将返回HAL_ERROR

复制代码
__HAL_RCC_HSE_CONFIG(RCC_OscInitStruct->HSEState);

这行代码根据RCC_OscInitStruct->HSEState的值配置HSE振荡器的状态。__HAL_RCC_HSE_CONFIG是一个宏,用于设置HSE的状态。

复制代码
/* Check the HSE State */
if (RCC_OscInitStruct->HSEState != RCC_HSE_OFF)
{
  /* Get Start Tick */
  tickstart = HAL_GetTick();

  /* Wait till HSE is ready */
  while (__HAL_RCC_GET_FLAG(RCC_FLAG_HSERDY) == RESET)
  {
    if ((HAL_GetTick() - tickstart) > HSE_TIMEOUT_VALUE)
    {
      return HAL_TIMEOUT;
    }
  }
}

这部分代码在HSE不是禁用状态时,等待HSE就绪。它使用__HAL_RCC_GET_FLAG宏来检查HSE是否已经就绪。如果HSE在超时时间内仍未就绪,函数将返回HAL_TIMEOUT

复制代码
else
{
  /* Get Start Tick */
  tickstart = HAL_GetTick();

  /* Wait till HSE is disabled */
  while (__HAL_RCC_GET_FLAG(RCC_FLAG_HSERDY) != RESET)
  {
    if ((HAL_GetTick() - tickstart) > HSE_TIMEOUT_VALUE)
    {
      return HAL_TIMEOUT;
    }
  }
}

这部分代码在HSE为禁用状态时,等待HSE被禁用。它使用__HAL_RCC_GET_FLAG宏来检查HSE是否已经禁用。如果HSE在超时时间内仍未禁用,函数将返回HAL_TIMEOUT

点击《STM32 HAL库》RCC 相关系列函数详尽解析------ HAL_RCC_OscConfig()------古月居可查看全文

相关推荐
可待电子单片机设计定制(论文)4 小时前
【STM32设计】基于STM32的智能门禁管理系统(指纹+密码+刷卡+蜂鸣器报警)(代码+资料+论文)
stm32·单片机·嵌入式硬件
不可思议迷宫6 小时前
Verilog编程实现一个分秒计数器
单片机·嵌入式硬件·fpga开发
life_yangzi7 小时前
关于单片机IAP升级的那点事儿|智能设置中断向量表
单片机·嵌入式硬件
了一li9 小时前
STM32实现一个简单电灯
stm32·单片机·嵌入式硬件
可待电子单片机设计定制(论文)12 小时前
【STM32设计】数控直流稳压电源的设计与实现(实物+资料+论文)
stm32·嵌入式硬件·mongodb
march_birds13 小时前
FreeRTOS 与 RT-Thread 事件组对比分析
c语言·单片机·算法·系统架构
小麦嵌入式13 小时前
Linux驱动开发实战(十一):GPIO子系统深度解析与RGB LED驱动实践
linux·c语言·驱动开发·stm32·嵌入式硬件·物联网·ubuntu
触角0101000115 小时前
STM32F103低功耗模式深度解析:从理论到应用实践(上) | 零基础入门STM32第九十二步
驱动开发·stm32·单片机·嵌入式硬件·物联网
昊虹AI笔记15 小时前
使用STM32CubeMX和Keil在STM32上创建并运行一个简单的FreeRTOS多任务程序
stm32·单片机·嵌入式硬件
王光环15 小时前
单片机使用printf,不用微库
单片机·嵌入式硬件