stm32f10x_rcc

STM32F10x RCC(复位和时钟控制)外设标准库函数参考文档

数据类型定义

结构体类型

RCC_ClocksTypeDef - 时钟频率信息结构体

typedef struct
{
  uint32_t SYSCLK_Frequency;  /* 系统时钟频率,单位Hz */
  uint32_t HCLK_Frequency;    /* AHB时钟频率,单位Hz */
  uint32_t PCLK1_Frequency;   /* APB1时钟频率,单位Hz */
  uint32_t PCLK2_Frequency;   /* APB2时钟频率,单位Hz */
  uint32_t ADCCLK_Frequency;  /* ADC时钟频率,单位Hz */
} RCC_ClocksTypeDef;

成员说明:

  • SYSCLK_Frequency:系统时钟频率值
  • HCLK_Frequency:AHB总线时钟频率值
  • PCLK1_Frequency:APB1总线时钟频率值
  • PCLK2_Frequency:APB2总线时钟频率值
  • ADCCLK_Frequency:ADC时钟频率值

时钟源配置常量

HSE配置选项

#define RCC_HSE_OFF                      ((uint32_t)0x00000000)  /* 关闭HSE */
#define RCC_HSE_ON                       ((uint32_t)0x00010000)  /* 开启HSE */
#define RCC_HSE_Bypass                   ((uint32_t)0x00040000)  /* HSE旁路模式 */

PLL时钟源配置

#define RCC_PLLSource_HSI_Div2           ((uint32_t)0x00000000)  /* HSI/2作为PLL输入 */
#define RCC_PLLSource_HSE_Div1           ((uint32_t)0x00010000)  /* HSE作为PLL输入 */
#define RCC_PLLSource_HSE_Div2           ((uint32_t)0x00030000)  /* HSE/2作为PLL输入 */

PLL倍频系数

#define RCC_PLLMul_2                     ((uint32_t)0x00000000)  /* PLL 2倍频 */
#define RCC_PLLMul_3                     ((uint32_t)0x00040000)  /* PLL 3倍频 */
#define RCC_PLLMul_4                     ((uint32_t)0x00080000)  /* PLL 4倍频 */
/* ... 其他倍频系数 ... */
#define RCC_PLLMul_16                    ((uint32_t)0x00380000)  /* PLL 16倍频 */

系统时钟源选择

#define RCC_SYSCLKSource_HSI             ((uint32_t)0x00000000)  /* HSI作为系统时钟 */
#define RCC_SYSCLKSource_HSE             ((uint32_t)0x00000001)  /* HSE作为系统时钟 */
#define RCC_SYSCLKSource_PLLCLK          ((uint32_t)0x00000002)  /* PLL作为系统时钟 */

AHB时钟分频系数

#define RCC_SYSCLK_Div1                  ((uint32_t)0x00000000)  /* AHB = SYSCLK */
#define RCC_SYSCLK_Div2                  ((uint32_t)0x00000080)  /* AHB = SYSCLK/2 */
#define RCC_SYSCLK_Div4                  ((uint32_t)0x00000090)  /* AHB = SYSCLK/4 */
#define RCC_SYSCLK_Div8                  ((uint32_t)0x000000A0)  /* AHB = SYSCLK/8 */
#define RCC_SYSCLK_Div16                 ((uint32_t)0x000000B0)  /* AHB = SYSCLK/16 */
#define RCC_SYSCLK_Div64                 ((uint32_t)0x000000C0)  /* AHB = SYSCLK/64 */
#define RCC_SYSCLK_Div128                ((uint32_t)0x000000D0)  /* AHB = SYSCLK/128 */
#define RCC_SYSCLK_Div256                ((uint32_t)0x000000E0)  /* AHB = SYSCLK/256 */
#define RCC_SYSCLK_Div512                ((uint32_t)0x000000F0)  /* AHB = SYSCLK/512 */

APB时钟分频系数

