初学STM32系统时钟设置

资料来自正点原子

在学习江科大教程示例的时候默认系统时钟是72MHZ,但是这个系统时钟是怎么过来的呢,通过时钟树以及相关的资料的学习可知,系统时钟它可以是内部RC时钟HSI 8MHZ通过锁相环倍频而来,也可以是外部晶振4-16MHZ通过锁相环倍频而来。但是我们在写程序的过程中好像并没有配置过程。

通过deepseek得知:

  • STM32 芯片上电后,首先执行启动文件 (如startup_stm32f10x.s),该文件会调用 SystemInit() 函数。
  • SystemInit() 是标准库(如 STM32F10x Standard Peripheral Library)提供的函数,其默认配置会将外部 8MHz 晶振通过 PLL 倍频到 72MHz。

但如果我们不想用外部时钟做为系统时钟的来源,而是内部时钟作为系统时钟该怎么设置呢?比如用内部时钟8MHZ设置输出36MHZ的系统时钟

配置函数

复制代码
#include "stm32f10x.h"
#include "stm32f10x_rcc.h"

void SetSysClockToHSI_36MHz(void) {
   
    
    // 1. 将 RCC 配置复位到默认状态
    RCC_DeInit();
    
    // 2. 使能 HSI(内部 8MHz 时钟)
    RCC_HSICmd(ENABLE);
    
    // 3. 等待 HSI 稳定
    while (RCC_GetFlagStatus(RCC_FLAG_HSIRDY) == RESET);
    
    // 4. 配置 PLL:HSI/2 = 4MHz -> PLL倍频9倍 -> 36MHz
    RCC_PLLConfig(RCC_PLLSource_HSI_Div2, RCC_PLLMul_9);
    
    // 5. 使能 PLL
    RCC_PLLCmd(ENABLE);
    
    // 6. 等待 PLL 就绪
    while (RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);
    
    // 7. 配置总线分频系数(可选)
    RCC_HCLKConfig(RCC_SYSCLK_Div1);    // AHB 时钟 = 36MHz
    RCC_PCLK1Config(RCC_HCLK_Div2);    // APB1时钟 = 18MHz(最大36MHz)
    RCC_PCLK2Config(RCC_HCLK_Div1);     // APB2时钟 = 36MHz
    
    // 8. 切换系统时钟到 PLL
    RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
    
    // 9. 等待系统时钟切换成功
    while (RCC_GetSYSCLKSource() != 0x08); // 0x08表示PLL作为系统时钟
}

//int main(void) {
//    // 调用自定义时钟配置函数
//    SetSysClockToHSI_36MHz();
//    
//    // 后续初始化代码(开启外设时钟、GPIO初始化等)
//    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
//    // ... 其他初始化代码
//    
//    while(1) {
//        // 主循环代码
//    }
//}

该配置能设置为内部时钟倍频后得到的36MHZ的系统时钟。

内部时钟设置

  • HSI(内部高速时钟信号) 的 PLL (锁相环)输入限制

STM32F10x 系列中,当选择 HSI 作为 PLL 时钟源 时,必须对 HSI 进行 2 分频 (即 HSI/2 = 4MHz)。可以通过库函数发现没有其它选项

PLL 的倍频系数范围为 2~16 倍 ,因此最高输出频率:无法通过 HSI 达到 72MHz。最大是64MHZ,因此如果想达到72MHZ必须要使用外部时钟源。

  • APB1最大能达到的速度是36MHZ,因此当系统时钟的速度大于36MHZ的时候,APB1的时钟都需要分频设置一下。
  • 为什么都设置为72MHZ作为内部系统时钟呢,全速USB的系统时钟需要48MHZ,72MHZ通过1.5倍分频后刚好是48MHZ。
  • 为什么不常用内部时钟做系统时钟呢?因为内部时钟温漂大,它的震动频率会随着温度变化幅度大。

以外部晶振作为系统时钟如果不想设置为72MHZ,那么该怎么配置这个函数呢?

复制代码
#include "stm32f10x.h"
#include "stm32f10x_rcc.h"

