STM32时钟详解(基于STM32F429)

目录

前言

一、时钟源组成

二、时钟树

三、时钟代码分析


前言

STM32的时钟就像是这个微控制器(MCU)的“心跳”或者“节拍器”。它决定了STM32内部各个部分(比如CPU、GPIO端口、串口通信等)的运行速度和时序。想象一下,如果你有一个机器人在做动作,时钟就是控制它每一步动作的速度和时间点的。如果时钟快了,机器人的动作就会加速;如果时钟慢了,机器人的动作就会变慢。同样地,在STM32中,如果时钟频率设置得高,MCU就会运行得更快,能够更快地处理数据;如果时钟频率设置得低,MCU就会运行得慢一些。

一、时钟源组成

1. HSI(高速内部时钟):一个内部RC(Resistor-Capacitor)振荡器,其频率为16MHz。HSI可以直接作为系统时钟或者用作PLL(锁相环)的输入。

2. HSE(高速外部时钟):一个外部时钟源,可以接石英/陶瓷谐振器或外部时钟源,频率范围为4MHz到26MHz。HSE也可以直接作为系统时钟或PLL的输入。

3. LSI(低速内部时钟):一个内部RC振荡器,频率为32kHz左右,主要用于独立看门狗和自动唤醒单元。

4. LSE(低速外部时钟):一个外部时钟源,通常接频率为32.768kHz的石英晶体,主要用于RTC(实时时钟)的时钟源。

5. PLL(锁相环):PLL实际分为三个时钟源,包括主PLL和专用的PLLI2S、PLLSAI。PLL用于倍频输入时钟信号,以产生更高的时钟频率。

(1)主PLL(PLL):由HSE或HSI提供时钟信号,并有两个不同的输出时钟。第一个输出PLLP用于生成高速的系统时钟(最高180MHz),第二个输出PLLQ为48MHz时钟,用于USB OTG FS时钟、随机数发生器的时钟和SDIO时钟。

(2)PLLI2S(专用PLL):用于生成精确时钟,在I2S和SAI1上实现高品质音频性能。

(3)PLLSAI(专用PLL):同样用于生成精确时钟,用于SAI1输入时钟,并为LCD_TFT接口提供精确时钟。

二、时钟树

由上图所示,①②③④⑤分别代表着stm32f429的五个时钟源,其频率和描述在上面我们都讲过了,所以不再赘述,下面带*为常用时钟。

A* 这是独立看门狗的时钟,实际时钟是一个 15~47kHz之间不精确的时钟,因为看门狗不需要那么高的精度,所以并不影响使用,我们将其默认为32kHz。

B* 这是RTC的输入时钟,RTC 的时钟源可以选择 LSI,LSE,以及HSE 分频后的时钟,HSE 分频系数为 2~31,一般我们默认使用LSE。

C* 在STM32F429中,MCO用来输出时钟,MCO1是一个特定的引脚(如PA8),它有四个时钟来源分别为:HSI,LSE,HSE 和 PLL 时钟,MCO2也是一个特定的引脚(如PA9),它同样有四个时钟来源分别为:HSE,PLL,SYSCLK 以及 PLLI2S时钟。

D* 这是系统时钟,可来源于HSI、HSE、PLL这三个时钟源其中之一,我们默认一般用PLL作为系统时钟的默认时钟源。

E* 这里指的是以太网PTP时钟、AHB 总线时钟,APB2 高速时钟,APB1 低速时钟,其中PTP时钟与系统时钟相同,AHB时钟、APB2时钟、APB1时钟是经过 SYSCLK 时钟分频得到的,AHB时钟最大为180MHz,APB2最大是90MHz,APB1最大是45MHz。

 这里是指 PLLI2S_R 时钟,可以作为 I2S 时钟源。

G  这里是指 PLLI2S_Q 时钟,可以作为 SAI1_A 和 SAI1_B 时钟来源。

H  这里是指 PLLSAI_Q 时钟,可以作为 SAI1_A 和 SAI1_B 时钟来源。

I  这里是指 PLLSAI_R 时钟,是 LCD-TFT(LTDC)接口时钟唯一来源。

J  这里是 I2S 的时钟,通过寄存器 I2SSRC 设置内部 PLLI2SCLK 还是外部 I2SCKIN作为时钟。

K  这里是 SAI1_A 的时钟,通过寄存器 SAI1ASRC 选择内部 PLLSAI_Q、PLLI2S_Q
还是外部 I2SCKIN 作为时钟。

L  这里是 SAI1_B 接口的时钟,通过寄存器 SAI1BSRC 选择内部 PLLSAI_Q、
PLLI2S_Q 还是外部 I2SCKIN 作为时钟。阿波罗没用到 SAI1_B 输出,所以这里
不用设置。

M  这里是 LTDC 接口的时钟,LTDC 的时钟,固定为 PLLSAI_R。

