STM32 时钟配置

来源:本站
导读:目前正在解读《STM32 时钟配置》的相关信息,《STM32 时钟配置》是由用户自行发布的知识型内容!下面请观看由(电工技术网 - www.9ddd.net)用户发布《STM32 时钟配置》的详细说明。
简介:STM32 时钟配置有2种方式:第一使用库自带的SystemInit();函数自动配置;第二种:通过stm32f10x_rcc.c文件里的函数配置。工作频率的选取根据所使用的芯片型号来确定,然后在system_stm32f10x.c函数中定义选取,如下选择的为工作频率36MHz。

STM32 时钟配置有2种方式:第一使用库自带的SystemInit();函数自动配置;第二种:通过stm32f10x_rcc.c文件里的函数配置,比如RCC_HCLKConfig(uint32_t RCC_SYSCLK),RCC_PCLK1Config(uint32_t RCC_HCLK),RCC_PCLK2Config(uint32_t RCC_HCLK);这种方式可以根据自己需要把HCLK、PLCK1、PLCK2配置成不同的数值。第一种方式中SystemInit()这个函数直接把SYSCLK 来源配置为PLLCK ,PCLK1=PCLK2=HCLK=SYSCLK。PLLCK 时钟来源为外部高速晶振,具体分频关系为HSE/2然后乘以倍频系数(PLLMUL),比如外部晶振为8MHZ,设置工作频率为36MHz,则PLLCK=(HSE(8)/2)*9=36MHz。工作频率的选取根据所使用的芯片型号来确定,然后在system_stm32f10x.c函数中定义选取,如下选择的为工作频率36MHz。

#if defined (STM32F10X_LD_VL) || (defined STM32F10X_MD_VL) || (defined STM32F10X_HD_VL)

#define SYSCLK_FREQ_24MHz 24000000

#else

#define SYSCLK_FREQ_36MHz 36000000// 选择系统工作频率为36MHz

#endif

注意在V3.5.0以上的库文件里SystemInit()函数已经被添加入启动文件中了,也就是库已经自动配置好了 HCLK(AHB总线)、PLCK1(APB1)、PLCK2(APB2)这几个总线的时钟频率,一般在36MHz以下的工作频率 HCLK=PLCK1=PLCK2=用户选择的工作频率,在超过36MHz的工作频率HCLK=PLCK2=用户选择的频率,而PCKL1因为是低速总线最大只能到36MHz,所以库自动设置PCLK=36MHz。

在V3.5.0以下的库中,通常在自己写的时钟配置使能函数里加入SystemInit(),比如我自己用的RCC_Configuration(void)如下:

void RCC_Configuration(void)

{

SystemInit();//初始化系统时钟

RCC_ADCCLKConfig(RCC_PCLK2_Div4); //设置ADC 的工作频率为9M

RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3| RCC_APB1Periph_TIM2, ENABLE);

RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA |RCC_APB2Periph_AFIO, ENABLE);

RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);

RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);

RCC_ClockSecuritySystemCmd(ENABLE);

}

下面是从一处论坛截取的例程,配置时钟为72MHz,使用CPU为STM32F107VC

我已经定义了STM32F10X_CL,SYSCLK_FREQ_72MHz

函数调用顺序:

startup_stm32f10x_cl.s(启动文件) → SystemInit() →SetSysClock () → SetSysClockTo72()

初始化时钟用到的RCC寄存器复位值:

RCC_CR = 0x0000 xx83; RCC_CFGR = 0x0000 0000;RCC_CIR = 0x0000 0000; RCC_CFGR2 = 0x0000 0000;

SystemInit()

在调用 SetSysClock()之前RCC寄存器的值如下(都是一些与运算,或运算,在此就不赘述了):

RCC->CR = 0x0000 0083;RCC->CIR = 0x00FF0000; RCC->CFGR2 = 0x00000000;至于这些寄存器都代表着什么意思,详见芯片资料RCC寄存器,该文重点不在此处;

SetSysClock()函数如下:

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 //我的定义的是SYSCLK_FREQ_72MHz,所以调用SetSysClockTo72()

SetSysClockTo72();

#endif

}

SetSysClockTo72()函数如下:

static void SetSysClockTo72(void)

{

__IO uint32_t StartUpCounter = 0, HSEStatus = 0;

RCC->CR = ((uint32_t)RCC_CR_HSEON);

do

{

HSEStatus = RCC->CR & RCC_CR_HSERDY;

StartUpCounter ;

} while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));

if ((RCC->CR & RCC_CR_HSERDY) != RESET)

{

HSEStatus = (uint32_t)0x01;

}

else

{

HSEStatus = (uint32_t)0x00;

}

if (HSEStatus == (uint32_t)0x01)

{

FLASH->ACR = FLASH_ACR_PRFTBE;

FLASH->ACR &= (uint32_t)((uint32_t)~FLASH_ACR_LATENCY);

FLASH->ACR = (uint32_t)FLASH_ACR_LATENCY_2;

RCC->CFGR = (uint32_t)RCC_CFGR_HPRE_DIV1;

RCC->CFGR = (uint32_t)RCC_CFGR_PPRE2_DIV1;

RCC->CFGR = (uint32_t)RCC_CFGR_PPRE1_DIV2;

#ifdef STM32F10X_CL

RCC->CFGR2 &= (uint32_t)~(RCC_CFGR2_PREDIV2 RCC_CFGR2_PLL2MUL

RCC_CFGR2_PREDIV1 RCC_CFGR2_PREDIV1SRC);

RCC->CFGR2 = (uint32_t)(RCC_CFGR2_PREDIV2_DIV5 RCC_CFGR2_PLL2MUL8

RCC_CFGR2_PREDIV1SRC_PLL2 RCC_CFGR2_PREDIV1_DIV5);

RCC->CR = RCC_CR_PLL2ON;

while((RCC->CR & RCC_CR_PLL2RDY) == 0)

{

}

RCC->CFGR &= (uint32_t)~(RCC_CFGR_PLLXTPRE RCC_CFGR_PLLSRC RCC_CFGR_PLLMULL);

RCC->CFGR = (uint32_t)(RCC_CFGR_PLLXTPRE_PREDIV1 RCC_CFGR_PLLSRC_PREDIV1

RCC_CFGR_PLLMULL9);

#else

RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC RCC_CFGR_PLLXTPRE

RCC_CFGR_PLLMULL));

