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);
}注意事项
-
时钟配置顺序:配置系统时钟时要按照正确的顺序进行,先配置时钟源,再配置分频器,最后切换系统时钟
-
Flash等待周期:当系统时钟超过24MHz时,必须配置Flash等待周期
-
外设时钟:使用外设前必须先使能相应的时钟
-
时钟安全系统:建议启用CSS功能以提高系统可靠性
-
低功耗考虑:不使用的外设应关闭其时钟以降低功耗
-
PLL配置:PLL使能后不能修改其配置,需要先失能PLL
-
备份域:访问备份域寄存器前需要使能PWR时钟并允许访问
总结
STM32F10x RCC标准库提供了完整的时钟和复位控制功能,通过合理配置这些函数,可以实现灵活的时钟管理和外设控制。掌握RCC的使用对于STM32系统优化和功耗管理至关重要。正确的时钟配置是整个系统稳定运行的基础。