#define RCC_HCLK_Div1                    ((uint32_t)0x00000000)  /* APB = HCLK */
#define RCC_HCLK_Div2                    ((uint32_t)0x00000400)  /* APB = HCLK/2 */
#define RCC_HCLK_Div4                    ((uint32_t)0x00000500)  /* APB = HCLK/4 */
#define RCC_HCLK_Div8                    ((uint32_t)0x00000600)  /* APB = HCLK/8 */
#define RCC_HCLK_Div16                   ((uint32_t)0x00000700)  /* APB = HCLK/16 */

ADC时钟分频系数

#define RCC_PCLK2_Div2                   ((uint32_t)0x00000000)  /* ADCCLK = PCLK2/2 */
#define RCC_PCLK2_Div4                   ((uint32_t)0x00004000)  /* ADCCLK = PCLK2/4 */
#define RCC_PCLK2_Div6                   ((uint32_t)0x00008000)  /* ADCCLK = PCLK2/6 */
#define RCC_PCLK2_Div8                   ((uint32_t)0x0000C000)  /* ADCCLK = PCLK2/8 */

外设时钟控制

AHB外设时钟

#define RCC_AHBPeriph_DMA1               ((uint32_t)0x00000001)  /* DMA1时钟 */
#define RCC_AHBPeriph_DMA2               ((uint32_t)0x00000002)  /* DMA2时钟 */
#define RCC_AHBPeriph_SRAM               ((uint32_t)0x00000004)  /* SRAM时钟 */
#define RCC_AHBPeriph_FLITF              ((uint32_t)0x00000010)  /* FLITF时钟 */
#define RCC_AHBPeriph_CRC                ((uint32_t)0x00000040)  /* CRC时钟 */
#define RCC_AHBPeriph_FSMC               ((uint32_t)0x00000100)  /* FSMC时钟 */
#define RCC_AHBPeriph_SDIO               ((uint32_t)0x00000400)  /* SDIO时钟 */

APB2外设时钟

#define RCC_APB2Periph_AFIO              ((uint32_t)0x00000001)  /* AFIO时钟 */
#define RCC_APB2Periph_GPIOA             ((uint32_t)0x00000004)  /* GPIOA时钟 */
#define RCC_APB2Periph_GPIOB             ((uint32_t)0x00000008)  /* GPIOB时钟 */
#define RCC_APB2Periph_GPIOC             ((uint32_t)0x00000010)  /* GPIOC时钟 */
#define RCC_APB2Periph_GPIOD             ((uint32_t)0x00000020)  /* GPIOD时钟 */
#define RCC_APB2Periph_GPIOE             ((uint32_t)0x00000040)  /* GPIOE时钟 */
#define RCC_APB2Periph_ADC1              ((uint32_t)0x00000200)  /* ADC1时钟 */
#define RCC_APB2Periph_ADC2              ((uint32_t)0x00000400)  /* ADC2时钟 */
#define RCC_APB2Periph_TIM1              ((uint32_t)0x00000800)  /* TIM1时钟 */
#define RCC_APB2Periph_SPI1              ((uint32_t)0x00001000)  /* SPI1时钟 */
#define RCC_APB2Periph_USART1            ((uint32_t)0x00004000)  /* USART1时钟 */

APB1外设时钟

#define RCC_APB1Periph_TIM2              ((uint32_t)0x00000001)  /* TIM2时钟 */
#define RCC_APB1Periph_TIM3              ((uint32_t)0x00000002)  /* TIM3时钟 */
#define RCC_APB1Periph_TIM4              ((uint32_t)0x00000004)  /* TIM4时钟 */
#define RCC_APB1Periph_WWDG              ((uint32_t)0x00000800)  /* WWDG时钟 */
#define RCC_APB1Periph_SPI2              ((uint32_t)0x00004000)  /* SPI2时钟 */
#define RCC_APB1Periph_USART2            ((uint32_t)0x00020000)  /* USART2时钟 */
#define RCC_APB1Periph_USART3            ((uint32_t)0x00040000)  /* USART3时钟 */
#define RCC_APB1Periph_I2C1              ((uint32_t)0x00200000)  /* I2C1时钟 */
#define RCC_APB1Periph_I2C2              ((uint32_t)0x00400000)  /* I2C2时钟 */
#define RCC_APB1Periph_PWR               ((uint32_t)0x10000000)  /* PWR时钟 */

标准库函数详解

