STM32学习笔记1----STM32F429系统时钟

FreeRTOS任务基本知识

1.系统时钟

在这里插入图片描述
    在 STM32F429 中,有 5 个最重要的时钟源,为 HSI、HSE、LSI、LSE、PLL。其中 PLL实际是分为三个时钟源,分别为主 PLL 和 I2S 部分专用 PLLI2S 和 SAI 部分专用 PLLSAI。
在这里插入图片描述
从时钟频率来分可以分为高速时钟源和低速时钟源,在这 5 个中HSI,HSE以及PLL是高速时钟,LSI 和 LSE 是低速时钟。从来源可分为外部时钟源和内部时钟源,外部时钟源就是从外部通过接晶振的方式获取时钟源,其中 HSE 和 LSE 是外部时钟源,其他的是内部时钟源。下面我们看看 STM32F429 的这 5 个时钟源,我们讲解顺序是按图中红圈标示的顺序:
①、LSI 是低速内部时钟,RC 振荡器,频率为 32kHz 左右。供独立看门狗和自动唤醒单元使用。
②、LSE 是低速外部时钟,接频率为 32.768kHz 的石英晶体。这个主要是 RTC 的时钟源。
③、HSE 是高速外部时钟,可接石英/陶瓷谐振器,或者接外部时钟源,频率范围为 4MHz~26MHz。我们的开发板接的是 25M 的晶振。 HSE 也可以直接做为系统时钟或者 PLL 输入。
④、HSI 是高速内部时钟,RC 振荡器,频率为 16MHz。可以直接作为系统时钟或者用作 PLL输入。
⑤、PLL 为锁相环倍频输出。STM32F4 有三个 PLL:

  1. 主 PLL(PLL)由 HSE 或者 HSI 提供时钟信号,并具有两个不同的输出时钟。 第一个输出 PLLP用于生成高速的系统时钟(最高 180MHz) 第二个输出 PLLQ 为 48M 时钟,用于 USB OTG FS 时钟,随机数发生器的时钟和 SDIO 时钟。
  2. 第一个专用 PLL(PLLI2S)用于生成精确时钟,在 I2S 和 SAI1上实现高品质音频性能。其 中,N 是用于 PLLI2S vco 的倍频系数,其取值范围是:192~432;R 是 I2S 时钟的分频系数,其取值范围是:2~7;Q 是 SAI 时钟分频系数,其取值范围是:2~15;P 没用到。
  3. 第二个专用PLL(PLLSAI)同样用于生成精确时钟,用于 SAI1 输入时钟,同时还为 LCD_TFT 接口提供精确时钟。其中,N 是用于PLLSAI vco 的倍频系数,其取值范围是:192~432; Q 是 SAI 时钟分频系数,其取值范围是:2~15;R 是 LTDC时钟的分频系数,其取值范 围是:2~7;P 没用到。

这里我们着重看看主 PLL 时钟第一个高速时钟输出 PLLP 的计算方法。图 4.3.1.2 是主 PLL 的时钟图。
在这里插入图片描述
从图 4.3.1.2 可以看出。主 PLL 时钟的时钟源要先经过一个分频系数为 M 的分频器,然后经过倍频系数为 N 的倍频器出来之后还需要经过一个分频系数为 P(第一个输出 PLLP)或者 Q(第二个输出 PLLQ)的分频器分频之后,最后才生成最终的主 PLL 时钟。
例如我们的外部晶振选择 25MHz。同时我们设置相应的分频器 M=25,倍频器倍频系数 N=360,分频器分频系数 P=2,那么主 PLL 生成的第一个输出高速时钟 PLLP 为:

PLL=25MHz * N/ (M * P)=25MHz* 360 / (25 * 2) = 180MHz

如果我们选择HSE为PLL时钟源,同时SYSCLK时钟源为PLL,那么SYSCLK时钟为 180MHz。这对于我们后面的实验都是采用这样的配置。

时钟树E标号处: 这里我们指的是以太网 PTP 时钟,AHB 时钟,APB2 高速时钟,APB1 低速时钟。这些时钟都是来源于 SYSCLK 系统时钟。其中以太网 PTP 时钟是使用系统时钟。AHB,APB2 和 APB1 时钟是经过 SYSCLK 时钟分频得来。这里大家记住,AHB最大时钟为180MHz, APB2高速时钟最大频率为90MHz,而APB1低速时钟最大频率为 45MHz。

Several prescalers are used to configure the AHB frequency, the
high-speed APB (APB2) and the low-speed APB (APB1) domains. The
maximum frequency of the AHB domain is 180 MHz. The maximum allowed
frequency of the high-speed APB2 domain is 90 MHz. The maximum allowed
frequency of the low-speed APB1 domain is 45 MHz

