打印
[STM32F4]

STM32F4时钟设置分析

[复制链接]
805|5
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
powerful1|  楼主 | 2015-3-22 23:28 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

环境:

主机: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函数.

沙发
powerful1|  楼主 | 2015-3-22 23:28 | 只看该作者
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>  



使用特权

评论回复
板凳
powerful1|  楼主 | 2015-3-22 23:29 | 只看该作者
而晶振频率则是在文件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

使用特权

评论回复
地板
powerful1|  楼主 | 2015-3-22 23:29 | 只看该作者
时钟图:

使用特权

评论回复
5
powerful1|  楼主 | 2015-3-22 23:30 | 只看该作者
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>  




使用特权

评论回复
6
powerful1|  楼主 | 2015-3-22 23:30 | 只看该作者
3.SetSysClock函数分析
在SetSysClock函数中,配置了系统时钟,PLL倍频以及分频系数:
[cpp] view plaincopy在CODE上查看代码片派生到我的代码片
<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

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

88

主题

430

帖子

4

粉丝