适用于 STM32F4 系列,其他系列原理相同
| 时钟源 | 频率 | 精度 | 启动时间 | 主要用途 | 推荐 |
|---|---|---|---|---|---|
| HSI 内部高速 |
16 MHz | ±1% 温漂大 | 快 (us级) | 系统启动默认时钟 | ○ |
| HSE 外部高速 |
4-26 MHz | ppm级 | 慢 (ms级) | 推荐正式产品,USB、以太网 | ★ |
| LSI 内部低速 |
~32 KHz | ±5% | 快 | 独立看门狗 (IWDG) | ○ |
| LSE 外部低速 |
32.768 KHz | ppm级 | 慢 (秒级) | RTC 实时时钟 | ★ |
为什么 LSE 是 32.768KHz? 因为 32768 = 215,可以通过 15 次二分频精确得到 1Hz!
PLL = Phase-Locked Loop = 锁相环
作用:将低频时钟"倍频"成高频时钟。就像变压器变换电压,PLL 变换频率。
| 参数 | 范围 | 推荐值 | 说明 |
|---|---|---|---|
| M | 2~63 | 使 HSE/M = 1~2MHz | VCO 输入频率 |
| N | 50~432 | 根据目标计算 | VCO 倍频系数 |
| P | 2, 4, 6, 8 | 通常用 2 | 主输出分频 |
| Q | 2~15 | 使输出 = 48MHz | USB / SDIO |
| HSE | M | N | P | Q | SYSCLK | 说明 |
|---|---|---|---|---|---|---|
| 8MHz | 8 | 336 | 2 | 7 | 168MHz | ★ USB 友好 |
| 8MHz | 8 | 360 | 2 | 8 | 180MHz | 最高性能 |
| 25MHz | 25 | 336 | 2 | 7 | 168MHz | ★ 推荐配置 |
| 25MHz | 25 | 360 | 2 | 8 | 180MHz | 最高性能 |
功耗、外设能力限制、时序要求。
| HCLK (MHz) | 等待周期 |
|---|---|
| 0 - 30 | 0 WS |
| 30 - 60 | 1 WS |
| 60 - 90 | 2 WS |
| 90 - 120 | 3 WS |
| 120 - 150 | 4 WS |
| 150 - 180 | 5 WS |
void SystemClock_Config(void)
{
// 1. HSE
RCC->CR |= RCC_CR_HSEON;
uint32_t timeout = 0xFFFF;
while (!(RCC->CR & RCC_CR_HSERDY) && timeout--);
if (timeout == 0) { Error_Handler(); }
// 2. PLL: HSE/25 * 360 / 2 = 180MHz
RCC->PLLCFGR = (25U << RCC_PLLCFGR_PLLM_Pos)
| (360U << RCC_PLLCFGR_PLLN_Pos)
| (0U << RCC_PLLCFGR_PLLP_Pos)
| (RCC_PLLCFGR_PLLSRC_HSE)
| (8U << RCC_PLLCFGR_PLLQ_Pos);
// 3. Enable PLL
RCC->CR |= RCC_CR_PLLON;
while (!(RCC->CR & RCC_CR_PLLRDY));
// 4. Flash: 5WS for 180MHz
FLASH->ACR = FLASH_ACR_LATENCY_5WS
| FLASH_ACR_PRFTEN
| FLASH_ACR_ICEN
| FLASH_ACR_DCEN;
// 5. Bus clocks
RCC->CFGR = (RCC->CFGR & ~(RCC_CFGR_HPRE | RCC_CFGR_PPRE1 | RCC_CFGR_PPRE2))
| RCC_CFGR_HPRE_DIV1
| RCC_CFGR_PPRE1_DIV4
| RCC_CFGR_PPRE2_DIV2;
// 6. Switch to PLL
RCC->CFGR |= RCC_CFGR_SW_PLL;
while ((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_PLL);
SystemCoreClock = 180000000U;
}
| # | 错误 | 症状 | 原因 | 解决 |
|---|---|---|---|---|
| 1 | HSE 启动超时 | 卡在 HSERDY | 晶振虚焊/损坏 | 示波器测 OSC_IN/OUT |
| 2 | 切换PLL后死机 | 程序跑飞 | Flash等待周期不足 | 先配 FLASH->ACR |
| 3 | USB 无法枚举 | PC不识别 | 48MHz不精确 | HSE + N=336 Q=7 |
| 4 | 外设不工作 | GPIO/UART无反应 | 忘记使能时钟 | RCC->AHB1ENR |
| 5 | 定时器频率错 | 中断周期不对 | 没考虑x2规则 | APB1 -> TIM=90M |
已知 HSE = 8MHz,目标 SYSCLK = 168MHz
问题:计算 M, N, P 的值;USB 需要 48MHz,Q = ?
M = 8, N = 336, P = 2, Q = 7
计算过程:8 / 8 * 336 / 2 = 168 MHz,VCO = 336 MHz,336 / 7 = 48 MHz (USB)
场景:HSI(16MHz) 正常,切到 HSE + PLL(180MHz) 后死机。原因?
Flash 等待周期不足。
180MHz 需要 5WS,但切换前未配置 FLASH->ACR。CPU 从 Flash 取指令来不及,导致程序跑飞。
修复:在切换系统时钟之前,先设置 FLASH->ACR = FLASH_ACR_LATENCY_5WS | ...
请在 STM32CubeMX 中配置:SYSCLK = 100MHz,USB = 48MHz。
以 HSE = 25MHz 为例:M = 25, N = 200, P = 2 -> SYSCLK = 100MHz
VCO = 200MHz,Q = 200/48 不整除。换一种:N = 192, P = 2 -> 96MHz (不满足)
更优方案:M = 25, N = 336, P = 4 = 84MHz... 实际操作中,CubeMX 会自动求解最优组合,建议利用其 Clock Configuration 页面的自动解算功能。
| Bit | 名称 | 说明 |
|---|---|---|
| 25 | PLLRDY | PLL 就绪标志 |
| 24 | PLLON | PLL 使能 |
| 17 | HSERDY | HSE 就绪标志 |
| 16 | HSEON | HSE 使能 |
| Bit | 名称 | 说明 |
|---|---|---|
| 27:24 | PLLQ | Q 分频 |
| 22 | PLLSRC | PLL 源选择 |
| 17:16 | PLLP | P 分频 |
| 14:6 | PLLN | N 倍频 |
| 5:0 | PLLM | M 分频 |