STM32时钟树总结和时钟配置 您所在的位置:网站首页 DDR速率和时钟锁相环 STM32时钟树总结和时钟配置

STM32时钟树总结和时钟配置

2024-06-19 06:57| 来源: 网络整理| 查看: 265

总结STM32时钟树和时钟配置 预习:

(1)5到6个时钟源,HSI、HSE、LSI、LSE、MSI、PLL(细分为主PLL、PLLI2S和PLLSAI)。 (2)LSI频率为32KHz左右,仅供看门狗和RTC使用。 (3)LSE频率为32.768KHz,作为RTC的时钟源。 (4)HSE:OSC_OUT和OSC_IN引脚接4~26MHz的晶振。 (5)HSI是高速内部RC振荡器,频率16MHz。 (6)MSI(暂时看到它出现在低功耗单片机里),时钟信号由内部RC振荡器产生。其频率范围可以由时钟控制寄存器(RCC_CR)调整。 (7)主PLL的时钟源可以是:1.HSE;2.HSI(;3.MSI)

问题:

1.Sysclk、PLLCLK、PCLK1、PCLK2、HCLK、AHB、APB1、APB2的关系? 2.如何配置完成自己想要的系统时钟? 在这里插入图片描述 上图是STM32L475的时钟树主PLL部分,从上图可以知道PLL有3个时钟源,通过分频因子M后再经过倍频xN后求出PLL时钟,PLL有3个通道,每条通道都有一个“弱化门”将输出时钟降频(分频)。我们经常使用到的是PLLCLK,用它来做系统时钟源。比如选择HSE8MHz,M为1,N为20,R为2,那么根据该时钟树可以得到PLLCLK = 80MHz。再看看CubeMX的时钟配置图: 在这里插入图片描述 前面得到了PLLCLK,那么根据上面显示的时钟树,就可以知道SYSCLK,HCLK(AHB),APB1(PCLK1),APB2(PCLK2)等的时钟频率。可以说是,先有SYSCLK,后有HCLK,以及再下一级的一些外设时钟总线(AHB、APB1、APB2等)。

了解SYSCLK、PLLCLK、PCLK1、PCLK2、HCLK、AHB、APB1、APB2的关系后,那么如何通过软件配置时钟呢?

对于低功耗单片机,启动文件会在执行main函数之前先执行SystemInit函数,该函数默认配置MSI为系统时钟;对于F系列单片机,启动文件先执行SystemInit函数配置HSI为系统时钟。但是往往默认的系统时钟不是我们想要的,这时就要配置相关寄存器修改系统时钟了。

HAL库版本:

HAL库用以下4个函数来配置系统时钟: 1.用来使能PWR时钟 __HAL_RCC_PWR_CLK_ENABLE(); 2.设置调压器输出电压级别 HAL_StatusTypeDef HAL_PWREx_ControlVoltageScaling(uint32_t VoltageScaling); 3.用来打开/关闭PLL和配置PLL的时钟源以及相关参数,比如M、N、P、Q、R HAL_StatusTypeDef HAL_RCC_OscConfig(RCC_OscInitTypeDef *RCC_OscInitStruct); 4.用来确定系统时钟以及外设总线时钟 HAL_StatusTypeDef HAL_RCC_ClockConfig(RCC_ClkInitTypeDef *RCC_ClkInitStruct, uint32_t FLatency);

若想设置系统的时钟为80MHz,那么在设置调压器的时候,设置成Vcore Range1,同时第四个函数的第二个入口参数等待周期要设置成4WS。规范要求如下图所示。 在这里插入图片描述

函数如下:(做笔记,方便以后开发使用) void SystemClock_Config(void) { HAL_StatusTypeDef ret = HAL_OK; RCC_OscInitTypeDef RCC_OscInitStruct; RCC_ClkInitTypeDef RCC_ClkInitStruct;__HAL_RCC_PWR_CLK_ENABLE(); //使能PWR时钟 /*Configure the main internal regulator output voltage*/ ret = HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1);//设置调压器输出电压级别为range1 if(ret != HAL_OK) while(1); /*Initializes the CPU, AHB and APB busses clocks*/ RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;//使用HSE RCC_OscInitStruct.HSEState = RCC_HSE_ON;//打开 RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;//锁相环打开 RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;//锁相环选择HSE RCC_OscInitStruct.PLL.PLLM = 1;//(8/1) RCC_OscInitStruct.PLL.PLLN = 20;//((8/1)*20) RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV7; RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV2; RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV2;//((8/1)*20)/2 ret = HAL_RCC_OscConfig(&RCC_OscInitStruct); if(ret != HAL_OK) while(1); /*Initializes the CPU, AHB and APB busses clocks*/ RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2; RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;//80MHz RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;//80MHz RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;//80MHz RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;//40MHz ret = HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_4); if(ret != HAL_OK) while(1); }

主程序调用该函数即可配置系统时钟为80MHz,当然还配置了APB1,APB2,AHB。

标准库版本:

相比HAL库,标准库版本的系统初始化SystemInit()函数多了个设置时钟频率的函数SetSysClock(void),里面用条件编译的方式选择系统的时钟频率,比如下面的F103的SetSysClock:

/** * @brief Configures the System clock frequency, HCLK, PCLK2 and PCLK1 prescalers. * @param None * @retval None */ static void SetSysClock(void) { #ifdef SYSCLK_FREQ_HSE SetSysClockToHSE(); #elif defined SYSCLK_FREQ_24MHz SetSysClockTo24(); #elif defined SYSCLK_FREQ_36MHz SetSysClockTo36(); #elif defined SYSCLK_FREQ_48MHz SetSysClockTo48(); #elif defined SYSCLK_FREQ_56MHz SetSysClockTo56(); #elif defined SYSCLK_FREQ_72MHz SetSysClockTo72(); #endif /* If none of the define above is enabled, the HSI is used as System clock source (default after reset) */ }

假设要求F103单片机工作在72MHz的时钟频率,就声明SYSCLK_FREQ_72MHz即可,主程序不用重复调用SystemInit()函数来设置系统时钟频率。



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

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