1. RCC_DeInit

/**
 * @brief  将 RCC 恢复为复位默认状态并切回 HSI 作 SYSCLK,用于时钟树重配或故障恢复起点
 * @param
 * @retval
 * @example
 *     RCC_DeInit();
 */
void RCC_DeInit(void);

功能说明:

  • 关闭 HSE/PLL 等,系统暂以 8MHz HSI 运行
  • 典型 SystemInit 第一步,再按目标频率重配
  • 不会关闭已使能的外设时钟门控位需后续重新配置

2. RCC_HSEConfig

/**
 * @brief  打开或关闭外部高速晶振 HSE,为 PLL 与高精度 SYSCLK 提供稳定基准
 * @param  RCC_HSE: 指定HSE的新状态
 * @retval
 * @example
 *     RCC_HSEConfig(RCC_HSE_ON);
 */
void RCC_HSEConfig(uint32_t RCC_HSE);

功能说明:

  • 常见 8MHz 晶振,须配合负载电容与 RCC_WaitForHSEStartUp
  • RCC_HSE_Bypass 用于外部时钟源直接输入
  • 关闭 HSE 前须确保 SYSCLK 不依赖 HSE/PLL

3. RCC_WaitForHSEStartUp

/**
 * @brief  阻塞等待 HSE 起振就绪,避免在晶振未稳定时切换 PLL 或 SYSCLK 导致跑飞
 * @param
 * @retval HSE启动状态,SUCCESS或ERROR
 * @example
 *     if(RCC_WaitForHSEStartUp() == SUCCESS)
 *     {
 *         // HSE启动成功
 *     }
 */
ErrorStatus RCC_WaitForHSEStartUp(void);

功能说明:

  • 返回 SUCCESS 表示 HSE 稳定,可配置 PLL
  • 超时返回 ERROR,需检查硬件或改用 HSI
  • 也可轮询 RCC_FLAG_HSERDY 配合超时逻辑

4. RCC_AdjustHSICalibrationValue

/**
 * @brief  微调 HSI 振荡校准值,补偿温度/电压漂移,提高无晶振场景下 UART 等时序精度
 * @param  HSICalibrationValue: 指定校准微调值
 * @retval
 * @example
 *     RCC_AdjustHSICalibrationValue(0x10);
 */
void RCC_AdjustHSICalibrationValue(uint8_t HSICalibrationValue);

功能说明:

  • 写入 RCC_CR 校准字段,出厂默认通常可用
  • 仅在使用 HSI 作 SYSCLK 或 PLL 源时有意义
  • 极端精度需求仍建议 HSE

5. RCC_HSICmd

/**
 * @brief  控制内部 8MHz HSI 振荡器开关,无外部晶振时的默认时钟源或 PLL 备选输入
 * @param  NewState: HSI的新状态,可以是ENABLE或DISABLE
 * @retval
 * @example
 *     RCC_HSICmd(ENABLE);
 */
void RCC_HSICmd(FunctionalState NewState);

功能说明:

  • 复位后 HSI 默认开启;作 SYSCLK 时可关 HSE 省电
  • DISABLE 前确认 SYSCLK/PLL 不依赖 HSI
  • 启动比 HSE 快,适合快速唤醒

6. RCC_PLLConfig

/**
 * @brief  选择 PLL 输入源与倍频系数,将 HSE/HSI 倍频到目标 SYSCLK(如 72MHz)
 * @param  RCC_PLLSource: 指定PLL入口时钟源
 * @param  RCC_PLLMul: 指定PLL倍频系数
 * @retval
 * @example
 *     RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);
 */
void RCC_PLLConfig(uint32_t RCC_PLLSource, uint32_t RCC_PLLMul);

功能说明:

  • 须在 PLL 关闭时修改;HSE 8MHz ×9 常见得 72MHz
  • HSE_Div2 等分频用于满足 PLL 输入频率范围
  • FLASH_SetLatency 匹配更高 SYSCLK

7. RCC_PLLCmd

/**
 * @brief  启动或关闭 PLL,使能后需等待就绪再切换 SYSCLK 到 PLLCLK
 * @param  NewState: PLL的新状态,可以是ENABLE或DISABLE
 * @retval
 * @example
 *     RCC_PLLCmd(ENABLE);
 */
void RCC_PLLCmd(FunctionalState NewState);

功能说明:

  • 使能后轮询 RCC_FLAG_PLLRDY
  • 关闭 PLL 前须先把 SYSCLK 切回 HSI/HSE
  • USB 等外设可能要求 48MHz 来自 PLL 分频

8. RCC_SYSCLKConfig

/**
 * @brief  切换系统主时钟源(HSI/HSE/PLL),决定 CPU 与 AHB 基准频率
 * @param  RCC_SYSCLKSource: 指定用作系统时钟的时钟源
 * @retval
 * @example
 *     RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
 */
void RCC_SYSCLKConfig(uint32_t RCC_SYSCLKSource);

功能说明:

  • 切换后须等 RCC_GetSYSCLKSource 反映新源
  • 升频前先提 Flash 等待周期,降频可后调
  • 动态切换可用于低功耗与高性能权衡

9. RCC_GetSYSCLKSource

/**
 * @brief  查询当前 SYSCLK 实际选用的时钟源,用于确认切换完成或诊断时钟配置
 * @param
 * @retval 系统时钟源
 * @example
 *     uint8_t clockSource = RCC_GetSYSCLKSource();
 */
uint8_t RCC_GetSYSCLKSource(void);

功能说明:

  • 读 CFGR 的 SWS 位,PLL 就绪时常为 0x08
  • RCC_SYSCLKConfig 后循环检查直至匹配
  • 调试时钟异常时的首要读数

10. RCC_HCLKConfig

/**
 * @brief  设置 AHB 预分频得到 HCLK,同步影响 Cortex 内核与 DMA 等 AHB 外设
 * @param  RCC_SYSCLK: 定义AHB时钟分频器
 * @retval
 * @example
 *     RCC_HCLKConfig(RCC_SYSCLK_Div1);
 */
void RCC_HCLKConfig(uint32_t RCC_SYSCLK);

功能说明:

  • 常用 Div1 使 HCLK=SYSCLK;低功耗可再分频
  • 变更后应重算 SysTick 与各波特率
  • 影响 RCC_GetClocksFreq 输出的 HCLK

11. RCC_PCLK1Config

/**
 * @brief  设置 APB1 低速总线分频,TIM2-7、USART2/3、I2C 等挂在 PCLK1 上
 * @param  RCC_HCLK: 定义APB1时钟分频器
 * @retval
 * @example
 *     RCC_PCLK1Config(RCC_HCLK_Div2);
 */
void RCC_PCLK1Config(uint32_t RCC_HCLK);

功能说明:

  • 72MHz 系统下常见 PCLK1=36MHz(Div2)
  • APB1 定时器在分频非 1 时时钟可能 ×2,须查参考手册
  • 超过 PCLK1 最大频率会导致外设异常

12. RCC_PCLK2Config

/**
 * @brief  设置 APB2 高速总线分频,GPIO、USART1、ADC、TIM1/8 等挂在 PCLK2
 * @param  RCC_HCLK: 定义APB2时钟分频器
 * @retval
 * @example
 *     RCC_PCLK2Config(RCC_HCLK_Div1);
 */
void RCC_PCLK2Config(uint32_t RCC_HCLK);

功能说明:

  • 常用 Div1 使 PCLK2=HCLK=72MHz
  • ADC 时钟由 PCLK2 再分频,与 RCC_ADCCLKConfig 配合
  • 高级定时器时基以 PCLK2 为参考

13. RCC_ITConfig

/**
 * @brief  打开 HSE/PLL/LSE 等就绪中断,避免轮询等待,适合起振时间长的场景
 * @param  RCC_IT: 指定要使能或失能的RCC中断源
 * @param  NewState: 指定RCC中断的新状态
 * @retval
 * @example
 *     RCC_ITConfig(RCC_IT_HSERDY, ENABLE);
 */
void RCC_ITConfig(uint8_t RCC_IT, FunctionalState NewState);

功能说明:

  • 须配置 NVIC 并在 ISR 中 RCC_ClearITPendingBit
  • CSS 故障也会触发相关中断路径
  • 裸机常用轮询标志,RTOS 可用中断唤醒任务