N  这是 STM32F4 内部以太网 MAC 时钟的来源。对于 MII 接口来说,必须向外部
PHY 芯片提供 25Mhz 的时钟,这个时钟,可以由 PHY 芯片外接晶振,或者使用
STM32F4 的 MCO 输出来提供。然后,PHY 芯片再给 STM32F4 提供ETH_MII_TX_CLK 和 ETH_MII_RX_CLK 时钟。对于 RMII 接口来说,外部必须提供 50Mhz 的时钟驱动 PHY 和 STM32F4 的 ETH_RMII_REF_CLK,这个 50Mhz时钟可以来自 PHY、有源晶振或者  MCO。

O  这里是指外部 PHY 提供的 USB_OTG_HS(60MHZ)时钟。

APB1与APB2根据时钟速率不同,主要连接以下外设:

APB1(低速外设总线)

  • 电源接口
  • 备份接口
  • CAN(控制器局域网)
  • USB
  • I2C1和I2C2(双向串行接口)
  • UART2和UART3(通用异步收发器)
  • SPI2(串行外设接口)
  • 窗口看门狗
  • Timer2、Timer3和Timer4(定时器)

APB2(高速外设总线)

  • GPIO_A到GPIO_E(通用输入/输出端口)
  • USART1(通用同步/异步收发器)
  • ADC1、ADC2和ADC3(模数转换器)
  • TIM1和TIM8(高级定时器)
  • SPI1(串行外设接口)

三、时钟代码分析

void Stm32_Clock_Init(u32 plln,u32 pllm,u32 pllp,u32 pllq)
{
    HAL_StatusTypeDef ret = HAL_OK;
    RCC_OscInitTypeDef RCC_OscInitStructure; 
    RCC_ClkInitTypeDef RCC_ClkInitStructure;
    
    __HAL_RCC_PWR_CLK_ENABLE(); //使能PWR时钟
    
    //下面这个设置用来设置调压器输出电压级别,以便在器件未以最大频率工作
    //时使性能与功耗实现平衡,此功能只有STM32F42xx和STM32F43xx器件有,
    __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);//设置调压器输出电压级别1
    
    RCC_OscInitStructure.OscillatorType=RCC_OSCILLATORTYPE_HSE;    //时钟源为HSE
    RCC_OscInitStructure.HSEState=RCC_HSE_ON;                      //打开HSE
    RCC_OscInitStructure.PLL.PLLState=RCC_PLL_ON;//打开PLL
    RCC_OscInitStructure.PLL.PLLSource=RCC_PLLSOURCE_HSE;//PLL时钟源选择HSE
    RCC_OscInitStructure.PLL.PLLM=pllm; //主PLL和音频PLL分频系数(PLL之前的分频),取值范围:2~63.
    RCC_OscInitStructure.PLL.PLLN=plln; //主PLL倍频系数(PLL倍频),取值范围:64~432.  
    RCC_OscInitStructure.PLL.PLLP=pllp; //系统时钟的主PLL分频系数(PLL之后的分频),取值范围:2,4,6,8.(仅限这4个值!)
    RCC_OscInitStructure.PLL.PLLQ=pllq; //USB/SDIO/随机数产生器等的主PLL分频系数(PLL之后的分频),取值范围:2~15.
    ret=HAL_RCC_OscConfig(&RCC_OscInitStructure);//初始化
	
    if(ret!=HAL_OK) while(1);
    
    ret=HAL_PWREx_EnableOverDrive(); //开启Over-Driver功能
    if(ret!=HAL_OK) while(1);
    
    //选中PLL作为系统时钟源并且配置HCLK,PCLK1和PCLK2
    RCC_ClkInitStructure.ClockType=(RCC_CLOCKTYPE_SYSCLK|RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2);
    RCC_ClkInitStructure.SYSCLKSource=RCC_SYSCLKSOURCE_PLLCLK;//设置系统时钟时钟源为PLL
    RCC_ClkInitStructure.AHBCLKDivider=RCC_SYSCLK_DIV1;//AHB分频系数为1
    RCC_ClkInitStructure.APB1CLKDivider=RCC_HCLK_DIV4; //APB1分频系数为4
    RCC_ClkInitStructure.APB2CLKDivider=RCC_HCLK_DIV2; //APB2分频系数为2
    ret=HAL_RCC_ClockConfig(&RCC_ClkInitStructure,FLASH_LATENCY_5);//同时设置FLASH延时周期为5WS,也就是6个CPU周期。
		
    if(ret!=HAL_OK) while(1);
}

plln是主 PLL 倍频系数(PLL 倍频),取值范围:64~432。

pllm是主 PLL 和音频 PLL 分频系数(PLL 之前的分频),取值范围:2~63。

pllp是系统时钟的主 PLL 分频系数(PLL 之后的分频),取值范围:2,4,6,8。

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

本函数我们传参,plln=360,pllm=25,pllp=2,pllq=8。

我们选择了,HSE外部晶振作为我们系统的基础时钟源,HSE的时钟频率为25MHz,所以系统时钟为25*360/25/2=180MHz。AHB分频系数是1,所以AHB时钟也是180MHz。APB1的分频系数是4,所以APB1的时钟是45MHz。APB2的分频系数是2,所以APB2的时钟是90MHz。

  • 35
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

千千道

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值