HAL 库的 SystemInit 函数并没有像标准库的 SystemInit 函数一样进行时钟的初始化配置。HAL库的 SystemInit 函数除了打开 HSI 之外,没有任何时钟相关配置,所以使用 HAL 库我们必须编写自己的时钟配置函数。首先我们打开工程模板看看我们在工程SYSTEM分组下面定义的sys.c文件中的时钟初始化函数 Stm32_Clock_Init 的内容:

//时钟设置函数
// VCO 频率 Fvco=Fs*(plln/pllm);
//系统时钟频率 Fsys=Fvco/pllp=Fs*(plln/(pllmpllp));
// USB,SDIO,RNG 等的时钟频率 Fusb=Fvco/pllq=Fs
(plln/(pllmpllq));
//Fs:PLL 输入时钟频率,可以是 HSI,HSE 等.
//plln:主 PLL 倍频系数(PLL 倍频),取值范围:64~432.
//pllm:主 PLL 和音频 PLL 分频系数(PLL 之前的分频),取值范围:2~63.
//pllp:系统时钟的主 PLL 分频系数(PLL 之后的分频),取值范围:2,4,6,8.(仅限这 4 个值!)
//pllq:USB/SDIO/随机数产生器等的主 PLL 分频系数(PLL 之后的分频),取值范围:2~15.
//外部晶振为 25M 的时候,推荐值:plln=360,pllm=25,pllp=2,pllq=8.
//得到:Fvco=25
(360/25)=360Mhz
// Fsys=360/2=180Mhz
// Fusb=360/8=45Mhz
//返回值:0,成功;1,失败
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);
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;
RCC_OscInitStructure.PLL.PLLN=plln;
RCC_OscInitStructure.PLL.PLLP=pllp;
RCC_OscInitStructure.PLL.PLLQ=pllq;
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;
RCC_ClkInitStructure.AHBCLKDivider=RCC_SYSCLK_DIV1;
RCC_ClkInitStructure.APB1CLKDivider=RCC_HCLK_DIV4;
RCC_ClkInitStructure.APB2CLKDivider=RCC_HCLK_DIV2;
ret=HAL_RCC_ClockConfig(&RCC_ClkInitStructure,FLASH_LATENCY_5);
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周期。

第一个参数 ClockType 配置说明我们要配置的是SYSCLK,HCLK,PCLK1 和PCLK2 四个时钟。
第二个参数 SYSCLKSource 配置选择系统时钟源为 PLL。
第三个参数 AHBCLKDivider 配置 AHB 分频系数为 1。
第四个参数 APB1CLKDivider 配置 APB1 分频系数为 4。
第五个参数 APB2CLKDivider 配置 APB2 分频系数为 2。

根据我们在主函数中调用 Stm32_Clock_Init(360,25,2,8)时候设置的入口参数值,我们可以计算出,PLL 时钟为 PLLCLK=HSEN/MP=25MHz360/(252)=180MHz,
同时我们选择系统时钟源为 PLL,所以系统时钟 SYSCLK=180MHz。AHB 分频系数为 1,故其频率为HCLK=SYSCLK/1=180MHz。APB1 分频系数为 4,故其频率为 PCLK1=HCLK/4=45MHz。APB2分频系数为 2,故其频率为 PCLK2=HCLK/2=180/2=90MHz。最后我们总结一下通过调用函数
Stm32_Clock_Init(360,25,2,8)之后的关键时钟频率值:

SYSCLK(系统时钟) =180MHz
PLL 主时钟 =180MHz
AHB 总线时钟(HCLK=SYSCLK/1) =180MHz
APB1 总线时钟(PCLK1=HCLK/4) =45MHz
APB2 总线时钟(PCLK2=HCLK/2) =90MHz

从STM32F4的内部时钟树可知,
(1)当APB1和APB2分频数为1的时候,TIM1、TIM8 ~ TIM11的时钟为APB2的时钟,TIM2~ TIM7、TIM12~TIM14的时钟为APB1的时钟;
(2)而如果APB1和APB2分频数不为1,那么TIM1、TIM8~ TIM11的时钟为APB2的时钟的两倍,TIM2~ TIM7、TIM12~ TIM14的时钟为APB1的时钟的两倍。即HCLK/4*2 =90MHz

    TIM3_Init(5000-1,9000-1);       //定时器3初始化,定时器时钟为90M,分频系数为9000-1,
                                    //所以定时器3的频率为90M/9000=10K,自动重装载为5000-1,那么定时器周期就是500ms
  • 1
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值