【STM32】RCC系统时钟
目录
- 一、什么是系统时钟
- 二、RCC系统时钟和系统时钟的关系
- 三、RCC介绍
- RCC的作用
- RCC的主要时钟源
- 相关寄存器
- 四、RCC复位和系统复位
- RCC复位
- 系统复位
- 1. 重新上电
- 2. 硬件复位
- 3. 独立看门狗(IWDG)复位
- 4. 软件复位
- 五、时钟
- 时钟树
- 六、配置时钟
- 示例代码
一、什么是系统时钟
系统时钟是MCU所有外设和内核运行的时钟源,决定了CPU、总线和外设的工作频率。STM32通常支持多时钟源,并通过时钟树配置分频/倍频。
二、RCC系统时钟和系统时钟的关系
RCC系统时钟是配置层,负责时钟源管理和分配。
系统时钟-SYSCLK是执行层,直接影响CPU性能和外设时序。
(RCC)Reset and Clock Control,复位和时钟控制, 负责管理整个芯片的时钟和复位
时钟系统相当于芯片的心跳, 负责整个系统的稳定动作和节奏
三、RCC介绍
RCC的作用
- 系统时钟配置(HSE、HSI、PLL等时钟源选择)
- 外设时钟管理(为 GPIO、USART、SPI、I2C、ADC 等模块提供时钟)
- 复位控制(对外设或整个系统进行复位)
- 低功耗管理(控制低功耗模式下的时钟)
RCC的主要时钟源
- HSE(High-Speed External):外部高速晶振(通常 8MHz、25MHz)
- HSI(High-Speed Internal):内部高速时钟(如 STM32F4 默认 16MHz)
- LSE(Low-Speed External):外部低速晶振(通常 32.768kHz,用于 RTC)
- LSI(Low-Speed Internal):内部低速时钟(约 32kHz)
- PLL(Phase-Locked Loop):锁相环,用于倍频,提高主频
相关寄存器
寄存器 | 作用 |
---|---|
RCC_CR | 控制时钟源(HSI、HSE、PLL) |
RCC_CFGR | 选择系统时钟、预分频系数 |
RCC_AHBENR | 使能 AHB 总线外设时钟 |
RCC_APB1ENR | 使能 APB1 总线外设时钟 |
RCC_APB2ENR | 使能 APB2 总线外设时钟 |
RCC_BDCR | 低功耗相关,如 LSE 控制 |
RCC_CSR | 复位标志等状态控制 |
四、RCC复位和系统复位
RCC复位
- 作用范围:主要针对时钟系统(如HSE/HSI/PLL配置异常、时钟源切换失败等),属于时钟树相关的局部复位。
- 触发条件:
- 时钟就绪超时(如HSE启动失败)。
- PLL解锁(PLL配置错误或失锁)。
- 时钟安全系统(CSS)检测到外部时钟故障。
- 影响:通常不会导致整个系统复位,但可能引发时钟中断(如CSS中断),需软件干预恢复。
系统复位
- 作用范围:全局复位(CPU、外设、内存等全部重置)
如:- 上电复位(POR)。
- 看门狗复位(IWDG/WWDG)。
- 软件复位(NVIC_SystemReset())。
- 硬件引脚复位(NRST引脚低电平)。
- 触发条件:更广泛,包含所有导致系统重启的硬件/软件事件。
对于嵌入式芯片来说,
系统复位
就是指重启
重启之后, 所有寄存器会恢复初始状态(初始值查阅手册) , 软件会重新从头运行
1. 重新上电
开关机
2. 硬件复位
STM32
有一个专门的NRST
引脚, 作为复位引脚, 上电状态下, NRST
拉低 (电压低于0.8V, 时间持续100ns) 会导致系统硬件复位
典型电路
3. 独立看门狗(IWDG)复位
- STM32 内部的 独立看门狗(IWDG) 可用于系统异常时自动复位。
- 如果开启了看门狗功能, 需要软件定期喂狗,否则 MCU 认为程序失控,自动复位
4. 软件复位
执行 NVIC_SystemReset();
函数复位, 这是ARM内核提供的一个函数, 实际是控制一个中断寄存器来复位
相比硬件复位, 软件复位会重新回到
main()
执行, 而不是bootloader
, 另外不是所有的寄存器都复位
五、时钟
时钟树
这个直接看懵
一张图解决
只有这三种时钟源可被用来驱动系统时钟(SYSCLK):
● HSI振荡器时钟
● HSE振荡器时钟
● PLL时钟
而其他时钟源(如LSI、LSE)通常不被直接用作SYSCLK,主要原因包括频率范围、稳定性、精度以及系统设计需求。
分频关系:
-
SYSCLK 最大72M
-
AHB时钟HCLK = SYSCLK / AHB预分频器, 最大72M
-
APB1时钟PCLK1 = SYSCLK / APB1预分频器, 最大36M
-
APB2时钟PCLK2 = SYSCLK / APB2预分频器, 最大72M
六、配置时钟
-
初始状态使用
HSI
作为时钟源, 为8M -
我们使用的工程使用的是ARM提供的默认初始代码, 将其设置为72M(HSE+PLL)
-
设置和调整时钟使用
RCC
相关函数, 调整RCC
相关寄存器 -
RCC
库中重要的标准库函数函数 作用 RCC_DeInit 将外设 RCC 寄存器重设为缺省值 RCC_HSEConfig 设置外部高速晶振(HSE) RCC_WaitForHSEStartUp 等待 HSE 起振 RCC_HSICmd 使能或者失能内部高速晶振(HSI) RCC_PLLConfig 设置 PLL 时钟源及倍频系数 RCC_PLLCmd 使能或者失能 PLL RCC_SYSCLKConfig 设置系统时钟(SYSCLK) RCC_HCLKConfig 设置 AHB 时钟(HCLK) RCC_PCLK1Config 设置低速 AHB 时钟(PCLK1) RCC_PCLK2Config 设置高速 AHB 时钟(PCLK2) RCC_AHBPeriphClockCmd 使能或者失能 AHB 外设时钟 RCC_APB2PeriphClockCmd 使能或者失能 APB2 外设时钟 RCC_APB1PeriphClockCmd 使能或者失能 APB1 外设时钟 RCC_APB2PeriphResetCmd 强制或者释放高速 APB(APB2)外设复位 RCC_APB1PeriphResetCmd 强制或者释放低速 APB(APB1)外设复位 RCC_GetFlagStatus 检查指定的 RCC 标志位设置与否 RCC_ClearFlag 清除 RCC 的复位标志位 -
我们想要设置的方案, 比如: 使用外部8M高速晶振, 不分频后, 经过锁相环PLL进行9倍频, 形成系统时钟
示例代码
#include "drv_rcc.h"
void MYRCC_Init(void)
{
// 配置为新时钟之前,将旧时钟初始化为缺省值
RCC_DeInit(); //将RCC(复位和时钟控制)寄存器恢复为默认状态(时钟源切换为内部HSI,其他配置清零)。
// 1. 使能外部晶振(HSE)
RCC_HSEConfig(RCC_HSE_ON);
// 等待HSE稳定
if (ERROR == RCC_WaitForHSEStartUp())
{
// 如果配置出错,直接进入死循环
while (1)
{
}
}
// 2. 配置PLL(HSE作为输入,倍频到72MHz)
RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9); // 8MHz * 9 = 72MHz
// 3. 使能PLL并等待就绪
RCC_PLLCmd(ENABLE);
// 等待PLL稳定
// 没有单独的函数,只能自己手动写
while (SET != RCC_GetFlagStatus(RCC_FLAG_PLLRDY))
{
}
// 4. 设置系统时钟源为PLL
RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
// 等待sysclk稳定
while (0x08 != RCC_GetSYSCLKSource())
{
}
// 5. 配置APB1和APB2分频(APB1最大36MHz,APB2最大72MHz)
RCC_HCLKConfig(RCC_SYSCLK_Div1); // AHB = 72MHz
RCC_PCLK1Config(RCC_HCLK_Div2); // APB1 = 36MHz
RCC_PCLK2Config(RCC_HCLK_Div1); // APB2 = 72MHz
}