STM32使用cubemx生成代码的系统时钟频率配置 您所在的位置:网站首页 手机设置cpu频率在哪里 STM32使用cubemx生成代码的系统时钟频率配置

STM32使用cubemx生成代码的系统时钟频率配置

2024-07-09 14:52| 来源: 网络整理| 查看: 265

STM32使用cubemx生成代码的系统时钟频率配置

当使用cubemx软件自动生成hal库代码时,我们在可视化界面配置的系统时钟频率会通过SystemClock_Config()函数进行配置。如下图所示:

img1

下面则是cubemx中可视化界面配置时钟频率的页面。 使用了外部高速时钟HSE当做时钟源,随后对外部高速时钟进行了1分频;然后进入PLL:选择HSE为PLL时钟源,配置PLL Mul为x9,将系统频率选择为PLLCLK输入,然后得到SYSCLK。SYSCLK通过AHB Prescaler(1分频)得到HCLK时钟,通过APB1 Prescaler(2分频)得到PCLK1时钟,通过APB2 Prescaler(1分频)得到PCLK2时钟。

img2

其实与SystemClock_Config()函数中的配置是一模一样的:

/** * @brief System Clock Configuration * @retval None */ void SystemClock_Config(void) { RCC_OscInitTypeDef RCC_OscInitStruct = {0}; RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; /** Initializes the RCC Oscillators according to the specified parameters * in the RCC_OscInitTypeDef structure. */ RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; RCC_OscInitStruct.HSEState = RCC_HSE_ON; RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1; //对外部高速时钟进行1分频 RCC_OscInitStruct.HSIState = RCC_HSI_ON; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; //选择HSE为PLL时钟源 RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9; //配置PLL Mul为x9 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; //系统频率选择PLLCLK输入 RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; //AHB 1分频 RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2; //APB1 2分频 RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; //APB2 1分频 if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK) { Error_Handler(); } } 系统频率配置过程

首先,STM32上电或复位后,通过汇编代码可以看出来:程序首先会进入SystemInit()函数中做一些初始化的工作,然后再进入main函数中执行。如下图所示:

img3

但是hal库中的SystemInit()函数并没有做配置时钟相关的操作。所以时钟配置只有在main函数中的SystemClock_Config()函数进行。 img4

那么,在STM32上电后到执行SystemClock_Config()函数之前,STM32的运行时钟频率是多少呢?

以STM32F1系列为例,在system_stm32f1xx.c文件中,有具体注释说明,如下图: img5

该文件提供了两个函数和一个全局变量: SystemInit():初始化系统时钟。 SystemCoreClockUpdate():更新SystemCoreClock全局变量。 SystemCoreClock:表示系统运行频率。 当设备(单片机)复位之后,HSI(内部高速时钟,在f1系列为8MHz)会作为系统的时钟源。在"startup_stm32f1xx_xx.s"文件中会在进入main函数之前调用SystemInit()函数去配置系统时钟(显然没有进行配置)。 HSE晶振的默认值设置为了8MHz(根据产品不同,也会设置成25MHz),定义为了HSE_VALUE宏。如果HSE直接或者通过PLL作为了系统时钟源,而且你使用了不同频率的外部晶振,那就必须修改HSE_VALUE的值为当前所用的时钟频率。

所以说,在程序还没执行到SystemClock_Config()函数之前,单片机都是使用内部高速时钟源HSI来作为系统时钟频率的,该HSI的频率会根据单片机的类型不同而有所不同。在执行了SystemClock_Config()函数之后,系统时钟频率便会设置为我们在cubemx中设置的频率。

SystemCoreClock变量

当前系统时钟频率的值保存在了SystemCoreClock全局变量中。可以通过该变量来得到当前系统的运行频率。

在system_stm32f1xx.c文件中,定义了SystemCoreClock变量,如下图。但是初始值给了一个16000000。这个初始值其实并不是一开始的系统运行频率。用户可以通过几种方式来更新该变量的值,更新之后才代表真正的系统运行频率。 img6

更新SystemCoreClock变量的三种方法:

调用SystemCoreClockUpdate()函数。 调用HAL_RCC_GetHCLKFreq()函数。 调用HAL_RCC_ClockConfig()函数。 总结 在system_stm32xx.c文件中,定义了HSI_VALUE和HSE_VALUE两个宏,分别表示该单片机的内部高速时钟频率和外部高速时钟频率,两个值一定要与实际的相对应。 当单片机复位之后,HSI(内部高速时钟,在f1系列为8MHz)会作为系统的时钟源。直到执行了SystemClock_Config()函数,系统时钟频率便会设置为在cubemx中设置的频率。 SystemCoreClock全局变量表示当前系统时钟频率,并不是实时的,需要更新。 SystemCoreClock全局变量会用于配置滴答定时器(SysTick timer)和其他参数。


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有