3.STM32:RCC

目录

HSE时钟

HSI时钟

PLLCLK

系统时钟

HCLK时钟

PCLK1时钟

PCLK2时钟

RTC时钟

独立看门狗时钟

MCO输出时钟

在STM32上如果不使用外部晶振,OSC_IN和OSC_OUT的接法:

用HSE时钟,程序设置时钟参数流程

HAL库_RCC

HAL_RCC结构体

HAL_RCC函数


RCC

复位

复位的三种类型:系统复位电源复位备份域复位

系统复位

复位时系统将所有寄存器的值重置(除了RCC_CSR寄存器和RCC_BDCR寄存器)。复位源可以通过RCC_CSR寄存器来识别。

引起系统复位的事件:

NRST引脚低电平(外部复位)

IWDG、WWDG复位

软件复位(SW复位)

低功耗管理复位

电源复位

复位时电源将所有寄存器的值重置(除了RCC_BDCR寄存器)。

引起电源复位的事件:

上电/下电复位(POR/PDR复位)

退出待机模式时

备份域复位

备份域复位只影响备份域。

引起备份域复位的事件:

软件复位,通过设置RCC_BDCR:BSRST。

如果两个电源先前都已关闭,则VDD或VBAT上电。

时钟

每个时钟源可以在使用时单独打开或关闭,以降低功耗。

下图为时钟树的总体框图。倒梯形表示选择器长边表示多个输入短边表示选择其中一个输出

STM32五个时钟源:HSI、HSE、LSI、LSE、PLL。

HSI高速内部时钟RC振荡器,频率为8MHz。可以直接作为系统时钟或者用作PLL时钟输入

HSE高速外部时钟接石英/陶瓷谐振器或者接外部时钟源,频率范围为4MHz~16MHz。

LSI低速内部时钟RC振荡器,频率为40kHz,提供低功耗时钟主要供独立看门狗和自动唤醒单元使用

LSE低速外部时钟频率为32.768kHz的石英晶体一般用于RTC

PLL锁相环倍频输出,其时钟输入源可选择为HSI/2、HSE或者HSE/2。倍频可选择为2~16倍,但是其输出频率最大不得超过72MHz。

PLL为主PLLPLLI2S为专用PLL

主PLL(PLL)由HSE或者HSI提供时钟信号,并具有两个不同的输出时钟。

第一个输出PLLP用于生成高速的系统时钟(最高168MHz)

第二个输出PLLQ用于生成USB FS的时钟(48MHz),随机数发生器的时钟和SDIO时钟。

专用PLL(PLLI2S)用于生成精确时钟,从而在I2S接口实现高品质音频性能

HSE时钟

来源:

HSE外部晶振/陶瓷谐振器(有源晶振)

HSE用户外部时钟(无源晶振,4-16M,通常使用8M无源晶振)

控制:

RCC_CR:HSEON控制

当使用到无源晶振的时候,一定要使用到起振电容,起振需要一定的时间,所以需要RCC_CR:HSERDY = 1时表示外部4-16Mhz振荡器就绪。

如果使用到有源晶振,OSC_OUT悬空,OSC_IN进入到我们的芯片。

 

HSI时钟

来源:芯片内部,大小为8M,当HSE故障时,系统时钟会自动切换到HSI,直到HSE启动成功。

控制:RCC_CR时钟控制寄存器的位0:HSION控制。

PLLCLK

来源:(HSI/2、HSE)经过倍频所得。

控制:RCC_CFGR:PLLXTPRE、PLLMUL和PLLSRC。

注意:PLL时钟源头使用HSI/2的时候,PLLMUL最大只能是16,这个时候PLLCLK最大只能是64M,小于ST官方推荐的最大时钟72M。并且根据温度和环境的情况,HSI的频率会有偏差,一般不作为PLL的时钟来源。

系统时钟

锁相环时钟:SYSCLK,最高为72M(ST官方推荐的)

来源:HSI、HSE、PLLCLK。

控制:RCC_CFGR:SW。

注意:通常的配置是SYSCLK=PLLCLK=72M。一般配置RCC_CFGR:SW,然后判断RCC_CFGR:SWS。如:配置RCC_CFGR:SW = 10,然后判断RCC_CFGR:SWS == 10?若是,则切换成功。

HCLK时钟

HCLK:AHB高速总线时钟,速度最高为72M。为AHB总线的外设提供时钟、为Cortex系统定时器提供时钟(SysTick)、为内核提供时钟(FCLK)。

来源:系统时钟分频得到,一般设置HCLK=SYSCLK=72M。

