STM32F4如何設(shè)置系統(tǒng)時(shí)鐘
STM32F4系統(tǒng)時(shí)鐘樹
STM32F4的系統(tǒng)時(shí)鐘非常重要,涉及到整個(gè)系統(tǒng)的運(yùn)行結(jié)果,無論是什么操作,都需要時(shí)鐘信號(hào),不同型號(hào)的微控制器的默認(rèn)系統(tǒng)時(shí)鐘配置是不同的,這里,給出兩種配置STM32F407系統(tǒng)時(shí)鐘的方法。方法一,采用官方庫提供的配置(這里外部晶振8MHz,系統(tǒng)配置為168MHz)
STM32F4啟動(dòng)與STM32F10X不同,時(shí)鐘已經(jīng)默認(rèn)配置好
啟動(dòng)代碼,文件:startup_stm32f4xx.s
Reset_HandlerPROC
EXPORTReset_Handler[WEAK]
IMPORTSystemInit
IMPORT__main
LDRR0,=SystemInit
BLXR0
LDRR0,=__main
BXR0
ENDP
可以看出,在進(jìn)入main函數(shù)之前,系統(tǒng)調(diào)用了SystemInit函數(shù).
SystemInit函數(shù)分析:SystemInit函數(shù)位于system_stm32f4xx.c文件中.此文件提供幾個(gè)宏定義可以設(shè)置各個(gè)時(shí)鐘:
/*************************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中進(jìn)行設(shè)置:
外部晶振:
#if!defined(HSE_VALUE)
#defineHSE_VALUE((uint32_t)8000000)/*!
#endif/*HSE_VALUE*/
內(nèi)部晶振:
[cpp]view plaincopy
#if!defined(HSI_VALUE)
#defineHSI_VALUE((uint32_t)16000000)/*!
#endif/*HSI_VALUE*/
綜上,如果使用外部晶振8MHz,則可以得出默認(rèn)配置中:
鎖相環(huán)壓腔振蕩器時(shí)鐘PLL_VCO =(HSE_VALUE/PLL_M)*PLL_N=8/ 8* 336 = 336MHz
系統(tǒng)時(shí)鐘SYSCLK = PLL_VCO / PLL_P=336 / 2 = 168MHz
USB,SD卡時(shí)鐘 = PLL_VCO / PLLQ=336 / 7 = 48MHz
SystemInit函數(shù)代碼:
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函數(shù)分析,在SetSysClock函數(shù)中,配置了系統(tǒng)時(shí)鐘,PLL倍頻以及分頻系數(shù):
staticvoidSetSysClock(void)
{
/******************************************************************************/
/* PLL (clocked by HSE) used as System clock source */