14. RCC_USBCLKConfig

/**
 * @brief  选择 USB 外设 48MHz 时钟来源,USB 功能正常工作的必要配置
 * @param  RCC_USBCLKSource: 指定USB时钟的时钟源
 * @retval
 * @example
 *     RCC_USBCLKConfig(RCC_USBCLKSource_PLLCLK_1Div5);
 */
void RCC_USBCLKConfig(uint32_t RCC_USBCLKSource);

功能说明:

  • 72MHz PLL 时常用 PLL/1.5 得 48MHz
  • 须先使能 PLL 且频率组合合法
  • 仅带 USB 的型号需要此配置

15. RCC_ADCCLKConfig

/**
 * @brief  设置 ADC 专用时钟分频,使 ADCCLK 不超过 14MHz 保证转换精度
 * @param  RCC_PCLK2: 定义ADC时钟分频器
 * @retval
 * @example
 *     RCC_ADCCLKConfig(RCC_PCLK2_Div6);
 */
void RCC_ADCCLKConfig(uint32_t RCC_PCLK2);

功能说明:

  • PCLK2=72MHz 时 Div6 得 12MHz 为常用安全值
  • ADC_Init 与校准前配置
  • 过快 ADCCLK 会增加误差

16. RCC_LSEConfig

/**
 * @brief  控制 32.768kHz 外部低速晶振 LSE,为 RTC 与备份域提供精确时基
 * @param  RCC_LSE: 指定LSE的新状态
 * @retval
 * @example
 *     RCC_LSEConfig(RCC_LSE_ON);
 */
void RCC_LSEConfig(uint8_t RCC_LSE);

功能说明:

  • PWR_BackupAccessCmd 后配置备份域
  • 起振慢,常轮询 RCC_FLAG_LSERDY
  • 支持 Bypass 接外部 32k 方波

17. RCC_LSICmd

/**
 * @brief  控制内部约 40kHz LSI,供独立看门狗 IWDG 与 RTC 备选时钟
 * @param  NewState: LSI的新状态,可以是ENABLE或DISABLE
 * @retval
 * @example
 *     RCC_LSICmd(ENABLE);
 */
void RCC_LSICmd(FunctionalState NewState);

功能说明:

  • IWDG 必须 LSI 或已配置的时钟源
  • 精度低于 LSE,RTC 走时一般优先 LSE
  • 使能后等待 RCC_FLAG_LSIRDY

18. RCC_RTCCLKConfig

/**
 * @brief  选择 RTC 时钟来自 LSE、LSI 或 HSE 分频,决定日历走时精度与功耗
 * @param  RCC_RTCCLKSource: 指定RTC时钟的时钟源
 * @retval
 * @example
 *     RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);
 */
void RCC_RTCCLKConfig(uint32_t RCC_RTCCLKSource);

功能说明:

  • 须在 RCC_RTCCLKCmd(ENABLE) 前且 RTC 未运行或备份域已复位时配置
  • LSE 适合实时时钟;LSI 免晶振
  • 切换源通常需复位备份域

19. RCC_RTCCLKCmd

/**
 * @brief  向 RTC 模块提供时钟,使能后方能访问 RTC 寄存器与日历功能
 * @param  NewState: RTC时钟的新状态,可以是ENABLE或DISABLE
 * @retval
 * @example
 *     RCC_RTCCLKCmd(ENABLE);
 */
void RCC_RTCCLKCmd(FunctionalState NewState);

功能说明:

  • 须先 RCC_APB1Periph_PWR/BKP 与备份访问
  • RCC_RTCCLKConfig 顺序:先选源再使能
  • DISABLE 会停止 RTC 计数

20. RCC_GetClocksFreq

/**
 * @brief  根据当前 RCC 配置计算 SYSCLK/HCLK/PCLK/ADCCLK 实际频率,供波特率与延时换算
 * @param  RCC_Clocks: 指向RCC_ClocksTypeDef结构的指针
 * @retval
 * @example
 *     RCC_ClocksTypeDef RCC_ClockFreq;
 *     RCC_GetClocksFreq(&RCC_ClockFreq);
 */
