STM32 时钟树

在我之前的文章中讲到了时钟的使能,我们通过查看系统的框架图,找到了AHB系统总线,在图中可以知道其为168MHz。那这168MHz是怎么来的呢,STM32中的时钟结构是怎样的呢?时钟的问题是一个很基础的问题,是学习一款单片机的核心,我们可以通过参考手册看看STM32的时钟树是怎样的。


在初始UART中我们使能了APB2,在上图中我们在左侧找到了APBx外设时钟,那么这个时钟源是怎么个回事呢?

stm32有5个时钟源分别是:高速内部时钟(HSI),低速内部时钟(LSI),高速外部时钟(HSE),低速内部时钟(LSE)和锁相环倍频输出(PLL)。

而我们的系统时钟能达到168MHz是怎么来的呢,根据上图,最大的HSE只达到了26MHz,所以我们使用的PLL来实现168MHz的。

在图里的第五块部分:

N表示倍频系数(取值范围:64~432),P表示系统时钟的主PLL分频系数(取值范围:2、4、6、8)

Q表示USB/SDIO/随机数产生器等主PLL分频系数(PLL之后的分频),取值范围:2~15。

R暂时用不上。

我们通常编写代码是会遇到

void Stm32_Clock_Init(u32 plln,u32 pllm,u32 pllp,u32 pllq)
Stm32_Clock_Init(336,8,2,7);//设置时钟168MHz;

外部晶振伟8MHz时,推荐使用N=336,M=8,P=2

得到Fvco =8*(336/8)=336MHz

        Fsys=Fvco/2=168MHz

        Fusb=Fvco/7=48MHz

通过SW选择SYSCLK=PLLCLK,即可得到168MHz的系统运行频率。继续通过分频就可得到相应的时钟频率了。

### STM32时钟树配置与原理 #### 一、STM32时钟树概述 STM32时钟树是一个复杂的结构,用于管理芯片内部的各种时钟信号。它负责将时钟源产生的信号分配给不同的外设模块,并允许开发者灵活调整频率以优化性能和功耗[^4]。 #### 二、时钟树的主要组成部分 根据已有资料,可以将STM32时钟树划分为以下几个主要部分: 1. **时钟源** - 主要包括外部晶振(HSE)、内部RC振荡器(HSI)、低速外部晶振(LSE)以及低速内部RC振荡器(LSI)。这些时钟源提供了原始的时钟信号。 - 开发者可以根据具体需求选择合适的时钟源作为系统的主时钟输入[^2]。 2. **时钟分频/倍频** - 使用PLL(Phase-Locked Loop)实现时钟倍频功能,从而获得更高的系统工作频率。 - 同时支持通过预分频器(Prescaler)降低某些外设的工作频率,以便节省电能或适配特定硬件的要求。 3. **时钟输出** - 经过分频和倍频处理后的时钟信号被分配至各个子系统和外设,例如CPU核心、定时器、USART等。 - 不同版本的STM32微控制器可能具有略微差异化的架构设计,但总体思路一致[^1]。 #### 三、配置流程解析 掌握STM32时钟树的关键在于熟悉其配置过程中的几个重要环节: - 设置时钟源优先级; - 调整PLL参数完成所需频率转换; - 定义AHB/APB总线及时钟分频因子; 对于初学者而言,建议重点关注官方文档中提到的核心步骤——即那些标注为黄色区域的部分。随着实践次数增多,这种抽象概念会逐渐变得直观易懂。 以下是基于HAL库的一个简单示例程序片段展示如何初始化基本的系统时钟设置: ```c void SystemClock_Config(void){ RCC_OscInitTypeDef RCC_OscInitStruct = {0}; RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; /** Configure the main internal regulator output voltage */ __HAL_RCC_PWR_CLK_ENABLE(); HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1); /** Initializes the CPU, AHB and APB buses clocks */ RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI; RCC_OscInitStruct.HSIState = RCC_HSI_ON; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI; RCC_OscInitStruct.PLL.PLLM = 8; RCC_OscInitStruct.PLL.PLLN = 100; RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2; RCC_OscInitStruct.PLL.PLLQ = 7; if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK){ Error_Handler(); } /** Initializes the CPU, AHB and APB buses clocks */ RCC_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; if(HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5)!= HAL_OK ){ Error_Handler(); } } ``` 此代码段展示了如何利用STM32CubeMX生成的基础框架进一步定制化自己的项目需求。 #### 四、总结 通过对上述内容的学习可知,虽然初次接触STM32时钟树可能会觉得棘手难解,但实际上只要按照既定方法论循序渐进地学习并不断练习模拟操作,则完全可以克服这一难关[^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值