1.STM32有5个时钟源:HSI、HSE、LSI、LSE、PLL。
①、HSI是高速内部时钟,RC振荡器,频率为16MHz,精度不高。可以直接作为系统时钟或者用作PLL时钟输入。
②、HSE是高速外部时钟,可接石英/陶瓷谐振器,或者接外部时钟源,频率范围为4MHz~26MHz。
③、LSI是低速内部时钟,RC振荡器,频率为32KHz提供低功耗时钟,这要供独立看门狗和自动唤醒单元使用。
④、LSE低速外部时钟,接频率为32.768KHz的石英晶体。RTC。
⑤、PLL为锁相环倍频输出,STM32F4有两个PLL:
⑴主PLL(PLL)由HSE或者HSI提供时钟信号,并具有两个不同的输出时钟。
⒈第一个输出PLLP用于生成高速的系统时钟(最高168MHz)
⒉第二个输出PLLQ用于生成USB OTG FS的时钟(48MHz),随机数发生器的时钟和SDIO时钟
⑵专用PLL(PLLI2S)用于生成精确时钟,从而在I2S接口实现高品质音频性能。
2.系统时钟SYSCLK可来源于三个时钟源:
①、HSI振荡器时钟
②、HSE振荡器时钟
③、PLL时钟
方法一,采用官方库提供的配置(这里外部晶振8MHz,系统配置为168MHz)
STM32F4启动与STM32F10X不同,时钟已经默认配置好
启动代码,文件:startup_stm32f4xx.s方法一,采用官方库提供的配置(这里外部晶振8MHz,系统配置为168MHz)
STM32F4启动与STM32F10X不同,时钟已经默认配置好
启动代码,文件:startup_stm32f4xx.s
Reset_Handler PROC
EXPORT Reset_Handler [WEAK]
IMPORT SystemInit
IMPORT __main
LDR R0, =SystemInit
BLX R0
LDR R0, =__main
BX R0
ENDP
在这里我们可以看出在运行main()函数时先初始化了SystemInit()函数。
SystemInit()函数对RCC各个寄存器的每一个位进行配置。代码如下所示:
void SystemInit(void)
{
/* FPU settings ------------------------------------------------------------*/
#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
SCB->CPACR |= ((3UL << 10*2)|(3UL << 11*2)); /* set CP10 and CP11 Full Access */
#endif
/* Reset the RCC clock configuration to the default reset state ------------*/
/* Set HSION bit */
RCC->CR |= (uint32_t)0x00000001;
/* Reset CFGR register */
RCC->CFGR = 0x00000000;
/* Reset HSEON, CSSON and PLLON bits */
RCC->CR &= (uint32_t)0xFEF6FFFF;
/* Reset PLLCFGR register */
RCC->PLLCFGR = 0x24003010;
/* Reset HSEBYP bit */
RCC->CR &= (uint32_t)0xFFFBFFFF;
/* Disable all interrupts */
RCC->CIR = 0x00000000;
首先如果使用外部时钟源HSE,要配置外部晶振频率:
stm32f4xx.h
#if !defined (HSE_VALUE)
#define HSE_VALUE ((uint32_t)8000000) /*!< Value of the External oscillator in Hz */
#endif /* HSE_VALUE */
如果使用内部时钟源HSI,要配置内部晶振频率:
#if !defined (HSI_VALUE)
#define HSI_VALUE ((uint32_t)16000000) /*!< Value of the Internal oscillator in Hz*/
#endif /* HSI_VALUE */
SystemInit函数分析:SystemInit函数位于system_stm32f4xx.c文件中.此文件提供几个宏定义可以设置各个时钟:
/************************* PLL Parameters *************************************/
#if defined (STM32F40_41xxx) || defined (STM32F427_437xx) || defined (STM32F429_439xx) || defined (STM32F401xx)
/* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLL_M) * PLL_N */
#define PLL_M 8
#else /* STM32F411xE */
#if defined (USE_HSE_BYPASS)
#define PLL_M 8
#else /* STM32F411xE */
#define PLL_M 16
#endif /* USE_HSE_BYPASS */
#endif /* STM32F40_41xxx || STM32F427_437xx || STM32F429_439xx || STM32F401xx */
/* USB OTG FS, SDIO and RNG Clock = PLL_VCO / PLLQ */
#define PLL_Q 7
#if defined (STM32F40_41xxx)
#define PLL_N 336
/* SYSCLK = PLL_VCO / PLL_P */
#define PLL_P 2 //2 //2---168M 4---84M
#endif /* STM32F40_41xxx */
#if defined (STM32F427_437xx) || defined (STM32F429_439xx)
#define PLL_N 360
/* SYSCLK = PLL_VCO / PLL_P */
#define PLL_P 2
#endif /* STM32F427_437x || STM32F429_439xx */
#if defined (STM32F401xx)
#define PLL_N 336
/* SYSCLK = PLL_VCO / PLL_P */
#define PLL_P 4
#endif /* STM32F401xx */
#if defined (STM32F411xE)
#define PLL_N 400
/* SYSCLK = PLL_VCO / PLL_P */
#define PLL_P 4
#endif /* STM32F411xx */
/******************************************************************************/