void RCC_GetClocksFreq(RCC_ClocksTypeDef* RCC_Clocks);

功能说明:

  • 读寄存器动态计算,改时钟后应重新调用
  • USART、SysTick、定时器 ARR 依赖此结果
  • 不测量芯片,仅按配置推导

21. RCC_AHBPeriphClockCmd

/**
 * @brief  开关 AHB 外设时钟门控,使用 DMA、SRAM 控制器等前必须使能
 * @param  RCC_AHBPeriph: 指定要设置时钟的AHB外设
 * @param  NewState: 指定外设时钟的新状态
 * @retval
 * @example
 *     RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
 */
void RCC_AHBPeriphClockCmd(uint32_t RCC_AHBPeriph, FunctionalState NewState);

功能说明:

  • 复位默认关闭,漏开时钟则寄存器访问无效
  • 多位或可同时开 DMA1/2
  • 低功耗不用时可 DISABLE 降功耗

22. RCC_APB2PeriphClockCmd

/**
 * @brief  开关 APB2 高速外设时钟,GPIO/AFIO/ADC/USART1 等初始化前必调
 * @param  RCC_APB2Periph: 指定要设置时钟的APB2外设
 * @param  NewState: 指定外设时钟的新状态
 * @retval
 * @example
 *     RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
 */
void RCC_APB2PeriphClockCmd(uint32_t RCC_APB2Periph, FunctionalState NewState);

功能说明:

  • 最常用的时钟使能函数之一
  • GPIO 与 AFIO 常一起 ENABLE
  • 可位或一次开启多个 APB2 外设

23. RCC_APB1PeriphClockCmd

/**
 * @brief  开关 APB1 低速外设时钟,TIM2-7、I2C、USART2/3、PWR 等使用前使能
 * @param  RCC_APB1Periph: 指定要设置时钟的APB1外设
 * @param  NewState: 指定外设时钟的新状态
 * @retval
 * @example
 *     RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
 */
void RCC_APB1PeriphClockCmd(uint32_t RCC_APB1Periph, FunctionalState NewState);

功能说明:

  • APB1 最大 36MHz(72MHz 系统典型)
  • 定时器波特率计算注意 PCLK1 与倍频规则
  • 未用时 DISABLE 可省电

24. RCC_APB2PeriphResetCmd

/**
 * @brief  脉冲复位 APB2 外设,解决外设卡死或重新初始化前清寄存器状态
 * @param  RCC_APB2Periph: 指定要复位的APB2外设
 * @param  NewState: 指定外设复位状态
 * @retval
 * @example
 *     RCC_APB2PeriphResetCmd(RCC_APB2Periph_GPIOA, ENABLE);
 */
void RCC_APB2PeriphResetCmd(uint32_t RCC_APB2Periph, FunctionalState NewState);

功能说明:

  • 典型序列:ENABLE 复位 → DISABLE 释放 → 再 Init
  • 复位期间外设寄存器恢复默认
  • 不要长时间保持 ENABLE

25. RCC_APB1PeriphResetCmd

/**
 * @brief  脉冲复位 APB1 外设,用于 TIM/I2C 等软复位而不影响整个系统
 * @param  RCC_APB1Periph: 指定要复位的APB1外设
 * @param  NewState: 指定外设复位状态
 * @retval
 * @example
 *     RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM2, ENABLE);
 */
void RCC_APB1PeriphResetCmd(uint32_t RCC_APB1Periph, FunctionalState NewState);

功能说明:

  • xxx_DeInit 类似但由 RCC 总线复位
  • 释放复位后须重新 xxx_Init
  • 可单独复位某一 APB1 模块

26. RCC_BackupResetCmd

/**
 * @brief  复位备份域(RTC、BKP 寄存器等),更换 RTC 时钟源或清除备份数据时使用
 * @param  NewState: 备份域复位状态,可以是ENABLE或DISABLE
 * @retval
 * @example
 *     RCC_BackupResetCmd(ENABLE);
 */
void RCC_BackupResetCmd(FunctionalState NewState);

