STM32F4如何设置系统时钟
扫描二维码
随时随地手机看文章
STM32F4系统时钟树
STM32F4的系统时钟非常重要,涉及到整个系统的运行结果,无论是什么操作,都需要时钟信号,不同型号的微控制器的默认系统时钟配置是不同的,这里,给出两种配置STM32F407系统时钟的方法。方法一,采用官方库提供的配置(这里外部晶振8MHz,系统配置为168MHz)
STM32F4启动与STM32F10X不同,时钟已经默认配置好
启动代码,文件:startup_stm32f4xx.s
Reset_HandlerPROC
EXPORTReset_Handler[WEAK]
IMPORTSystemInit
IMPORT__main
LDRR0,=SystemInit
BLXR0
LDRR0,=__main
BXR0
ENDP
可以看出,在进入main函数之前,系统调用了SystemInit函数.
SystemInit函数分析:SystemInit函数位于system_stm32f4xx.c文件中.此文件提供几个宏定义可以设置各个时钟:
/*************************PLLParameters*************************************/
#ifdefined(STM32F40_41xxx)||defined(STM32F427_437xx)||defined(STM32F429_439xx)||defined(STM32F401xx)
/*PLL_VCO=(HSE_VALUEorHSI_VALUE/PLL_M)*PLL_N*/
#definePLL_M8
#else/*STM32F411xE*/
#ifdefined(USE_HSE_BYPASS)
#definePLL_M8
#else/*STM32F411xE*/
#definePLL_M16
#endif/*USE_HSE_BYPASS*/
#endif/*STM32F40_41xxx||STM32F427_437xx||STM32F429_439xx||STM32F401xx*/
/*USBOTGFS,SDIOandRNGClock=PLL_VCO/PLLQ*/
#definePLL_Q7
#ifdefined(STM32F40_41xxx)
#definePLL_N336
/*SYSCLK=PLL_VCO/PLL_P*/
#definePLL_P2//2//2---168M4---84M
#endif/*STM32F40_41xxx*/
#ifdefined(STM32F427_437xx)||defined(STM32F429_439xx)
#definePLL_N360
/*SYSCLK=PLL_VCO/PLL_P*/
#definePLL_P2
#endif/*STM32F427_437x||STM32F429_439xx*/
#ifdefined(STM32F401xx)
#definePLL_N336
/*SYSCLK=PLL_VCO/PLL_P*/
#definePLL_P4
#endif/*STM32F401xx*/
#ifdefined(STM32F411xE)
#definePLL_N400
/*SYSCLK=PLL_VCO/PLL_P*/
#definePLL_P4
#endif/*STM32F411xx*/
/******************************************************************************/
我使用的是STM32F407,筛选可用信息如下:
/*************************PLLParameters*************************************/
/*PLL_VCO=(HSE_VALUEorHSI_VALUE/PLL_M)*PLL_N*/
#definePLL_M8
#definePLL_N336
/*SYSCLK=PLL_VCO/PLL_P*/
#definePLL_P2
/*USBOTGFS,SDIOandRNGClock=PLL_VCO/PLLQ*/
#definePLL_Q7
/******************************************************************************/
而晶振频率则是在文件stm32f4xx.h中进行设置:
外部晶振:
#if!defined(HSE_VALUE)
#defineHSE_VALUE((uint32_t)8000000)/*!
#endif/*HSE_VALUE*/
内部晶振:
[cpp]view plaincopy
#if!defined(HSI_VALUE)
#defineHSI_VALUE((uint32_t)16000000)/*!
#endif/*HSI_VALUE*/
综上,如果使用外部晶振8MHz,则可以得出默认配置中:
锁相环压腔振荡器时钟PLL_VCO =(HSE_VALUE/PLL_M)*PLL_N=8/ 8* 336 = 336MHz
系统时钟SYSCLK = PLL_VCO / PLL_P=336 / 2 = 168MHz
USB,SD卡时钟 = PLL_VCO / PLLQ=336 / 7 = 48MHz
SystemInit函数代码:
voidSystemInit(void)
{
/*FPUsettings------------------------------------------------------------*/
#if(__FPU_PRESENT==1)&&(__FPU_USED==1)
SCB->CPACR|=((3UL<<10*2)|(3UL<<11*2));/*setCP10andCP11FullAccess*/
#endif
/*ResettheRCCclockconfigurationtothedefaultresetstate------------*/
/*SetHSIONbit*/
RCC->CR|=(uint32_t)0x00000001;
/*ResetCFGRregister*/
RCC->CFGR=0x00000000;
/*ResetHSEON,CSSONandPLLONbits*/
RCC->CR&=(uint32_t)0xFEF6FFFF;
/*ResetPLLCFGRregister*/
RCC->PLLCFGR=0x24003010;
/*ResetHSEBYPbit*/
RCC->CR&=(uint32_t)0xFFFBFFFF;
/*Disableallinterrupts*/
RCC->CIR=0x00000000;
#ifdefined(DATA_IN_ExtSRAM)||defined(DATA_IN_ExtSDRAM)
SystemInit_ExtMemCtl();
#endif/*DATA_IN_ExtSRAM||DATA_IN_ExtSDRAM*/
/*ConfiguretheSystemclocksource,PLLMultiplierandDividerfactors,
AHB/APBxprescalersandFlashsettings----------------------------------*/
SetSysClock();
/*ConfiguretheVectorTablelocationaddoffsetaddress------------------*/
#ifdefVECT_TAB_SRAM
SCB->VTOR=SRAM_BASE|VECT_TAB_OFFSET;/*VectorTableRelocationinInternalSRAM*/
#else
SCB->VTOR=FLASH_BASE|VECT_TAB_OFFSET;/*VectorTableRelocationinInternalFLASH*/
#endif
}
SetSysClock函数分析,在SetSysClock函数中,配置了系统时钟,PLL倍频以及分频系数:
staticvoidSetSysClock(void)
{
/******************************************************************************/
/* PLL (clocked by HSE) used as System clock source */