控制:RCC_CFGR:HPRE。

PCLK1时钟

PCLK1:APB1低速总线时钟,最高为36M。为APB1总线的外设提供时钟。2倍频之后则为APB1总线的定时器2-7提供时钟,最大为72M。

来源:HCLK分频得到,一般设置PCLK1=HCLK/2=36M。

控制:RCC_CFGR:PPRE1。

PCLK2时钟

PCLK2:APB2高速总线时钟,最高为72M。为APB2总线的外设提供时钟。不分频则为APB2总线的定时器1和8提供时钟,最大为72M。

来源:HCLK分频得到,一般设置PCLK2=HCLK=72M。

控制:RCC_CFGR:PPRE2。

RTC时钟

RTC时钟:为芯片内部的RTC外设提供时钟。

来源:HSE_RTC(HSE分频得到)、LSE(外部32.768kHz的晶体提供)、LSI(32kHz)。

控制:RCC_BDCR:RTCSEL。

独立看门狗时钟

IWDGCLK:由LSI提供。

MCO输出时钟

MCO:微控制器时钟输出引脚,由PA8复用所得。主要作用是可以对外提供时钟,相当于一个有源晶振。

来源:PLLCLK/2,HSE、HSI、SYSCLK。

控制:RCC_CFGR:MCO。

在STM32上如果不使用外部晶振,OSC_IN和OSC_OUT的接法:

如果使用内部RC振荡器而不使用外部晶振,请按照下面方法处理:

①对于100脚或144脚的产品,OSC_IN应接地,OSC_OUT应悬空。

②对于少于100脚的产品,有2种接法:

第1种:OSC_IN和OSC_OUT分别通过10K电阻接地。此方法可提高EMC性能;

第2种:分别重映射OSC_IN和OSC_OUT至PD0和PD1,再配置PD0和PD1为推挽输出并输出'0'。此方法可以减小功耗并(相对上面)节省2个外部电阻。

系统时钟配置

配置步骤

01、复位RCC                                        RCC_DeInit;

02、打开外部高速时钟晶振HSE            RCC_HSEConfig(RCC_HSE_ON);

03、等待外部高速时钟晶振工作            HSEStartUpStatus = RCC_WaitForHSEStartUp();

04、设置AHB时钟                                 RCC_HCLKConfig;

05、设置APB2时钟                               RCC_PCLK2Config;

06、设置APB1时钟                               RCC_PCLK1Config;

07、设置PLL                                         RCC_PLLConfig;

08、使能PLL                                         RCC_PLLCmd(ENABLE);

09、等待PLL工作                                 while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET)

10、设置系统时钟                                RCC_SYSCLKConfig;

11、判断PLL是否是系统时钟              while(RCC_GetSYSCLKSource() != 0x08)

12、打开要使用的外设时钟                RCC_APB2PeriphClockCmd()/RCC_APB1PeriphClockCmd()

对system_stm32f10x.c的static void SetSysClockTo72(void)进行解析。

static void SetSysClockTo72(void)
{
      __IO uint32_t StartUpCounter = 0, HSEStatus = 0;
  
      /* SYSCLK, HCLK, PCLK2 and PCLK1 configuration ---------------------------*/    
      /* Enable HSE */    
      RCC->CR |= ((uint32_t)RCC_CR_HSEON);
 
      /*等待HSE准备就绪,如果超时,则退出*/
      do
      {
            HSEStatus = RCC->CR & RCC_CR_HSERDY;
            StartUpCounter++;  
      } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));

      if ((RCC->CR & RCC_CR_HSERDY) != RESET)
      {
            HSEStatus = (uint32_t)0x01;
      }else
      {
            HSEStatus = (uint32_t)0x00;
      }  


      //如果HSE启动成功,则程序继续往下执行
      if (HSEStatus == (uint32_t)0x01)
      {
            /* 使能预取缓冲区 */
            FLASH->ACR |= FLASH_ACR_PRFTBE;

            /* 时延,等待2个延迟周期 */
            FLASH->ACR &= (uint32_t)((uint32_t)~FLASH_ACR_LATENCY);
            FLASH->ACR |= (uint32_t)FLASH_ACR_LATENCY_2;    

            /* HCLK = SYSCLK */
            RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1;
      
            /* PCLK2 = HCLK */
            RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1;
    
            /* PCLK1 = HCLK */
            RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV2;

            /*  PLL配置: PLLCLK = HSE * 9 = 72 MHz */
            RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE |
                                        RCC_CFGR_PLLMULL));
            RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_HSE | RCC_CFGR_PLLMULL9);

            /* PLL使能 */
            RCC->CR |= RCC_CR_PLLON;

            /* 等待PLL稳定 */
            while((RCC->CR & RCC_CR_PLLRDY) == 0)
            {
            }    
    
            /* 选择PLL作为系统时钟源 */
            RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));
            RCC->CFGR |= (uint32_t)RCC_CFGR_SW_PLL;    

            /* 等待PLLCLK切换成系统时钟*/
            while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)0x08)
            {
            }
      }
      else
      {    /*如果HSE启动失败,应用程序将会有错误的时钟配置。用户可以在这里添加一些代码来处理这个错误  */
      }
}

