尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

STM32时钟树详解:配错一个全乱套

STM32时钟树详解:配错一个全乱套 你有没有遇到过UART波特率9600发出来却是乱码定时器中断频率不对十有八九是时钟配置错了。这篇把STM32时钟树从HSE讲到APB帮你彻底搞懂。一、为什么时钟这么重要STM32的每个外设都依赖时钟工作UART波特率 APB时钟 / 分频I2C/SPI速率 APB时钟 / 分频定时器中断频率 APB时钟 / [(PSC1)(ARR1)]ADC转换时间 ADC时钟相关时钟配错了所有外设的时序全错。二、四个时钟源STM32有4个时钟源时钟源简称频率精度用途内部高速RCHSI8MHz/16MHz±1%上电默认精度差外部高速晶振HSE4-26MHz±20ppm主力时钟精度高内部低速RCLSI32kHz-40kHz±10%看门狗、RTC外部低速晶振LSE32.768kHz±20ppmRTC精准计时主力用HSE外部晶振。HSI精度差±1%高波特率通信可能出错。三、时钟树以STM32F103为例HSE 8MHz ──→ PLL倍频 ──→ SYSCLK(72MHz) ──→ AHB分频 ──→ HCLK(72MHz) **PLL是什么** PLLPhase-Locked Loop锁相环是STM32内部的一个硬件模块你可以理解为一个频率乘法器——输入8MHz设置倍频系数×9输出就是8×972MHz。STM32内部没法直接产生72MHz的高频时钟所以用PLL把外部晶振的8MHz放大到72MHz。 │ ┌─────────────────────────┤ ↓ ↓ APB1分频 APB2分频 (/2 36MHz) (/1 72MHz) │ │ ↓ ↓ PCLK1(36MHz) PCLK2(72MHz) (UART2/3, I2C, (UART1, SPI1, TIM2-7, ADC) TIM1, GPIO) │ ↓ ADC时钟(≤14MHz)3.1 SYSCLK系统时钟MCU的主频。STM32F103最高72MHzSTM32F407最高168MHzSTM32H7最高480MHz。3.2 HCLKAHB总线时钟CPU和DMA跑在这个频率上。通常等于SYSCLK。3.3 PCLK1APB1低速外设时钟STM32F103最大36MHz。挂在这里的USART2/3、I2C、SPI2、TIM2-7、ADC。3.4 PCLK2APB2高速外设时钟STM32F103最大72MHz。挂在这里的USART1、SPI1、TIM1、GPIO、ADC。3.5 定时器倍频重要当APB1分频≠1时通常÷236MHz挂在上面的定时器会自动×2倍频72MHz。APB1 36MHz → 定时器时钟 36MHz × 2 72MHz APB2 72MHz → 定时器时钟 72MHz不倍频因为APB2分频1坑点很多人以为TIM2-7的时钟是36MHz实际是72MHz。算定时器频率时别搞错。四、典型配置F103 72MHz4.1 CubeMX配置HSE: 8MHz (外部晶振) PLL Source: HSE PLL Multiplier: ×9 → 8MHz × 9 72MHz SYSCLK: PLL 72MHz AHB Prescaler: /1 → HCLK 72MHz APB1 Prescaler: /2 → PCLK1 36MHz APB2 Prescaler: /1 → PCLK2 72MHz4.2 代码寄存器版voidSystemClock_Config(void){/* 1. 开HSE */RCC-CR|(116);/* HSEON */while(!(RCC-CR(117)));/* 等HSERDY *//* 2. 配置Flash等待周期72MHz需要2个等待 *//* Flash是物理存储读取速度有限。CPU跑72MHz时Flash来不及在一个时钟周期内交出数据 * 需要等2个周期。不配等待周期会导致CPU读到错误指令程序跑飞。 * prefetch预取是让Flash提前取下一条指令弥补等待周期的性能损失 */FLASH-ACR0x00000012;/* 2 wait states prefetch *//* 3. 配置PLLHSE × 9 72MHz */RCC-CFGR|(116);/* PLLSRC HSE */RCC-CFGR|(718);/* PLLMUL ×9 *//* 4. 配置分频 */RCC-CFGR|(48);/* APB1 HCLK/2 36MHz *//* APB2 HCLK/1 72MHz默认不用配 *//* 5. 开PLL */RCC-CR|(124);/* PLLON */while(!(RCC-CR(125)));/* 等PLLRDY *//* 6. 切换SYSCLK到PLL */RCC-CFGR|(20);/* SW PLL */while(((RCC-CFGR2)3)!2);/* 等SWS PLL */}五、时钟与外设的关系5.1 UART波特率/* UART1挂在APB2(72MHz) */波特率72MHz/(16× BRR值)BRR72MHz/(16×115200)39.0625≈39/* UART2挂在APB1(36MHz) */波特率36MHz/(16× BRR值)BRR36MHz/(16×115200)19.53≈20注意UART1和UART2时钟不同BRR值也不同。配错时钟波特率必错。5.2 定时器频率/* TIM2挂在APB1(36MHz)定时器倍频×2 72MHz */中断频率72MHz/[(PSC1)×(ARR1)]/* 要1kHz中断 *//* 72MHz / [(711) × (9991)] 1kHz ✓ */5.3 ADC时钟STM32F103的ADC最大14MHz从APB2(72MHz)分频ADCCLK PCLK2 / 分频系数 72MHz / 6 12MHz ✓≤14MHz 72MHz / 4 18MHz ✗超过14MHz可能出错六、常见踩坑坑1UART乱码——时钟没配现象代码写115200串口助手收到的全是乱码。原因系统时钟默认8MHz(HSI)但波特率按72MHz算的。解决确保SystemClock_Config()被调用且配置正确。坑2定时器频率差9倍原因没配PLLSYSCLK8MHz而非72MHz。定时器按72MHz算实际8MHz差9倍。坑3ADC时钟超限ADC时钟超过14MHzF103限制采样数据不稳定甚至损坏。检查分频系数。坑4Flash等待周期不够CPU频率24MHz(F103)时Flash读取需要等待周期。72MHz需要2个等待周期不配会HardFault。七、总结要点内容四个时钟源HSE(主力)/HSI(备用)/LSE(RTC)/LSI(看门狗)SYSCLK系统主频F103最高72MHzAPB1低速F103最大36MHz定时器×2倍频72MHzAPB2高速F103最大72MHz时钟影响UART波特率、定时器频率、ADC速率全取决于时钟一句话总结时钟树的核心是HSE→PLL倍频→SYSCLK→AHB/APB分频→外设配错任何一级下游全错。下一篇预告《启动流程详解从上电到main()发生了什么》如果这篇文章对你有帮助点赞 收藏 关注这是我持续更新的动力有问题欢迎评论区交流我会逐条回复。作者嵌入式阿蔡
返回列表