void SetSysClockToHSE_72MHz(void) {
    // 复位RCC配置
    RCC_DeInit();
    
    // 使能HSE
    RCC_HSEConfig(RCC_HSE_ON);
    while (RCC_GetFlagStatus(RCC_FLAG_HSERDY) == RESET);

    // 配置PLL:HSE=8MHz → 倍频9 → 72MHz
    RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);
    RCC_PLLCmd(ENABLE);
    while (RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);

    // 配置总线分频
    RCC_HCLKConfig(RCC_SYSCLK_Div1);    // AHB = 72MHz
    RCC_PCLK1Config(RCC_HCLK_Div2);     // APB1 = 36MHz(最大36MHz)
    RCC_PCLK2Config(RCC_HCLK_Div1);     // APB2 = 72MHz

    // 切换系统时钟到PLL
    RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
    while (RCC_GetSYSCLKSource() != 0x08);
}

int main(void) {
    SetSysClockToHSE_72MHz();
    // 后续初始化代码...
}

该函数要放在主函数最前面。可以通过修改参数调整系统时钟比如:

复制代码
 // 配置PLL:HSE=8/2MHz → 倍频9 → 36MHz
    RCC_PLLConfig(RCC_PLLSource_HSE_Div2, RCC_PLLMul_9);

如此就修改了默认系统时钟为36MHZ


在学习TIM2的时候发现它是APB1总线上的设备,但是APB1的总线频率是36MHZ,为什么在设置TIM2的时钟频率的时候还是72MHZ呢,这是因为APB1上的定时器时钟又被硬件自动倍频了。使得APB1上的定时器时钟能够允许在较快时钟频率下工作。但是APB1上的其它外设还是在36MHZ的频率下工作。

看图:

关键区别总结

特性 APB1 Peripheral Clock (PCLK1) APB1 Time Clock(定时器时钟)
作用对象 APB1总线上所有外设的寄存器访问 仅APB1总线上的定时器模块
频率决定因素 直接由HCLK和APB1预分频系数决定 由PCLK1决定,可能自动倍频(×2)
典型场景 低速外设通信(如I2C、UART) 定时器高精度操作(如PWM、输入捕获)
配置影响 修改APB1分频系数直接影响PCLK1频率 修改APB1分频系数可能触发定时器时钟倍频
相关推荐
西城微科方案开发32 分钟前
体重秤PCBA电路方案组成结构
单片机·嵌入式硬件
深圳市青牛科技实业有限公司38 分钟前
「青牛科技 」GC4931P/4938/4939 12-24V三相有感电机驱动芯片 对标Allegro A4931/瑞盟MS4931
科技·单片机·扫地机器人吸尘·筋膜枪电机·驱动轮电机·服务机器人驱动轮电机·工业机器人减速电机
集和诚JHCTECH1 小时前
集和诚携手Intel重磅发布BRAV-7820边缘计算新品,为车路云一体化场景提供强大算力支撑
人工智能·嵌入式硬件·边缘计算
阿超爱嵌入式1 小时前
STM32学习笔记之RCC模块(实操篇)
笔记·stm32·学习
Qingniu011 小时前
「青牛科技」GC5849 12V三相无感正弦波电机驱动芯片
科技·单片机·嵌入式硬件·cpu散热风扇·vga显卡散热风扇·rgb机箱散热风扇·水冷泵及散热风扇
charlie1145141912 小时前
STM32F103C8T6单片机硬核原理篇:讨论GPIO的基本原理篇章1——只讨论我们的GPIO简单输入和输出
c语言·stm32·单片机·嵌入式硬件·gpio·数据手册
阿让啊2 小时前
bootloader+APP中,有些APP引脚无法正常使用?
c语言·开发语言·stm32·单片机·嵌入式硬件
可待电子单片机设计定制(论文)3 小时前
【51单片机】基于单片机的智能门禁系统设计
单片机·mongodb·51单片机
蝎蟹居3 小时前
GB/T 4706.1-2024 家用和类似用途电器的安全 第1部分:通用要求 与2005版差异(1)
人工智能·单片机·嵌入式硬件·物联网·安全
Lhj061613 小时前
stm32 can 遥控帧的问题
stm32·单片机·嵌入式硬件