功能说明:

  • PWR_BackupAccessCmd(ENABLE) 才有效
  • 短脉冲 ENABLE 后 DISABLE
  • 会清除 BKP 数据与 RTC 配置

27. RCC_ClockSecuritySystemCmd

/**
 * @brief  使能时钟安全系统 CSS,HSE 失效时自动切 HSI 并触发 NMI,提高运行可靠性
 * @param  NewState: 时钟安全系统状态,可以是ENABLE或DISABLE
 * @retval
 * @example
 *     RCC_ClockSecuritySystemCmd(ENABLE);
 */
void RCC_ClockSecuritySystemCmd(FunctionalState NewState);

功能说明:

  • 依赖 HSE 的应用建议生产环境开启
  • 故障时进 NMI_Handler,须编写恢复逻辑
  • RCC_ITConfig(RCC_IT_CSS, ...) 可配合

28. RCC_MCOConfig

/**
 * @brief  将内部时钟输出到 MCO 引脚(如 PA8),便于示波器测量或同步外部电路
 * @param  RCC_MCO: 指定要输出的时钟源
 * @retval
 * @example
 *     RCC_MCOConfig(RCC_MCO_SYSCLK);
 */
void RCC_MCOConfig(uint8_t RCC_MCO);

功能说明:

  • 须将 MCO 引脚配为复用推挽输出
  • 输出频率过高时注意 PCB 负载
  • 调试 PLL 是否锁定时常用 SYSCLK/2

29. RCC_GetFlagStatus

/**
 * @brief  查询 HSE/PLL/LSE 就绪或复位原因等 RCC 标志,用于起振等待与上电诊断
 * @param  RCC_FLAG: 指定要检查的标志
 * @retval 标志状态,SET或RESET
 * @example
 *     if(RCC_GetFlagStatus(RCC_FLAG_HSERDY) == SET)
 *     {
 *         // HSE就绪
 *     }
 */
FlagStatus RCC_GetFlagStatus(uint8_t RCC_FLAG);

功能说明:

  • 常用 HSERDY、PLLRDY、LSERDY 轮询
  • 复位标志可判断 POR/软件复位等来源
  • 比固定 delay 更可靠

30. RCC_ClearFlag

/**
 * @brief  清除 RCC 复位标志位,读取复位原因后清零以便下次判断
 * @param
 * @retval
 * @example
 *     RCC_ClearFlag();
 */
void RCC_ClearFlag(void);

功能说明:

  • 清除 PIN/POR/SFTRST 等累计标志
  • 一般在记录复位原因后调用一次
  • 不影响当前时钟配置

31. RCC_GetITStatus

/**
 * @brief  判断 RCC 中断(如 HSE 就绪)是否 pending,用于中断方式等待时钟稳定
 * @param  RCC_IT: 指定要检查的RCC中断源
 * @retval 中断状态,SET或RESET
 * @example
 *     if(RCC_GetITStatus(RCC_IT_HSERDY) == SET)
 *     {
 *         // HSE就绪中断
 *     }
 */
ITStatus RCC_GetITStatus(uint8_t RCC_IT);

功能说明:

  • 须已 RCC_ITConfig 并使能 NVIC
  • ISR 内先查再清除 pending
  • 与标志位查询互补

32. RCC_ClearITPendingBit

/**
 * @brief  清除 RCC 中断 pending,避免重复进入 ISR 或影响后续就绪检测
 * @param  RCC_IT: 指定要清除的RCC中断待处理位
 * @retval
 * @example
 *     RCC_ClearITPendingBit(RCC_IT_HSERDY);
 */
void RCC_ClearITPendingBit(uint8_t RCC_IT);

功能说明:

  • 通常在 RCC 中断服务函数末尾调用
  • 清除后相应 IT 状态查询为 RESET
  • 未清除可能导致连续中断

使用示例

系统时钟配置示例(使用HSE + PLL到72MHz)

