HAL_RCC

文章目录

  • 一、RCC简介
    • [   两大功能:](#   两大功能:)
  • 二、RCC模块详解
    • [   1、时钟框图](#   1、时钟框图)
    • [   2、系统时钟](#   2、系统时钟)
      • [     1. HSE高速外部时钟信号](#     1. HSE高速外部时钟信号)
      • [     2. PLL时钟源](#     2. PLL时钟源)
      • [     3. PLL时钟PLLCLK](#     3. PLL时钟PLLCLK)
      • [     4. 系统时钟SYSCLK](#     4. 系统时钟SYSCLK)
      • [     5. AHB总线时钟HCLK](#     5. AHB总线时钟HCLK)
      • [     6. APB2总线时钟PCLK2](#     6. APB2总线时钟PCLK2)
      • [     7. APB1总线时钟PCLK1](#     7. APB1总线时钟PCLK1)
    • [   3、其它时钟](#   3、其它时钟)
      • [     1. USB时钟](#     1. USB时钟)
      • [     2. Cortex系统时钟](#     2. Cortex系统时钟)
      • [     3. ADC时钟](#     3. ADC时钟)
      • [     4. RTC时钟、独立看门狗时钟](#     4. RTC时钟、独立看门狗时钟)
      • [     5. MCO时钟输出](#     5. MCO时钟输出)
    • [   4、时钟源](#   4、时钟源)
    • [   5、时钟信号](#   5、时钟信号)
    • [   6、时钟树结构总结](#   6、时钟树结构总结)
  • 三、CudeMx配置RCC
    • [   1、常用配置](#   1、常用配置)
    • [   2、HSI 直驱(最简 / 无晶振)](#   2、HSI 直驱(最简 / 无晶振))
    • [   3、HSE 直驱(高精度 / 不倍频)](#   3、HSE 直驱(高精度 / 不倍频))
    • [   4、PLL 倍频(最高性能,最常用)](#   4、PLL 倍频(最高性能,最常用))
    • [   5、低功耗(主频低、功耗小)](#   5、低功耗(主频低、功耗小))
  • 四、RCC模块组成
    • [   1、数据结构](#   1、数据结构)
      • [     1. RCC_OscInitTypeDef](#     1. RCC_OscInitTypeDef)
      • [     2. RCC_ClkInitTypeDef](#     2. RCC_ClkInitTypeDef)
      • [     3. RCC_PLLInitTypeDef](#     3. RCC_PLLInitTypeDef)
    • [   2、句柄](#   2、句柄)
    • [   3、API函数](#   3、API函数)
      • [     1. 时钟源配置](#     1. 时钟源配置)
      • [     2. 系统时钟与总线配置](#     2. 系统时钟与总线配置)
      • [     3. 外设时钟使能](#     3. 外设时钟使能)
      • [     4. 外设时钟失能](#     4. 外设时钟失能)
      • [     5. 外设复位](#     5. 外设复位)
      • [     6. 获取系统时钟频率](#     6. 获取系统时钟频率)
      • [     7. 使能 CSS 时钟安全系统](#     7. 使能 CSS 时钟安全系统)
    • [   4、状态/错误](#   4、状态/错误)
      • [     1.就绪状态:](#     1.就绪状态:)
      • [     2.系统时钟源状态:](#     2.系统时钟源状态:)
      • [     3.频率状态:](#     3.频率状态:)
  • 五、RCC模块应用实例
    • [   1、SystemInit默认时钟配置MCO查看](#   1、SystemInit默认时钟配置MCO查看)
    • [   2、使用内部HSI通过PLL倍频程序](#   2、使用内部HSI通过PLL倍频程序)
    • [   3、STM32F103 标准 RCC 配置(72MHz)](#   3、STM32F103 标准 RCC 配置(72MHz))
    • [   4、STM32F103 的 MCO 强行输出 72MHz(失真)](#   4、STM32F103 的 MCO 强行输出 72MHz(失真))
  • 六、RCC中断
    • [   1、RCC_IRQn](#   1、RCC_IRQn)
    • [   2、RCC_IRQn中断的应用场景](#   2、RCC_IRQn中断的应用场景)
    • [   3、配置RCC_IRQn中断的基本步骤](#   3、配置RCC_IRQn中断的基本步骤)
    • [   4、简单代码实例](#   4、简单代码实例)

一、RCC简介

RCC :Reset Clock Control 复位和时钟控制器。

两大功能:

时钟管理:

给 CPU、GPIO、ADC、TIM、UART、I2C、SPI、USB 等所有外设提供时钟。

没有时钟,外设完全不工作。

复位管理:

系统复位

外设复位(单独复位 UART、TIM 等)

电源复位

RCC 就是 STM32 的 "心脏与供电总开关",负责给整个芯片提供稳定时钟,并控制所有外设的启停。

二、RCC模块详解

1、时钟框图

2、系统时钟

1. HSE高速外部时钟信号

HSE是高速的外部时钟信号,可以由有源晶振或者无源晶振提供,频率从4-16MHZ不等。

当使用有源晶振时,时钟从OSC_IN引脚进入,OSC_OUT引脚悬空,当选用无源晶振时,时钟从OSC_IN和OSC_OUT进入,并且要配谐振电容。

HSE最常使用的就是8M的无源晶振。

当确定PLL时钟来源的时候,HSE可以不分频或者2分频,这个由时钟配置寄存器CFGR的位17:PLLXTPRE设置。

这量设置为HSE不分频。

2. PLL时钟源

PLL时钟来源可以有两个,一个来自HSE,另外一个是HSI/2,具体用哪个由时钟配置寄存器CFGR的位16:PLLSRC设置。

HSI是内部高速的时钟信号,频率为8M,根据温度和环境的情况频率会有漂移,一般不作为PLL的时钟来源。

这时选HSE作为PLL的时钟来源。

3. PLL时钟PLLCLK

通过设置PLL的倍频因子,可以对PLL的时钟来源进行倍频,倍频因子可以是:[2,3,4,5,6,7,8,9,10,11,12,13,14,15,16],具体设置成多少,由时钟配置寄存器CFGR的位21-18:PLLMUL[3:0]设置。

我们这里设置为9倍频,因为上一步我们设置PLL的时钟来源为HSE=8M,所以经过PLL倍频之后的PLL时钟:PLLCLK = 8M *9 = 72M。72M是ST官方推荐的稳定运行时钟,如果你想超频的话,增大倍频因子即可,最高为128M。

我们这里设置PLL时钟:PLLCLK = 8M *9 = 72M。

4. 系统时钟SYSCLK

系统时钟来源可以是:HSI、PLLCLK、HSE,具体的时钟配置寄存器CFGR的位1-0:SW[1:0]设置。

这里设置系统时钟:SYSCLK = PLLCLK = 72M。

5. AHB总线时钟HCLK

系统时钟SYSCLK经过AHB预分频器分频之后得到时钟叫APB总线时钟,即HCLK,分频因子可以是:[1,2,4,8,16,64,128,256,512],具体的由时钟配置寄存器CFGR的位7-4 :HPRE[3:0]设置。

片上大部分外设的时钟都是经过HCLK分频得到,至于AHB总线上的外设的时钟设置为多少,得等到我们使用该外设的时候才设置,我们这里只需粗线条的设置好APB的时钟即可。

这里设置为1分频,即HCLK=SYSCLK=72M。

6. APB2总线时钟PCLK2

APB2总线时钟PCLK2由HCLK经过高速APB2预分频器得到,分频因子可以是:[1,2,4,8,16],具体由时钟配置寄存器CFGR的位13-11:PPRE2[2:0]决定。

HCLK2属于高速的总线时钟,片上高速的外设就挂载到这条总线上,比如全部的GPIO、USART1、SPI1等。

至于APB2总线上的外设的时钟设置为多少,得等到使用该外设的时候才设置,这里只需粗线条的设置好APB2的时钟即可。

这里设置为1分频,即PCLK2 = HCLK = 72M。

7. APB1总线时钟PCLK1

APB1总线时钟PCLK1由HCLK经过低速APB预分频器得到,分频因子可以是:[1,2,4,8,16],具体的由时钟配置寄存器CFGR的位10-8:PRRE1[2:0]决定。

PCLK1属于低速的总线时钟,最高为36M,片上低速的外设就挂载到这条总线上,比如USART2/3/4/5、SPI2/3,I2C1/2等。

至于APB1总线上的外设的时钟设置为多少,得等到使用该外设的时候才设置,这里只需粗线条的设置好APB1的时钟即可。

这里设置为2分频,即PCLK1 = HCLK/2 = 36M。

3、其它时钟

1. USB时钟

USB时钟是由PLLCLK经过USB预分频器得到,分频因子可以是:[1,1.5],具体的由时钟配置寄存器CFGR的位22:USBPRE配置。

USB的时钟最高是48M,根据分频因子反推过来算,PLLCLK只能是48M或者是72M。

一般设置PLLCLK=72M,USBCLK=48M。USB对时钟要求比较高,所以PLLCLK只能是由HSE倍频得到,不能使用HSI倍频。

2. Cortex系统时钟

Cortex系统时钟由HCLK 8分频得到,等于9M,Cortex系统时钟用来驱动内核的系统定时器SysTick,SysTick一般用于操作系统的时钟节拍,也可以用做普通的定时。

3. ADC时钟

ADC时钟由PCLK2经过ADC预分频器得到,分频因子可以是[2,4,6,8],具体的由时钟配置寄存器CFGR的位15-14:ADCPRE[1:0]决定。

ADC时钟最高只能是14M,如果采样周期设置成最短的1.5个周期的话,ADC的转换时间可以达到最短的1us。如果真要达到最短的转换时间1us的话,那ADC的时钟就得是14M,反推PCLK2的时钟只能是:28M、56M、84M、112M,鉴于PCLK2最高是72M,所以只能取28M和56M。

4. RTC时钟、独立看门狗时钟

RTC时钟可由HSE/128分频得到,也可由低速外部时钟信号LSE提供,频率为32.768KHZ,也可由低速内部时钟信号LSI提供,具体选用哪个时钟由备份域控制寄存器BDCR的位9-8:RTCSEL[1:0]配置。

独立看门狗的时钟由LSI提供,且只能是由LSI提供,LSI是低速的内部时钟信号,频率为30~60KHZ直接不等,一般取40KHZ。

5. MCO时钟输出

MCO是microcontroller clock output的缩写,是微控制器时钟输出引脚,在STM32 F1系列中 由 PA8复用所得,主要作用是可以对外提供时钟,相当于一个有源晶振。

MCO的时钟来源可以是:PLLCLK/2、HSI、HSE、SYSCLK,具体选哪个由时钟配置寄存器CFGR的位26-24:MCO[2:0]决定。除了对外提供时钟这个作用之外,还可以通过示波器监控MCO引脚的时钟输出来验证系统时钟配置是否正确。

4、时钟源

HSI:内部高速 RC 时钟,约 8MHz / 16MHz(精度一般)

HSE:外部晶振,4~32MHz(精度高,USB/WIFI/ 蓝牙必须用)

LSI:内部低速 RC,约 32kHz,给 IWDG、RTC

LSE:外部 32.768kHz 晶振,给 RTC 走时(精准)

一般我们使用外部晶振,配置为72MHz。

5、时钟信号

SYSCLK:系统核心时钟(如 72MHz、168MHz、480MHz)

AHB:CPU、内存、DMA 时钟

APB1:低速外设(UART2/3/4、I2C、SPI2、DAC、TIM2~7)

APB2:高速外设(GPIO、ADC、UART1、TIM1/8、SPI1)

PLL48CK / USB48MHz:USB、I2S 必须的 48MHz 精确时钟

6、时钟树结构总结

外部 / 内部时钟 → PLL 倍频 → 系统时钟 SYSCLK → 分频到 AHB/AHB1/APB1/APB2 → 各个外设。

三、CudeMx配置RCC

1、常用配置

2、HSI 直驱(最简 / 无晶振)

SYSCLK = 8MHz(HSI 直接输出)

无需外部晶振,电路最简

适用:低成本、低精度、快速启动场景

3、HSE 直驱(高精度 / 不倍频)

SYSCLK = HSE 频率(如 8MHz)

精度高、稳定,无需 PLL

适用:对时序敏感但不需要 72MHz 主频

4、PLL 倍频(最高性能,最常用)

输入:HSE(8MHz) 或 HSI/2(4MHz)

倍频:PLLMUL ×2~×16(F103 最高到 72MHz)

典型:8MHz HSE ×9 = 72MHz(官方推荐)

适用:需要全速运行、USB、高速外设

5、低功耗(主频低、功耗小)

输入:HIS(8MHz)

典型:HSI/2+PLL×4 = 16MHz

适用:低功耗场景

四、RCC模块组成

1、数据结构

1. RCC_OscInitTypeDef

作用:配置时钟源(HSE/HSI/PLL)

c 复制代码
			typedef struct {
			  uint32_t OscillatorType;       // 选择要配置的时钟源
			  uint32_t HSEState;             // HSE 开启/关闭
			  uint32_t LSEState;             // LSE 开启/关闭
			  uint32_t HSIState;             // HSI 开启/关闭
			  uint32_t LSIState;             // LSI 开启/关闭
			  RCC_PLLInitTypeDef PLL;        // PLL 配置(倍频、源)
			} RCC_OscInitTypeDef;

2. RCC_ClkInitTypeDef

作用:配置系统时钟、总线分频(SYSCLK、AHB、APB1、APB2)

c 复制代码
			typedef struct {
			  uint32_t ClockType;            // 要配置的时钟(SYSCLK/HCLK/PCLK1/PCLK2)
			  uint32_t SYSCLKSource;         // 系统时钟源(PLL/HSE/HSI)
			  uint32_t AHBCLKDivider;        // AHB 分频
			  uint32_t APB1CLKDivider;       // APB1 分频(最高36M)
			  uint32_t APB2CLKDivider;       // APB2 分频
			} RCC_ClkInitTypeDef;

3. RCC_PLLInitTypeDef

作用:PLL 倍频配置

c 复制代码
			typedef struct {
			  uint32_t PLLState;             // PLL 开启/关闭
			  uint32_t PLLSource;            // PLL 源(HSE/HSI)
			  uint32_t PLLMUL;               // 倍频系数 ×2~×16
			} RCC_PLLInitTypeDef;

2、句柄

RCC 是系统内核,没有句柄!

直接用函数配置。

3、API函数

1. 时钟源配置

// 配置晶振、PLL

HAL_RCC_OscConfig(RCC_OscInitTypeDef *RCC_OscInitStruct);

2. 系统时钟与总线配置

// 配置 SYSCLK、AHB、APB1、APB2

HAL_RCC_ClockConfig(RCC_ClkInitTypeDef *RCC_ClkInitStruct, uint32_t FLatency);

3. 外设时钟使能

// GPIO

__HAL_RCC_GPIOA_CLK_ENABLE();

__HAL_RCC_GPIOB_CLK_ENABLE();

// UART

__HAL_RCC_USART1_CLK_ENABLE();

// ADC

__HAL_RCC_ADC1_CLK_ENABLE();

// TIM

__HAL_RCC_TIM2_CLK_ENABLE();

// I2C

__HAL_RCC_I2C1_CLK_ENABLE();

// USB

__HAL_RCC_USB_CLK_ENABLE();

4. 外设时钟失能

__HAL_RCC_GPIOA_CLK_DISABLE();

5. 外设复位

__HAL_RCC_USART1_FORCE_RESET();

__HAL_RCC_USART1_RELEASE_RESET();

6. 获取系统时钟频率

HAL_RCC_GetSysClockFreq(); // 获取 SYSCLK

HAL_RCC_GetHCLKFreq(); // 获取 AHB

HAL_RCC_GetPCLK1Freq(); // 获取 APB1

HAL_RCC_GetPCLK2Freq(); // 获取 APB2

7. 使能 CSS 时钟安全系统

HAL_RCC_EnableCSS();

4、状态/错误

1.就绪状态:

时钟是否稳定可用。

c 复制代码
			// 返回值:SET(已就绪) / RESET(未就绪)
			HAL_RCC_GetOscReadyState(RCC_OSC_HSI);
			HAL_RCC_GetOscReadyState(RCC_OSC_HSE);
			HAL_RCC_GetOscReadyState(RCC_OSC_LSE);
			HAL_RCC_GetOscReadyState(RCC_OSC_LSI);
			HAL_RCC_GetOscReadyState(RCC_OSC_PLL);

2.系统时钟源状态:

当前是 HSI/HSE/PLL

c 复制代码
			uint32_t sys_source = HAL_RCC_GetSysClockSource();
			// 返回值可能是:
			// RCC_SYSCLKSOURCE_HSI
			// RCC_SYSCLKSOURCE_HSE
			// RCC_SYSCLKSOURCE_PLLCLK

3.频率状态:

实际运行时钟多少 MHz

c 复制代码
			uint32_t sysclk = HAL_RCC_GetSysClockFreq();  // 系统时钟
			uint32_t hclk   = HAL_RCC_GetHCLKFreq();      // AHB
			uint32_t pclk1  = HAL_RCC_GetPCLK1Freq();     // APB1
			uint32_t pclk2  = HAL_RCC_GetPCLK2Freq();     // APB2

五、RCC模块应用实例

1、SystemInit默认时钟配置MCO查看

c 复制代码
		#include "stm32f1xx_hal.h"
		
		uint32_t  HCLKFreq;  
		uint32_t  PCLK1Freq;
		uint32_t  PCLK2Freq;
		
		int main(void){
		        //HAL库核心初始化
		        HAL_Init();
		        //配置系统时钟输出到MCO(PA8)
		        HAL_RCC_MCOConfig(RCC_MCO1,RCC_MCO1SOURCE_SYSCLK,RCC_MCODIV_1);        
		        //自动读取当前 RCC 时钟配置,计算并更新系统时钟频率变量 SystemCoreClock。
		        SystemCoreClockUpdate();
		        //获取HCLK时钟
		        HCLKFreq = HAL_RCC_GetHCLKFreq();
		        //获取PCLK1时钟
		        PCLK1Freq = HAL_RCC_GetPCLK1Freq();
		        //获取PCLK2时钟
		        PCLK2Freq = HAL_RCC_GetPCLK2Freq();
		}

2、使用内部HSI通过PLL倍频程序

c 复制代码
		#include "stm32f1xx_hal.h"
		
		uint32_t  HCLKFreq;
		uint32_t  PCLK1Freq;
		uint32_t  PCLK2Freq;
		
		int main(void){
		        //HAL库初始化
		        HAL_Init();
		        
		        RCC_OscInitTypeDef RCC_OscInitType = {0};
		        RCC_ClkInitTypeDef RCC_ClkInitType = {0};
		        //配置时钟源
		        RCC_OscInitType.OscillatorType = RCC_OSCILLATORTYPE_HSI;
		        RCC_OscInitType.HSIState = RCC_HSI_ON;
		        RCC_OscInitType.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
		        RCC_OscInitType.PLL.PLLState = RCC_PLL_ON;
		        RCC_OscInitType.PLL.PLLSource = RCC_PLLSOURCE_HSI_DIV2;
		        RCC_OscInitType.PLL.PLLMUL = RCC_PLL_MUL16;
		        HAL_RCC_OscConfig(&RCC_OscInitType);
		        //配置时钟信号
		        RCC_ClkInitType.ClockType = RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2;
		        RCC_ClkInitType.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
		        RCC_ClkInitType.AHBCLKDivider = RCC_SYSCLK_DIV1;
		        RCC_ClkInitType.APB1CLKDivider = RCC_HCLK_DIV2;
		        RCC_ClkInitType.APB2CLKDivider = RCC_HCLK_DIV1;
		        HAL_RCC_ClockConfig(&RCC_ClkInitType,FLASH_LATENCY_2);        
		        //MCO输出SYSCLK到PA8
		        HAL_RCC_MCOConfig(RCC_MCO1,RCC_MCO1SOURCE_SYSCLK,RCC_MCODIV_1);        
		        
		        //自动读取当前 RCC 时钟配置,计算并更新系统时钟频率变量 SystemCoreClock。
		        SystemCoreClockUpdate();
		        //获取HCLK时钟
		        HCLKFreq = HAL_RCC_GetHCLKFreq();
		        //获取PCLK1时钟
		        PCLK1Freq = HAL_RCC_GetPCLK1Freq();
		        //获取PCLK2时钟
		        PCLK2Freq = HAL_RCC_GetPCLK2Freq();
		}

3、STM32F103 标准 RCC 配置(72MHz)

标准RCC配置,F103复用代码。

c 复制代码
		void SystemClock_Config(void)
		{
		  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
		  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
		
		  // 1. 配置时钟源 + PLL
		  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
		  RCC_OscInitStruct.HSEState = RCC_HSE_ON;
		  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
		  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
		  RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;    // 8M ×9 =72M
		  HAL_RCC_OscConfig(&RCC_OscInitStruct);
		
		  // 2. 配置系统时钟与总线
		  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_SYSCLK |
		                                RCC_CLOCKTYPE_HCLK |
		                                RCC_CLOCKTYPE_PCLK1 |
		                                RCC_CLOCKTYPE_PCLK2;
		
		  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
		  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
		  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;  // 36M
		  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;  // 72M
		
		  HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2);
		}

4、STM32F103 的 MCO 强行输出 72MHz(失真)

输出 72MHz(选 SYSCLK), GPIO 硬件上限只有 50MHz,波形会失真。

要稳定、干净的时钟,优先用 36MHz(PLL/2)。

c 复制代码
		// 1. 先把系统时钟配置为 72MHz(PLL=72MHz)
		SystemClock_Config();
		
		// 2. 配置 PA8 为复用推挽,速度设为最高(50MHz)
		__HAL_RCC_GPIOA_CLK_ENABLE();
		GPIO_InitTypeDef GPIO_InitStruct = {0};
		GPIO_InitStruct.Pin = GPIO_PIN_8;
		GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
		GPIO_InitStruct.Pull = GPIO_NOPULL;
		GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; // 50MHz 档
		HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
		
		// 3. 选择输出 SYSCLK(72MHz)
		HAL_RCC_MCOConfig(RCC_MCO, RCC_MCO_SYSCLK, RCC_MCODIV_1);
		// 4. 输出 PLLCLK/2 = 72MHz/2 = 36MHz(建议使用)
		//HAL_RCC_MCOConfig(RCC_MCO, RCC_MCO_PLLCLK_Div2, RCC_MCODIV_1);

六、RCC中断

RCC 中断 = 复位与时钟控制器产生的中断。

1、RCC_IRQn

RCC_IRQn 并不是一个直接代表某种特定外设中断的中断类型,而是嵌套向量中断控制器(NVIC)中用于表示RCC(Reset and Clock Control)模块中断请求(IRQ)的一个枚举值。

在STM32系列微控制器中,RCC模块负责管理系统的时钟和复位功能,包括启用或禁用外设时钟、配置系统时钟源等。

当某个与RCC相关的中断事件发生时,例如时钟安全系统(CSS)中断、内部高速时钟(HSI)就绪中断、外部高速时钟(HSE)就绪中断等,RCC模块会向NVIC发出中断请求,这个请求在NVIC中被标识为RCC_IRQn。

通过配置NVIC,可以将RCC_IRQn中断的优先级设置,并指定相应的中断处理函数来响应这些事件。

2、RCC_IRQn中断的应用场景

时钟故障检测:

当启用CSS(Clock Security System)功能时,如果检测到外部时钟源(如HSE)出现故障,RCC会触发一个中断,通知处理器执行相应的故障处理程序。

时钟准备就绪:

当HSI或HSE等内部或外部时钟源稳定并准备好使用时,RCC可以配置为在这些时钟源就绪时产生中断,以便及时更新系统时钟配置。

低功耗模式唤醒:

在某些低功耗模式下,可以通过配置RCC中断来实现从低功耗模式中唤醒系统,例如当某个特定的时钟源恢复工作时触发中断,从而唤醒处理器。

3、配置RCC_IRQn中断的基本步骤

为了使用RCC_IRQn中断,需要按照以下步骤进行配置:

1.启用RCC时钟

首先确保RCC模块本身的时钟已经被正确启用,这通常在系统初始化阶段完成。

2.配置RCC中断源:

根据需要启用的中断源(如CSS中断、HSI就绪中断等),配置RCC的相关寄存器以启用对应的中断。

3.配置NVIC:

使用NVIC配置函数(如NVIC_Init())为RCC_IRQn设置合适的优先级,并启用该中断。

4.编写中断服务例程:

在中断向量表中找到RCC_IRQn对应的中断处理函数(通常在stm32f4xx_it.c文件中定义),并编写具体的中断处理逻辑。

4、简单代码实例

c 复制代码
		#include "stm32f4xx.h"
		
		void RCC_Configuration(void) {
		    // 启用HSE时钟
		    RCC_HSEConfig(RCC_HSE_ON);
		    
		    // 等待HSE稳定
		    if (RCC_WaitForHSEStartUp() == SUCCESS) {
		        // HSE已经稳定,启用HSE就绪中断
		        RCC_ITConfig(RCC_IT_HSIRDY, ENABLE);
		    }
		}
		
		void NVIC_Configuration(void) {
		    NVIC_InitTypeDef NVIC_InitStructure;
		
		    // 设置NVIC优先级分组
		    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
		
		    // 配置RCC_IRQn中断优先级
		    NVIC_InitStructure.NVIC_IRQChannel = RCC_IRQn;
		    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
		    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
		    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
		    NVIC_Init(&NVIC_InitStructure);
		}
		
		void RCC_IRQHandler(void) {
		    // 检查是否是HSE就绪中断
		    if (RCC_GetITStatus(RCC_IT_HSIRDY) != RESET) {
		        // 执行HSE就绪中断处理逻辑
		        // ...
		
		        // 清除中断标志
		        RCC_ClearITPendingBit(RCC_IT_HSIRDY);
		    }
		}
相关推荐
RFID舜识物联网2 小时前
耐高温RFID标签提升汽车喷涂线效率,精准度再升级
大数据·人工智能·嵌入式硬件·物联网·汽车
Suifqwu2 小时前
rk3576(5)之编些简单GPIO驱动
单片机·嵌入式硬件
爱喝纯牛奶的柠檬3 小时前
【已验证】STM32采集声音传感器实现环境声实时监测
单片机·嵌入式硬件
我先去打把游戏先3 小时前
Git 一个本地仓库同时推送到两个远程仓库(私人 GitHub + 公司 Git)保姆级教程
git·vscode·单片机·嵌入式硬件·物联网·学习·github
悠哉悠哉愿意3 小时前
【物联网学习笔记】OLED
笔记·单片机·嵌入式硬件·物联网·学习
三佛科技-134163842123 小时前
融蜡机方案,脱毛热蜡机MCU控制方案开发
单片机·嵌入式硬件·物联网·智能家居·pcb工艺
三佛科技-134163842123 小时前
智能小夜灯方案,智能遥控台灯方案开发MCU控制方案设计
单片机·嵌入式硬件·物联网·智能家居·pcb工艺
誰能久伴不乏3 小时前
给开发板装上嘴巴与耳朵:i.MX6ULL 裸机串口 (UART) 驱动终极指南
arm开发·c++·单片机·嵌入式硬件·arm
wdfk_prog3 小时前
MCU内核电压不稳导致程序跑飞的现象、原因与影响
数据库·单片机·嵌入式硬件