然后仿照system_stm32f10x.c的static void SetSysClockTo72(void),根据固件库写一个void HSE_SetSysClk(uint32_t RCC_PLLMul_x)。

void HSE_SetSysClk(uint32_t RCC_PLLMul_x)
{ 
	ErrorStatus HSEStatus; 
	
	//把RCC寄存器复位成复位值
	RCC_DeInit();
	
	//使能 HSE 时钟
	RCC_HSEConfig(RCC_HSE_ON);
	
	HSEStatus = RCC_WaitForHSEStartUp();

	if(HSEStatus == SUCCESS)
	{
		//使能预取指和等待2个延迟周期
		FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);
		FLASH_SetLatency(FLASH_Latency_2);
		
		//配置APH、APB1、APB2时钟
		RCC_HCLKConfig(RCC_SYSCLK_Div1);
		RCC_PCLK1Config(RCC_HCLK_Div2);
		RCC_PCLK2Config(RCC_HCLK_Div1);
		
		//配置PLLCLK = HSE * RCC_PLLMul_x
		RCC_PLLConfig(RCC_PLLSource_HSE_Div1,RCC_PLLMul_x);
		
		//使能PLL
		RCC_PLLCmd(ENABLE);
		
		//等待PLL时钟稳定
		while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);
		
		//选择系统时钟
		RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
		
		//等待PLLCLK切换为系统时钟
		while(RCC_GetSYSCLKSource() != 0x08);
		
	}
	else
	{
		//如果HSE启动失败,用户可以在这里添加处理错误的代码
	}
}

类似,再写一个void HSI_SetSysClk(uint32_t RCC_PLLMul_x)。

void HSI_SetSysClk(uint32_t RCC_PLLMul_x)
{ 
	__IO uint32_t HSIStatus = 0; 
	
	//把RCC寄存器复位成复位值
	RCC_DeInit();
	
	//使能 HSE 时钟
	RCC_HSICmd(ENABLE);
	
	HSIStatus = RCC->CR & RCC_CR_HSIRDY;

	if(HSIStatus == RCC_CR_HSIRDY)
	{
		//使能预取指和等待2个延迟周期
		FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);
		FLASH_SetLatency(FLASH_Latency_2);
		
		//配置APH、APB1、APB2时钟
		RCC_HCLKConfig(RCC_SYSCLK_Div1);
		RCC_PCLK1Config(RCC_HCLK_Div2);
		RCC_PCLK2Config(RCC_HCLK_Div1);
		
		//配置PLLCLK = HSE * RCC_PLLMul_x
		RCC_PLLConfig(RCC_PLLSource_HSI_Div2,RCC_PLLMul_x);
		
		//使能PLL
		RCC_PLLCmd(ENABLE);
		
		//等待PLL时钟稳定
		while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);
		
		//选择系统时钟
		RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
		
		//等待PLLCLK切换为系统时钟
		while(RCC_GetSYSCLKSource() != 0x08);
		
	}
	else
	{
		//如果HSI启动失败,用户可以在这里添加处理错误的代码
	}
}

对于配置时钟函数,有以下步骤:

1)复位RCC

2)使能HSE时钟,等待HSE使能完成

3)使能预取指和进行时延等待

4)配置AHB、APB1和APB2

5)配置PLL

6)使能PLL,等待PLL使能完成

7)对系统时钟进行选择,等待选择完成

HAL库_RCC

SystemClock_Config()函数

void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

  /** Initializes the RCC Oscillators according to the specified parameters
  * in the RCC_OscInitTypeDef structure.
  */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
  RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }

  /** Initializes the CPU, AHB and APB buses clocks
  */
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
  {
    Error_Handler();
  }
}

HAL_RCC_ClockConfig()函数

