17.stm32_Clock Init时钟系统初始化函数剖析

stm32_Clock Init时钟系统初始化函数剖析

阿波罗STM32开发板:
《STM32FXX开发指南-HAL库版本》-4.3小节 STM32F4时钟系统
STM32FXxx官方资料:
《STM32F4xx中文参考手册》-第6章 复位和时钟控制

笔记基于正点原子官方视频
视频连接https://www.bilibili.com/video/BV1Wx411d7wT?p=71&spm_id_from=333.1007.top_right_bar_window_history.content.click
如有侵权,联系删除

一、STM32 有5个时钟源:HSI、HSE、LSI、LSE、PLL
  • HSI是高速内部时钟,RC振荡器,频率为16MHz,精度不高。可以直接作为系统时钟或者用作PLL时钟输入。

  • HSE是高速外部时钟,可接石英/陶瓷谐振器,或者接外部时钟源,频率范围为4MHz~26MHz。

  • LSI是低速内部时钟,RC振荡器,频率为32kHz,提供低功耗时钟。

  • LSE是低速外部时钟,接频率为32.768kHz的石英晶体。RTC

  • PLL为锁相环倍频输出。

  • 系统时钟默认使用的是HSI时钟

1)STM32F4有三个PLL:

  • 主PLL(PLL)由HSE或者HSI提供时钟信号,并具有两个不同的输出时钟。
    ①第一个输出PLLP用于生成高速的系统时钟
    ②第二个输出PLLQ为48M时钟,用于USB OTG FS时钟,随机数
    发生器的时钟和SDIO时钟。
  • 第一个专用PLL(PLLI2S)生成精确时钟,在I2S和SAI1上实现高品质音频
    N是用于PLLI2S vco的倍频系数 ;
    R是I2S时钟的分频系数 ;
    Q是SAI时钟分频系数 ;P没用到。
  • 第二个专用PLL(PLLSAI)同样用于生成精确时钟,用于SAI1输入时钟,同时还为LCD_TFT接口提供精确时钟。
    N是用于PLLSAI vco的倍频系数 ;
    Q是SAI时钟分频系数 ;
    R是LTDC时钟的分频系数 。
    2)主PLL时钟计算:
    在这里插入图片描述
PLLCLK= HSE * N / (M*P)
二、系统初始化函数 SystemInit();

使用HAL库函数的时候,在系统启动之后会自动调用:

; Reset handler
Reset_Handler PROC
			EXPORT Reset_Handler [WEAK]
		IMPORT SystemInit
		IMPORT __main
			LDR R0, =SystemInit
			BLX R0
			LDR R0, =__main
			BX R0
			ENDP
三、时钟系统配置一般步骤:
  • 使能PWR时钟:调用函数 __HAL_RCC_PWR_CLK_ENABLE()。
  • 设置调压器输出电压级别:调用函数 __HAL_PWR_VOLTAGESCALING_CONFIG()。
  • 选择是否开启Over-Driver功能:调用函数 HAL_PWREx_EnableOverDrive()。
  • 配置时钟源相关参数:调用函数 HAL_RCC_OscConfig()。
  • 配置系统时钟源以及AHB,APB1和APB2的分频系数:调用函数 HAL_RCC_ClockConfig()。
1.时钟源配置函数:HAL_RCC_OscConfig

在工程文件HALLIB-stm32f4xx_hal_rcc.h文件里
在这里插入图片描述

__weak HAL_StatusTypeDef HAL_RCC_OscConfig(RCC_OscInitTypeDef *RCC_OscInitStruct)
RCC_OscInitTypeDef定义如下

typedef struct
{
	uint32_t OscillatorType; 
	uint32_t HSEState; 
	uint32_t LSEState; 
	uint32_t HSIState; 
	uint32_t HSICalibrationValue; 
	uint32_t LSIState; 
	RCC_PLLInitTypeDef PLL; 
}RCC_OscInitTypeDef;
typedef struct
{
	uint32_t PLLState; 
	uint32_t PLLSource; 
	uint32_t PLLM; 
	uint32_t PLLN; 
	uint32_t PLLP; 
	uint32_t PLLQ; 
}RCC_PLLInitTypeDef;

HAL_RCC_OscConfig函数配置方法:

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之前的分频)
RCC_OscInitStructure.PLL.PLLN=plln; 															//主PLL倍频系数(PLL倍频)
RCC_OscInitStructure.PLL.PLLP=pllp; 															//系统时钟的主PLL分频系数(PLL之后的分频)
RCC_OscInitStructure.PLL.PLLQ=pllq; 															//USB/SDIO/随机数产生器等的主PLL分频系数
HAL_RCC_OscConfig(&RCC_OscInitStructure);											//初始化

后面我们在主函数里调用Stm32_Clock_Init(360,25,2,8); //设置时钟,180Mhz
查看Stm32_Clock_Init定义有:
在这里插入图片描述
可以看到Stm32_Clock_Init(360,25,2,8);中N=360;M=25;P=2;Q=8,对应时钟倍数关系如下图:
在这里插入图片描述

2.时钟配置函数:HAL_RCC_ClockConfig

HAL_StatusTypeDef HAL_RCC_ClockConfig(RCC_ClkInitTypeDef *RCC_ClkInitStruct, uint32_t FLatency)

在工程文件HALLIB-stm32f4xx_hal_rcc.h文件里
在这里插入图片描述
RCC_ClkInitTypeDef定义如下

typedef struct
{
	uint32_t ClockType; 
	uint32_t SYSCLKSource; 
	uint32_t AHBCLKDivider; 
	uint32_t APB1CLKDivider; 
	uint32_t APB2CLKDivider; 
}RCC_ClkInitTypeDef;

函数HAL_RCC_ClockConfig配置实例

//选中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;												//AHB分频系数为1
RCC_ClkInitStructure.APB1CLKDivider=RCC_HCLK_DIV4;													 //APB1分频系数为4
RCC_ClkInitStructure.APB2CLKDivider=RCC_HCLK_DIV2; 												//APB2分频系数为2
(&RCC_ClkInitStructure,FLASH_LATENCY_5);
//同时设置FLASH延时周期为5WS,也就是6个CPU周期。

配置系统时钟图如下:
在这里插入图片描述

3.FLASH等待周期表(STM32F429)

在这里插入图片描述

4.使能PWR时钟:

配置调压器输出级别和开启Over-driver功能需要开启PWR时钟。

5.配置调压器输出级别:

__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);

PWR_CR寄存器来配置:
位15:14 VOS[1:0]
00:保留(默认模式3选中)
01:级别3:HCLK最大频率120MHz
10:级别2:HCLK最大频率144MHz
11:级别1:HCLK最大频率168MHz,通过开启Over-drive模式可以达到180MHz。

6.开启Over-Driver功能:

HAL_StatusTypeDef HAL_PWREx_EnableOverDrive(void);

7.系统时钟配置完整代码

在工程文件SYSTEM-sys.c文件里
在这里插入图片描述

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);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值