1. RCC(复位和时钟控制)
RCC(Reset and Clock Control)是 STM32 的时钟系统控制模块,负责管理整个芯片的时钟信号。在使用任何外设之前,必须先使能其时钟。
2. 时钟系统框图解析
时钟源(5 种)
HSI(高速内部时钟)
- 由内部 RC 振荡器产生,默认 8MHz
- 精度较低,适用于对时钟精度要求不高的应用
- 可作为系统时钟源
HSE(高速外部时钟)
- 由外部晶振(石英/陶瓷谐振器或外部时钟)产生,频率范围 4-16MHz
- 可直接作为系统时钟,或经分频后作为 PLL 输入
PLL(锁相环)
- 来源:HSI/2、HSE、HSE/2
- 作用:倍频(×2 ~ ×16)
- 通常作为系统时钟的最终来源
LSE(低速外部时钟)
- 由外部 32.768kHz 石英晶振产生
- 用于 RTC(实时时钟)
LSI(低速内部时钟)
- 由内部 RC 振荡器产生,约 40kHz
- 低功耗,适用于独立看门狗(IWDG)
主要时钟信号
SYSCLK(系统时钟)
- 来源:HSI、HSE、PLLCLK
- 通过 AHB 预分频器(1/2/4/8/16/64/128/256/512)得到 HCLK
- 最高可达 72MHz
AHB 总线时钟(HCLK)
- 供给 AHB 总线、存储器、DMA 等模块
APB1 低速总线时钟
- 最高 36MHz,用于低速外设
APB2 高速总线时钟
- 最高 72MHz,用于高速外设
RTCCLK(实时时钟时钟)
- 来源:HSE/128、LSE、LSI
USBCLK(USB 时钟)
- 来源:PLLCLK 经过 USB 预分频器(÷1 或 ÷1.5)
MCO(时钟输出)
- 通过 PA8 引脚输出,来源可选 SYSCLK、HSI、HSE、PLLCLK/2
3. 时钟安全系统(CSS)
当 HSE 失效时,CSS 可自动切换到 HSI,确保系统继续运行。
4. 时钟控制寄存器(RCC 寄存器)
typedef struct
{
__IO uint32_t CR; // HSI, HSE, CSS, PLL 使能/就绪标志
__IO uint32_t CFGR; // 时钟源选择、分频系数设定
__IO uint32_t CIR; // 时钟中断控制
__IO uint32_t APB2RSTR; // APB2 外设复位
__IO uint32_t APB1RSTR; // APB1 外设复位
__IO uint32_t AHBENR; // AHB 外设时钟使能
__IO uint32_t APB2ENR; // APB2 外设时钟使能
__IO uint32_t APB1ENR; // APB1 外设时钟使能
__IO uint32_t BDCR; // 备份域控制
__IO uint32_t CSR; // 控制状态
} RCC_TypeDef;
5. RCC 库函数
时钟源使能
RCC_LSEConfig();
RCC_HSEConfig();
RCC_HSICmd();
RCC_LSICmd();
RCC_PLLCmd();
时钟源选择
RCC_PLLConfig();
RCC_SYSCLKConfig();
RCC_RTCCLKConfig();
分频系数选择
RCC_HCLKConfig();
RCC_PCLK1Config();
RCC_PCLK2Config();
外设时钟使能
RCC_APB1PeriphClockCmd(); // APB1 外设
RCC_APB2PeriphClockCmd(); // APB2 外设
RCC_AHBPeriphClockCmd(); // AHB 外设
时钟状态获取
RCC_GetClocksFreq();
RCC_GetSYSCLKSource();
RCC_GetFlagStatus();
RCC 中断控制
RCC_ITConfig();
RCC_GetITStatus();
RCC_ClearITPendingBit();
6. SystemInit 初始化时钟系统
SystemInit 函数定义在 system_stm32f10x.c
,用于复位和初始化时钟。
void SystemInit(void)
{
RCC->CR |= (uint32_t)0x00000001; // 使能 HSI
RCC->CFGR &= (uint32_t)0xF8FF0000; // 复位 SW、HPRE、PPRE1、PPRE2
RCC->CR &= (uint32_t)0xFEF6FFFF; // 关闭 HSE、CSS、PLL
RCC->CR &= (uint32_t)0xFFFBFFFF; // 关闭 HSEBYP
RCC->CFGR &= (uint32_t)0xFF80FFFF; // 复位 PLL 相关位
/* 禁用所有 RCC 相关中断 */
RCC->CIR = 0x009F0000;
/* 设置系统时钟 */
SetSysClock();
/* 设置向量表偏移地址 */
SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET;
}
7. SysTick(系统滴答定时器)
SysTick 是 ARM Cortex-M 内核自带的 24 位定时器,主要用于操作系统心跳时钟或延时。
SysTick 相关寄存器
CTRL(控制和状态)
TICKINT
:是否启用中断COUNTFLAG
:计数标志
LOAD(重装载值)
- 设定倒计数初值
VAL(当前计数值)
CALIB(校准值)
SysTick 配置
void SysTick_CLKSourceConfig(uint32_t SysTick_CLKSource)
{
// SysTick 时钟源选择
if (SysTick_CLKSource == SysTick_CLKSource_HCLK)
SysTick->CTRL |= SysTick_CTRL_CLKSOURCE_Msk;
else
SysTick->CTRL &= ~SysTick_CTRL_CLKSOURCE_Msk;
}
SysTick_CLKSource_HCLK
(内部 72MHz 时钟)SysTick_CLKSource_HCLK_Div8
(外部 HCLK/8,即 9MHz)