/**
  * @brief  Initializes the CPU, AHB and APB buses clocks according to the specified
  *         parameters in the RCC_ClkInitStruct.
  * @param  RCC_ClkInitStruct pointer to an RCC_OscInitTypeDef structure that
  *         contains the configuration information for the RCC peripheral.
  * @param  FLatency FLASH Latency
  *          The value of this parameter depend on device used within the same series
  * @note   The SystemCoreClock CMSIS variable is used to store System Clock Frequency
  *         and updated by @ref HAL_RCC_GetHCLKFreq() function called within this function
  *
  * @note   The HSI is used (enabled by hardware) as system clock source after
  *         start-up from Reset, wake-up from STOP and STANDBY mode, or in case
  *         of failure of the HSE used directly or indirectly as system clock
  *         (if the Clock Security System CSS is enabled).
  *
  * @note   A switch from one clock source to another occurs only if the target
  *         clock source is ready (clock stable after start-up delay or PLL locked).
  *         If a clock source which is not yet ready is selected, the switch will
  *         occur when the clock source will be ready.
  *         You can use @ref HAL_RCC_GetClockConfig() function to know which clock is
  *         currently used as system clock source.
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_RCC_ClockConfig(RCC_ClkInitTypeDef  *RCC_ClkInitStruct, uint32_t FLatency)
{
  uint32_t tickstart;

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

  /* Check the parameters */
  assert_param(IS_RCC_CLOCKTYPE(RCC_ClkInitStruct->ClockType));
  assert_param(IS_FLASH_LATENCY(FLatency));

  /* To correctly read data from FLASH memory, the number of wait states (LATENCY)
  must be correctly programmed according to the frequency of the CPU clock
    (HCLK) of the device. */

#if defined(FLASH_ACR_LATENCY)
  /* Increasing the number of wait states because of higher CPU frequency */
  if (FLatency > __HAL_FLASH_GET_LATENCY())
  {
    /* Program the new number of wait states to the LATENCY bits in the FLASH_ACR register */
    __HAL_FLASH_SET_LATENCY(FLatency);

    /* Check that the new number of wait states is taken into account to access the Flash
    memory by reading the FLASH_ACR register */
    if (__HAL_FLASH_GET_LATENCY() != FLatency)
  {
    return HAL_ERROR;
  }
}