void SystemClock_Config(void)
{
    ErrorStatus HSEStartUpStatus;
    
    /* RCC系统复位 */
    RCC_DeInit();
    
    /* 使能HSE */
    RCC_HSEConfig(RCC_HSE_ON);
    
    /* 等待HSE就绪 */
    HSEStartUpStatus = RCC_WaitForHSEStartUp();
    
    if(HSEStartUpStatus == SUCCESS)
    {
        /* 使能Prefetch Buffer */
        FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);
        
        /* Flash延迟设置 */
        FLASH_SetLatency(FLASH_Latency_2);
        
        /* HCLK = SYSCLK */
        RCC_HCLKConfig(RCC_SYSCLK_Div1);
        
        /* PCLK2 = HCLK */
        RCC_PCLK2Config(RCC_HCLK_Div1);
        
        /* PCLK1 = HCLK/2 */
        RCC_PCLK1Config(RCC_HCLK_Div2);
        
        /* ADCCLK = PCLK2/6 */
        RCC_ADCCLKConfig(RCC_PCLK2_Div6);
        
        /* 配置PLL: PLLCLK = HSE * 9 = 72 MHz */
        RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);
        
        /* 使能PLL */
        RCC_PLLCmd(ENABLE);
        
        /* 等待PLL就绪 */
        while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);
        
        /* 选择PLL作为系统时钟源 */
        RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
        
        /* 等待PLL被用作系统时钟源 */
        while(RCC_GetSYSCLKSource() != 0x08);
    }
}

外设时钟使能示例

void PeriphClock_Config(void)
{
    /* 使能GPIO时钟 */
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | 
                          RCC_APB2Periph_GPIOB | 
                          RCC_APB2Periph_GPIOC, ENABLE);
    
    /* 使能USART1时钟 */
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
    
    /* 使能TIM2时钟 */
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
    
    /* 使能I2C1时钟 */
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);
    
    /* 使能ADC1时钟 */
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
    
    /* 使能DMA1时钟 */
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
}

获取系统时钟频率示例

void GetClockFrequencies(void)
{
    RCC_ClocksTypeDef RCC_ClockFreq;
    
    /* 获取系统时钟频率 */
    RCC_GetClocksFreq(&RCC_ClockFreq);
    
    /* 打印时钟频率信息 */
    printf("SYSCLK频率: %d Hz\n", RCC_ClockFreq.SYSCLK_Frequency);
    printf("HCLK频率: %d Hz\n", RCC_ClockFreq.HCLK_Frequency);
    printf("PCLK1频率: %d Hz\n", RCC_ClockFreq.PCLK1_Frequency);
    printf("PCLK2频率: %d Hz\n", RCC_ClockFreq.PCLK2_Frequency);
    printf("ADCCLK频率: %d Hz\n", RCC_ClockFreq.ADCCLK_Frequency);
}

RTC时钟配置示例

void RTC_Clock_Config(void)
{
    /* 使能PWR和BKP时钟 */
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);
    
    /* 允许访问BKP域 */
    PWR_BackupAccessCmd(ENABLE);
    
    /* 复位BKP域 */
    RCC_BackupResetCmd(ENABLE);
    RCC_BackupResetCmd(DISABLE);
    
    /* 使能LSE */
    RCC_LSEConfig(RCC_LSE_ON);
    
    /* 等待LSE就绪 */
    while(RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET);
    
    /* 选择LSE作为RTC时钟源 */
    RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);
    
    /* 使能RTC时钟 */
    RCC_RTCCLKCmd(ENABLE);
}

注意事项

  1. 时钟配置顺序:配置系统时钟时要按照正确的顺序进行,先配置时钟源,再配置分频器,最后切换系统时钟

  2. Flash等待周期:当系统时钟超过24MHz时,必须配置Flash等待周期

  3. 外设时钟:使用外设前必须先使能相应的时钟

  4. 时钟安全系统:建议启用CSS功能以提高系统可靠性

  5. 低功耗考虑:不使用的外设应关闭其时钟以降低功耗

  6. PLL配置:PLL使能后不能修改其配置,需要先失能PLL

  7. 备份域:访问备份域寄存器前需要使能PWR时钟并允许访问

总结

STM32F10x RCC标准库提供了完整的时钟和复位控制功能,通过合理配置这些函数,可以实现灵活的时钟管理和外设控制。掌握RCC的使用对于STM32系统优化和功耗管理至关重要。正确的时钟配置是整个系统稳定运行的基础。