RCC->CFGR = (uint32_t)(RCC_CFGR_PLLSRC_HSE RCC_CFGR_PLLMULL9);

#endif

RCC->CR = RCC_CR_PLLON;

while((RCC->CR & RCC_CR_PLLRDY) == 0)

{

}

RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));

RCC->CFGR = (uint32_t)RCC_CFGR_SW_PLL;

while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)0x08)

{

}

}

else

{

}

}

1:AHB, APB1,APB2时钟确定

//HCLK = SYSCLK ,从下面的分析可以得出SYSCLK是使用PLLCLK时钟的,也就是72MHZ(至于72MHZ如何得来,请看下面分析)

//那么就是HCLK(AHB总线时钟)=PLLCLK = 72MHZ

//AHB总线时钟等于系统时钟SYSCLK,也就是 AHB时钟 = HCLK = SYSCLK = 72MHZ

RCC->CFGR = (uint32_t)RCC_CFGR_HPRE_DIV1;

//PLCK2等于HCLK一分频, 所以PCLK2 = HCLK,HCLK = 72MHZ, 那么PLCK2(APB2总线时钟) = 72MHZ

//APB2总线时钟等于HCLK的一分频,也就是不分频;APB2 时钟 = HCLK = SYSCLK = 72MHZ

RCC->CFGR = (uint32_t)RCC_CFGR_PPRE2_DIV1;

//PCLK1 = HCLK / 2;PCLK1 等于HCLK时钟的二分频,那么PCLK1(APB1) = 72MHZ / 2 = 36MHZ

//APB1总线时钟等于HCLK的二分频,也就是 APB1时钟= HCLK / 2 = 36MHZ

RCC->CFGR = (uint32_t)RCC_CFGR_PPRE1_DIV2;

2:如何得出SYSCLK(系统时钟)为72MHZ(外部晶振25MHZ)

//记得参考英文芯片资料的时钟树P115页和RCC时钟寄存器进行理解

RCC->CFGR2 = (uint32_t)(RCC_CFGR2_PREDIV2_DIV5 RCC_CFGR2_PLL2MUL8 RCC_CFGR2_PREDIV1SRC_PLL2 RCC_CFGR2_PREDIV1_DIV5);

RCC_CFGR2_PREDIV2_DIV5:PREDIV2 = 5; 5分频

也就是PREDIV2对输入的外部时钟 5分频,那么PLL2和PLL3没有倍频前是25 /5 = 5MHZ

RCC_CFGR2_PLL2MUL8: PLL2MUL = 8; 8倍频

8倍频后,PLL2时钟 = 5 * 8 = 40MHZ; 因此 PLL2CLK = 40MHZ

RCC_CFGR2_PREDIV1SRC_PLL2 : RCC_CFGR2的第16位为1,选择PLL2CLK 作为PREDIV1的时钟源

RCC_CFGR2_PREDIV1_DIV5:PREDIV1 = 5;PREDIV1对输入时钟5分频 PREDIV1CLK = PLL2CLK / 5 = 8MHZ

以上是对RCC_CFGR2进行的配置

--------------------------------------------------------------------------------------

RCC->CFGR = (uint32_t)(RCC_CFGR_PLLXTPRE_PREDIV1 RCC_CFGR_PLLSRC_PREDIV1

RCC_CFGR_PLLMULL9);

RCC_CFGR_PLLXTPRE_PREDIV1 :操作的是RCC_CFGR的第17位PLLXTPRE,操作这一位和操作RCC_CFGR2寄存器的位[3:0]中的最低位是相同的效果

RCC_CFGR_PLLSRC_PREDIV1 :选择PREDIV1输出作为PLL输入时钟;PREDIV1CLK = 8MHZ,所以输入给PLL倍频的 时钟源是8MHZ

RCC_CFGR_PLLMULL9 :PLLMUL = 9;PLL倍频系数为9,也就是对 PLLCLK = PREDIV1CLK * 8 = 72MHZ

以上是对RCC_CFGR进行的配置

---------------------------------------------------------------------------------------------------

RCC->CFGR = (uint32_t)RCC_CFGR_SW_PLL;//选择PLLCLK作为系统时钟源

--------------------------------------------------------------------------------------------------

至此基本配置已经完成,配置的时钟如下所述:

SYSCLK(系统时钟) = 72MHZ

AHB总线时钟= 72MHZ

APB1总线时钟= 36MHZ

APB2总线时钟= 72MHZ

PLL时钟= 72MHZ

PLL2时钟= 40MHZ

提醒:《STM32 时钟配置》最后刷新时间 2024-03-14 01:09:43,本站为公益型个人网站,仅供个人学习和记录信息,不进行任何商业性质的盈利。如果内容、图片资源失效或内容涉及侵权,请反馈至,我们会及时处理。本站只保证内容的可读性,无法保证真实性,《STM32 时钟配置》该内容的真实性请自行鉴别。