#endif /* FLASH_ACR_LATENCY */
/*-------------------------- HCLK Configuration --------------------------*/
if (((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_HCLK) == RCC_CLOCKTYPE_HCLK)
  {
    /* Set the highest APBx dividers in order to ensure that we do not go through
    a non-spec phase whatever we decrease or increase HCLK. */
    if (((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_PCLK1) == RCC_CLOCKTYPE_PCLK1)
    {
      MODIFY_REG(RCC->CFGR, RCC_CFGR_PPRE1, RCC_HCLK_DIV16);
    }

    if (((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_PCLK2) == RCC_CLOCKTYPE_PCLK2)
    {
      MODIFY_REG(RCC->CFGR, RCC_CFGR_PPRE2, (RCC_HCLK_DIV16 << 3));
    }

    /* Set the new HCLK clock divider */
    assert_param(IS_RCC_HCLK(RCC_ClkInitStruct->AHBCLKDivider));
    MODIFY_REG(RCC->CFGR, RCC_CFGR_HPRE, RCC_ClkInitStruct->AHBCLKDivider);
  }

  /*------------------------- SYSCLK Configuration ---------------------------*/
  if (((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_SYSCLK) == RCC_CLOCKTYPE_SYSCLK)
  {
    assert_param(IS_RCC_SYSCLKSOURCE(RCC_ClkInitStruct->SYSCLKSource));

    /* HSE is selected as System Clock Source */
    if (RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_HSE)
    {
      /* Check the HSE ready flag */
      if (__HAL_RCC_GET_FLAG(RCC_FLAG_HSERDY) == RESET)
      {
        return HAL_ERROR;
      }
    }
    /* PLL is selected as System Clock Source */
    else if (RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_PLLCLK)
    {
      /* Check the PLL ready flag */
      if (__HAL_RCC_GET_FLAG(RCC_FLAG_PLLRDY) == RESET)
      {
        return HAL_ERROR;
      }
    }
    /* HSI is selected as System Clock Source */
    else
    {
      /* Check the HSI ready flag */
      if (__HAL_RCC_GET_FLAG(RCC_FLAG_HSIRDY) == RESET)
      {
        return HAL_ERROR;
      }
    }
    __HAL_RCC_SYSCLK_CONFIG(RCC_ClkInitStruct->SYSCLKSource);

    /* Get Start Tick */
    tickstart = HAL_GetTick();

    while (__HAL_RCC_GET_SYSCLK_SOURCE() != (RCC_ClkInitStruct->SYSCLKSource << RCC_CFGR_SWS_Pos))
    {
      if ((HAL_GetTick() - tickstart) > CLOCKSWITCH_TIMEOUT_VALUE)
      {
        return HAL_TIMEOUT;
      }
    }
  }

#if defined(FLASH_ACR_LATENCY)
  /* Decreasing the number of wait states because of lower CPU frequency */
  if (FLatency < __HAL_FLASH_GET_LATENCY())
  {
    /* Program the new number of wait states to the LATENCY bits in the FLASH_ACR register */
    __HAL_FLASH_SET_LATENCY(FLatency);

    /* Check that the new number of wait states is taken into account to access the Flash
    memory by reading the FLASH_ACR register */
    if (__HAL_FLASH_GET_LATENCY() != FLatency)
  {
    return HAL_ERROR;
  }
}
#endif /* FLASH_ACR_LATENCY */

/*-------------------------- PCLK1 Configuration ---------------------------*/
if (((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_PCLK1) == RCC_CLOCKTYPE_PCLK1)
  {
    assert_param(IS_RCC_PCLK(RCC_ClkInitStruct->APB1CLKDivider));
    MODIFY_REG(RCC->CFGR, RCC_CFGR_PPRE1, RCC_ClkInitStruct->APB1CLKDivider);
  }

  /*-------------------------- PCLK2 Configuration ---------------------------*/
  if (((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_PCLK2) == RCC_CLOCKTYPE_PCLK2)
  {
    assert_param(IS_RCC_PCLK(RCC_ClkInitStruct->APB2CLKDivider));
    MODIFY_REG(RCC->CFGR, RCC_CFGR_PPRE2, ((RCC_ClkInitStruct->APB2CLKDivider) << 3));
  }

  /* Update the SystemCoreClock global variable */
  SystemCoreClock = HAL_RCC_GetSysClockFreq() >> AHBPrescTable[(RCC->CFGR & RCC_CFGR_HPRE) >> RCC_CFGR_HPRE_Pos];

  /* Configure the source of time base considering new system clocks settings*/
  HAL_InitTick(uwTickPrio);

  return HAL_OK;
}

HAL_RCC结构体

typedef struct
{
  uint32_t OscillatorType;
  uint32_t HSEState;              
  uint32_t HSEPredivValue;      
  uint32_t LSEState;              
  uint32_t HSIState;              
  uint32_t HSICalibrationValue;  
  uint32_t LSIState;              
  RCC_PLLInitTypeDef PLL;         
} RCC_OscInitTypeDef;

typedef struct
{
  uint32_t ClockType;        //RCC_CLOCKTYPE_SYSCLK、RCC_CLOCKTYPE_HCLK、RCC_CLOCKTYPE_PCLK1、RCC_CLOCKTYPE_PCLK2        
  uint32_t SYSCLKSource;     //RCC_SYSCLKSOURCE_HSI、RCC_SYSCLKSOURCE_HSE、RCC_SYSCLKSOURCE_PLLCLK     
  uint32_t AHBCLKDivider;    //RCC_SYSCLK_DIVx     
  uint32_t APB1CLKDivider;   //RCC_HCLK_DIVx     
  uint32_t APB2CLKDivider;   //RCC_HCLK_DIVx     
} RCC_ClkInitTypeDef;

HAL_RCC函数

void              HAL_RCC_DeInit(void);
HAL_StatusTypeDef HAL_RCC_OscConfig(RCC_OscInitTypeDef  *RCC_OscInitStruct);
HAL_StatusTypeDef HAL_RCC_ClockConfig(RCC_ClkInitTypeDef  *RCC_ClkInitStruct, uint32_t FLatency);

void              HAL_RCC_MCOConfig(uint32_t RCC_MCOx, uint32_t RCC_MCOSource, uint32_t RCC_MCODiv);
void              HAL_RCC_EnableCSS(void);
void              HAL_RCC_DisableCSS(void);
uint32_t          HAL_RCC_GetSysClockFreq(void);
uint32_t          HAL_RCC_GetHCLKFreq(void);
uint32_t          HAL_RCC_GetPCLK1Freq(void);
uint32_t          HAL_RCC_GetPCLK2Freq(void);
void              HAL_RCC_GetOscConfig(RCC_OscInitTypeDef  *RCC_OscInitStruct);
void              HAL_RCC_GetClockConfig(RCC_ClkInitTypeDef  *RCC_ClkInitStruct, uint32_t *pFLatency);

void              HAL_RCC_NMI_IRQHandler(void);

void              HAL_RCC_CSSCallback(void);

  • 3
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值