您的位置:首页 > 其它

STM32F4时钟设置分析

2015-12-09 11:00 309 查看
STM32F4时钟设置分析

本文博客链接:http://blog.csdn.net/jdh99,作者:jdh,转载请注明.

环境:

主机:WIN7

开发环境:MDK4.72

MCU:STM32F407VGT6

STM32F4启动与STM32F10X不同,时钟已经默认配置好.

1.启动代码:

文件:startup_stm32f4xx.s

[cpp] view
plaincopy





<span style="font-family:KaiTi_GB2312;font-size:18px;">; Reset handler  

Reset_Handler    PROC  

                 EXPORT  Reset_Handler             [WEAK]  

        IMPORT  SystemInit  

        IMPORT  __main  

  

                 LDR     R0, =SystemInit  

                 BLX     R0  

                 LDR     R0, =__main  

                 BX      R0  

                 ENDP</span>  

可以看出,在进入main函数之前,系统调用了SystemInit函数.

2.SystemInit函数分析

SystemInit函数位于system_stm32f4xx.c文件中.此文件提供几个宏定义可以设置各个时钟:

[cpp] view
plaincopy





<span style="font-family:KaiTi_GB2312;font-size:18px;">/************************* PLL Parameters *************************************/  

/* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLL_M) * PLL_N */  

#define PLL_M      25  

#define PLL_N      336  

  

/* SYSCLK = PLL_VCO / PLL_P */  

#define PLL_P      2  

  

/* USB OTG FS, SDIO and RNG Clock =  PLL_VCO / PLLQ */  

#define PLL_Q      7  

  

/******************************************************************************/</span>  

而晶振频率则是在文件stm32f4xx.h中进行设置:

外部晶振:

[cpp] view
plaincopy





<span style="font-family:KaiTi_GB2312;font-size:18px;">#if !defined  (HSE_VALUE)   

  #define HSE_VALUE    ((uint32_t)25000000) /*!< Value of the External oscillator in Hz */  

#endif /* HSE_VALUE */</span>  

内部晶振:

[cpp] view
plaincopy





<span style="font-family:KaiTi_GB2312;font-size:18px;">#if !defined  (HSI_VALUE)     

  #define HSI_VALUE    ((uint32_t)16000000) /*!< Value of the Internal oscillator in Hz*/  

#endif /* HSI_VALUE */ </span>  

综上,可以得出默认配置中:

锁相环压腔振荡器时钟PLL_VCO = 25 / 25 * 336 = 336MHz

系统时钟SYSCLK = 336 / 2 = 168MHz

USB,SD卡时钟 = 336 / 7 = 48MHz

时钟图:



SystemInit函数代码:

[cpp] view
plaincopy





<span style="font-family:KaiTi_GB2312;font-size:18px;">/** 

  * @brief  Setup the microcontroller system 

  *         Initialize the Embedded Flash Interface, the PLL and update the  

  *         SystemFrequency variable. 

  * @param  None 

  * @retval None 

  */  

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;  

  

#ifdef DATA_IN_ExtSRAM  

  SystemInit_ExtMemCtl();   

#endif /* DATA_IN_ExtSRAM */  

           

  /* Configure the System clock source, PLL Multiplier and Divider factors,  

     AHB/APBx prescalers and Flash settings ----------------------------------*/  

  SetSysClock();  

  

  /* Configure the Vector Table location add offset address ------------------*/  

#ifdef VECT_TAB_SRAM  

  SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM */  

#else  

  SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH */  

#endif  

}</span>  

3.SetSysClock函数分析
在SetSysClock函数中,配置了系统时钟,PLL倍频以及分频系数:

[cpp] view
plaincopy





<span style="font-family:KaiTi_GB2312;font-size:18px;">/** 

  * @brief  Configures the System clock source, PLL Multiplier and Divider factors,  

  *         AHB/APBx prescalers and Flash settings 

  * @Note   This function should be called only once the RCC clock configuration   

  *         is reset to the default reset state (done in SystemInit() function).    

  * @param  None 

  * @retval None 

  */  

static void SetSysClock(void)  

{  

/******************************************************************************/  

/*            PLL (clocked by HSE) used as System clock source                */  

/******************************************************************************/  

  __IO uint32_t StartUpCounter = 0, HSEStatus = 0;  

    

  /* Enable HSE */  

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

   

  /* Wait till HSE is ready and if Time out is reached exit */  

  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)  

  {  

    /* Select regulator voltage output Scale 1 mode, System frequency up to 168 MHz */  

    RCC->APB1ENR |= RCC_APB1ENR_PWREN;  

    PWR->CR |= PWR_CR_VOS;  

  

    /* HCLK = SYSCLK / 1*/  

    RCC->CFGR |= RCC_CFGR_HPRE_DIV1;  

        

    /* PCLK2 = HCLK / 2*/  

    RCC->CFGR |= RCC_CFGR_PPRE2_DIV2;  

      

    /* PCLK1 = HCLK / 4*/  

    RCC->CFGR |= RCC_CFGR_PPRE1_DIV4;  

  

    /* Configure the main PLL */  

    RCC->PLLCFGR = PLL_M | (PLL_N << 6) | (((PLL_P >> 1) -1) << 16) |  

                   (RCC_PLLCFGR_PLLSRC_HSE) | (PLL_Q << 24);  

  

    /* Enable the main PLL */  

    RCC->CR |= RCC_CR_PLLON;  

  

    /* Wait till the main PLL is ready */  

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

    {  

    }  

     

    /* Configure Flash prefetch, Instruction cache, Data cache and wait state */  

    FLASH->ACR = FLASH_ACR_ICEN |FLASH_ACR_DCEN |FLASH_ACR_LATENCY_5WS;  

  

    /* Select the main PLL as system clock source */  

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

    RCC->CFGR |= RCC_CFGR_SW_PLL;  

  

    /* Wait till the main PLL is used as system clock source */  

    while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS ) != RCC_CFGR_SWS_PLL);  

    {  

    }  

  }  

  else  

  { /* If HSE fails to start-up, the application will have wrong clock 

         configuration. User can add here some code to deal with this error */  

  }  

  

}</span>  

如果外部时钟启动失败,系统会使用内部时钟

默认配置:

HCLK = SYSCLK / 1 = 168MHz

PCLK2 = HCLK / 2 = 84MHz

PCLK1 = HCLK / 4 = 42MHz
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: