认识时钟树F1 📅 2026/6/30 5:18:06 下面按 STM32F103ZET6也就是 F1 系列常见 72MHz 配置 来讲。你可以把“时钟树”理解成单片机内部所有模块的“节拍来源分配图”。1. 什么是时钟树STM32 里面很多模块都需要时钟才能工作比如CPU 内核运行需要时钟GPIO 需要时钟USART 串口需要时钟TIM 定时器需要时钟ADC 需要时钟I2C、SPI、DMA 等也需要时钟这些时钟不是随便来的而是从几个源头开始经过 选择、倍频、分频最后送到不同外设。这整套结构就叫 时钟树。可以简单理解为时钟源 → 选择 → PLL倍频 → 系统时钟SYSCLK → AHB/APB分频 → 各个外设2. F1 的几个主要时钟源STM32F1 常见有 4 个时钟源① HSI内部高速时钟HSI 8MHzHSI 是芯片内部自带的 RC 振荡器不需要外接晶振。优点不需要外部硬件上电就能用启动快缺点精度不如外部晶振做串口、USB、精确计时不如 HSE 稳定一般刚上电时STM32 默认先用 HSI 8MHz 启动。② HSE外部高速时钟HSE 常见 8MHz你用的正点原子 STM32F103ZET6 板子一般外部晶振是 8MHz。HSE 是外部晶振提供的时钟。优点精度高稳定常用于 PLL 倍频到 72MHz缺点需要外部晶振启动比 HSI 稍慢一点F1 最常用的系统主频配置就是HSE 8MHz → PLL ×9 → 72MHz③ LSI内部低速时钟LSI ≈ 40kHzLSI 是内部低速 RC 时钟。主要给独立看门狗 IWDGRTC 可选时钟源它不太准但不需要外部晶振。④ LSE外部低速时钟LSE 32.768kHzLSE 一般接 32.768kHz 的手表晶振。主要给RTC 实时时钟它比较准适合做年月日、时分秒。3. 最核心的一条F1 常用 72MHz 是怎么来的对于 STM32F103最大主频一般是72MHz常用配置是HSE 8MHzPLL倍频 ×98MHz × 9 72MHz也就是外部晶振 HSE↓PLL 倍频器↓PLLCLK 72MHz↓SYSCLK 72MHzSYSCLK 就是系统时钟可以理解成单片机的主时钟。4. SYSCLK、HCLK、PCLK1、PCLK2 分别是什么这几个名字很容易混重点记住下面这张关系图SYSCLK 系统时钟↓AHB 分频器↓HCLK↓CPU / 内存 / DMA / AHB总线↓APB1 分频器 → PCLK1 → 低速外设↓APB2 分频器 → PCLK2 → 高速外设① SYSCLKSYSCLK 是系统时钟可以来自HSIHSEPLLCLK最常用SYSCLK PLLCLK 72MHz② HCLKHCLK 是 AHB 总线时钟也就是 CPU、DMA、内存这些用的时钟。通常配置HCLK SYSCLK / 1 72MHz所以 CPU 实际运行频率一般就是 72MHz。③ PCLK1PCLK1 是 APB1 总线时钟。APB1 最大只能到36MHz所以当 HCLK 是 72MHz 时APB1 必须二分频PCLK1 HCLK / 2 36MHzAPB1 上常见外设TIM2、TIM3、TIM4、TIM5USART2、USART3I2C1、I2C2SPI2CANDAC你之前用的 TIM3 就挂在 APB1 上。④ PCLK2PCLK2 是 APB2 总线时钟。APB2 最大可以到72MHz所以常用配置PCLK2 HCLK / 1 72MHzAPB2 上常见外设GPIOA、GPIOB、GPIOC...USART1SPI1ADC1、ADC2TIM1AFIO你之前用的 USART1、GPIOA、GPIOB 都和 APB2 有关。5. 最经典的 F1 72MHz 时钟配置你可以直接记这个HSE 8MHzPLL ×9SYSCLK 72MHzAHB /1HCLK 72MHzAPB1 /2PCLK1 36MHzAPB2 /1PCLK2 72MHzADC PCLK2 /6 12MHz整理成表格项目配置结果HSE8MHz8MHzPLL×972MHzSYSCLKPLLCLK72MHzAHB/1HCLK 72MHzAPB1/2PCLK1 36MHzAPB2/1PCLK2 72MHzADC/6ADCCLK 12MHz6. 重点定时器时钟有一个特殊规则这个地方很重要很多人学 PWM 会搞混。规则是如果 APB 分频系数 1定时器时钟 PCLK如果 APB 分频系数 1定时器时钟 PCLK × 2例如你常用的 TIM3TIM3 在 APB1 上。常用配置HCLK 72MHzAPB1 /2PCLK1 36MHz因为 APB1 分频系数是 2大于 1所以TIM3CLK PCLK1 × 2 36MHz × 2 72MHz也就是说虽然 APB1 是 36MHz但是 TIM3 的输入时钟还是 72MHz。这就是为什么很多 PWM 计算时用的是 72MHz而不是 36MHz。7. 结合你之前的 TIM3_PWM_Init(7199, 1)你之前代码里有TIM3_PWM_Init(7199, 1);一般意思是ARR 7199PSC 1定时器 PWM 频率公式PWM频率 定时器时钟 / (PSC 1) / (ARR 1)TIM3 时钟是 72MHz所以PWM频率 72MHz / (1 1) / (7199 1) 72MHz / 2 / 7200 36MHz / 7200 5000Hz所以你的 PWM 频率是5kHz也就是说 TIM3 每秒输出 5000 个 PWM 周期。8. PSC 和 ARR 分别控制什么定时器可以理解为一个自动计数器。TIMxCLK → PSC预分频 → CNT计数 → 到ARR溢出PSC预分频器PSC 负责先把时钟降下来。公式计数频率 TIMxCLK / (PSC 1)比如TIMxCLK 72MHzPSC 71那么计数频率 72MHz / 72 1MHz也就是计数器 1 微秒加 1。ARR自动重装载值ARR 决定计数器数到多少清零。如果ARR 999计数器就是0, 1, 2, 3 ... 999一共 1000 个数。如果计数频率是 1MHz那么一个 PWM 周期就是1000 × 1us 1ms频率就是1kHz9. CCR 控制占空比PWM 里面还有一个重要寄存器CCRCCR 决定高电平持续多久。在 PWM 模式 1 下可以简单理解为CNT CCR 时输出有效电平CNT CCR 时输出无效电平占空比公式占空比 CCR / (ARR 1)比如ARR 7199CCR 3600那么占空比 3600 / 7200 50%如果CCR 7200接近 100%。如果CCR 0就是 0%。你之前电机调速本质就是改 CCR。10. CubeMX / HAL 里时钟树怎么看在 STM32CubeMX 里面时钟树大概这样设置第一步选择 HSERCC → High Speed Clock HSE → Crystal/Ceramic Resonator意思是使用外部晶振。第二步PLL Source 选择 HSEPLL Source Mux HSE第三步PLL 倍频选择 ×9PLL MUL ×9如果 HSE 是 8MHz8MHz × 9 72MHz第四步SYSCLK 选择 PLLCLKSystem Clock Mux PLLCLK这样系统主频就是 72MHz。第五步设置总线分频AHB Prescaler /1APB1 Prescaler /2APB2 Prescaler /1ADC Prescaler /6最后得到SYSCLK 72MHzHCLK 72MHzPCLK1 36MHzPCLK2 72MHzADC 12MHz11. HAL 代码里时钟树怎么写HAL 工程里一般有一个函数void SystemClock_Config(void){}F103 72MHz 常见写法大概是void SystemClock_Config(void){RCC_OscInitTypeDef RCC_OscInitStruct {0};RCC_ClkInitTypeDef RCC_ClkInitStruct {0};// 1. 配置外部高速晶振 HSE 和 PLLRCC_OscInitStruct.OscillatorType RCC_OSCILLATORTYPE_HSE;RCC_OscInitStruct.HSEState RCC_HSE_ON;RCC_OscInitStruct.HSEPredivValue RCC_HSE_PREDIV_DIV1;RCC_OscInitStruct.PLL.PLLState RCC_PLL_ON;RCC_OscInitStruct.PLL.PLLSource RCC_PLLSOURCE_HSE;RCC_OscInitStruct.PLL.PLLMUL RCC_PLL_MUL9;HAL_RCC_OscConfig(RCC_OscInitStruct);// 2. 配置 SYSCLK、HCLK、PCLK1、PCLK2RCC_ClkInitStruct.ClockType RCC_CLOCKTYPE_HCLK |RCC_CLOCKTYPE_SYSCLK |RCC_CLOCKTYPE_PCLK1 |RCC_CLOCKTYPE_PCLK2;RCC_ClkInitStruct.SYSCLKSource RCC_SYSCLKSOURCE_PLLCLK;RCC_ClkInitStruct.AHBCLKDivider RCC_SYSCLK_DIV1;RCC_ClkInitStruct.APB1CLKDivider RCC_HCLK_DIV2;RCC_ClkInitStruct.APB2CLKDivider RCC_HCLK_DIV1;HAL_RCC_ClockConfig(RCC_ClkInitStruct, FLASH_LATENCY_2);}重点看这几句RCC_OscInitStruct.HSEState RCC_HSE_ON;开启外部晶振。RCC_OscInitStruct.PLL.PLLSource RCC_PLLSOURCE_HSE;PLL 使用 HSE 作为输入。RCC_OscInitStruct.PLL.PLLMUL RCC_PLL_MUL9;PLL 倍频 9 倍。RCC_ClkInitStruct.SYSCLKSource RCC_SYSCLKSOURCE_PLLCLK;系统时钟选择 PLL 输出。RCC_ClkInitStruct.APB1CLKDivider RCC_HCLK_DIV2;APB1 分频为 2所以 PCLK1 是 36MHz。RCC_ClkInitStruct.APB2CLKDivider RCC_HCLK_DIV1;APB2 不分频所以 PCLK2 是 72MHz。FLASH_LATENCY_272MHz 下 Flash 需要 2 个等待周期这个很重要。12. 为什么要设置 Flash 延迟CPU 跑到 72MHz 后取指令速度很快。Flash 读取速度跟不上 CPU就需要加等待周期。所以 72MHz 一般配置FLASH_LATENCY_2如果这个设置不对可能会出现程序跑飞下载后不稳定中断异常代码莫名卡死所以时钟配置不是只改 PLL还要配 Flash 延迟。13. 外设时钟和 RCC 有什么关系你之前经常看到这种代码__HAL_RCC_GPIOA_CLK_ENABLE();__HAL_RCC_TIM3_CLK_ENABLE();__HAL_RCC_USART1_CLK_ENABLE();或者标准库版本RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);这就是给外设开时钟。STM32 为了省电外设默认很多是关闭时钟的。比如 GPIOA 没开时钟你就算配置 PA9、PA10也没用。可以理解为外设没有时钟 外设没通电 配置无效14. 常见外设挂在哪条总线上你需要重点记这些。APB2 外设GPIOAGPIOBGPIOCGPIODAFIOUSART1SPI1ADC1ADC2TIM1所以 GPIO 初始化经常看到__HAL_RCC_GPIOA_CLK_ENABLE();USART1 初始化会开__HAL_RCC_USART1_CLK_ENABLE();APB1 外设TIM2TIM3TIM4TIM5USART2USART3I2C1I2C2SPI2CAN你的小车 PWM 用 TIM3所以它在 APB1 上__HAL_RCC_TIM3_CLK_ENABLE();15. 为什么 APB1 不能直接 72MHzSTM32F1 里面 APB1 属于低速外设总线最大频率是36MHz而 APB2 可以到72MHz所以 72MHz 系统主频下必须这样分APB1 72MHz / 2 36MHzAPB2 72MHz / 1 72MHz如果 APB1 不分频可能超出芯片手册限制导致外设不稳定。16. 串口波特率和时钟的关系USART1 挂在 APB2USART1 时钟 PCLK2 72MHzUSART2、USART3 挂在 APB1USART2/3 时钟 PCLK1 36MHz所以如果你用 USART1 蓝牙通信波特率 9600 是根据 72MHz 算出来的。如果系统时钟配置不对比如本来以为是 72MHz实际还是 8MHz那么串口就会出现乱码接收异常蓝牙通信失败所以串口乱码有时候不一定是接线错也可能是系统时钟没配对。17. ADC 时钟为什么要单独分频ADC 在 F1 里面最大时钟一般不能超过14MHz如果 PCLK2 是 72MHzADC 不能直接用 72MHz。所以常用ADC Clock PCLK2 / 6 12MHz或者ADC Clock PCLK2 / 8 9MHz所以 ADC 这一路一般要单独分频。18. USB 为什么要求 48MHzSTM32F103 如果使用 USBUSB 时钟要求48MHz当 PLL 输出是 72MHz 时可以通过USBCLK PLLCLK / 1.5 48MHz所以 F103 用 USB 时72MHz 主频也很常见。19. RTC 和看门狗的时钟RTC 不走 SYSCLK 主时钟而是可以从低速时钟来。RTC 常见来源LSE 32.768kHzLSI 40kHzHSE / 128独立看门狗 IWDG 通常使用LSI这也是为什么有时候系统主时钟停了看门狗还可以继续工作。20. 用一张图总结 F1 时钟树HSI 8MHz│├── 可直接作为 SYSCLK│└── HSI/2 → PLLHSE 8MHz│├── 可直接作为 SYSCLK│└── PLL ×9│↓PLLCLK 72MHz│↓SYSCLK 72MHz│↓AHB /1│↓HCLK 72MHz│ ││ ├── CPU│ ├── DMA│ └── 存储器│├── APB1 /2│ ↓│ PCLK1 36MHz│ ↓│ TIM2/3/4/5 实际可为 72MHz│ USART2/3、I2C、SPI2│└── APB2 /1↓PCLK2 72MHz↓GPIO、USART1、SPI1、ADC、TIM121. 你现在最应该记住的版本对于你现在做 STM32F103 小车、PWM、电机、蓝牙、OLED先记这个就够了外部晶振 HSE 8MHz8MHz × 9 72MHzSYSCLK 72MHzHCLK 72MHzPCLK1 36MHzPCLK2 72MHzTIM3CLK 72MHzUSART1CLK 72MHzGPIO 时钟在 APB2TIM3 时钟在 APB1你之前 TIM3 PWMTIM3_PWM_Init(7199, 1);对应TIM3CLK 72MHzPSC 1ARR 7199PWM频率 72MHz / 2 / 7200 5kHz22. 一句话理解STM32F1 时钟树的核心就是先用 HSE 8MHz 经过 PLL 倍频到 72MHz再把 72MHz 分给 CPU、总线和外设。APB1 慢一点最多 36MHzAPB2 快一点可以 72MHz定时器在 APB 分频不为 1 时时钟会自动翻倍。你学 PWM、串口、ADC、定时器的时候基本都绕不开这棵时钟树。