//学习STM32F4的过程中关于时钟上面讲的比较好 特地转发与大家分享
 
STM32F4时钟设置分析
 
 
原文博客链接:http://blog.csdn.net/jdh99,作者:jdh,转载请注明.
 
 
环境:
主机:WIN7
开发环境:MDK4.72
MCU:STM32F407VGT6
 
STM32F4启动与STM32F10X不同,时钟已经默认配置好.
1.启动代码:
文件:startup_stm32f4xx.s
 
- <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文件中.此文件提供几个宏定义可以设置各个时钟:
 
- <span style="font-family:KaiTi_GB2312;font-size:18px;">
- #define PLL_M      25  
- #define PLL_N      336  
-   
- #define PLL_P      2  
-   
- #define PLL_Q      7  
-   
 
而晶振频率则是在文件stm32f4xx.h中进行设置:
 
外部晶振:
 
- <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>  
 
内部晶振:
 
 
- <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函数代码:
 
- <span style="font-family:KaiTi_GB2312;font-size:18px;">
- void SystemInit(void)  
- {  
-   
-   #if (__FPU_PRESENT == 1) && (__FPU_USED == 1)  
-     SCB->CPACR |= ((3UL << 10*2)|(3UL << 11*2));  
-   #endif  
-   
-   
-   
-   RCC->CR |= (uint32_t)0x00000001;  
-   
-   
-   RCC->CFGR = 0x00000000;  
-   
-   
-   RCC->CR &= (uint32_t)0xFEF6FFFF;  
-   
-   
-   RCC->PLLCFGR = 0x24003010;  
-   
-   
-   RCC->CR &= (uint32_t)0xFFFBFFFF;  
-   
-   
-   RCC->CIR = 0x00000000;  
-   
- #ifdef DATA_IN_ExtSRAM  
-   SystemInit_ExtMemCtl();   
- #endif /* DATA_IN_ExtSRAM */  
-            
-   
-   SetSysClock();  
-   
-   
- #ifdef VECT_TAB_SRAM  
-   SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; 
- #else  
-   SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; 
- #endif  
- }</span>  
 
 
 
3.SetSysClock函数分析
在SetSysClock函数中,配置了系统时钟,PLL倍频以及分频系数:
 
- <span style="font-family:KaiTi_GB2312;font-size:18px;">
- static void SetSysClock(void)  
- {  
-   __IO uint32_t StartUpCounter = 0, HSEStatus = 0;  
-     
-   
-   RCC->CR |= ((uint32_t)RCC_CR_HSEON);  
-    
-   
-   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)  
-   {  
-     
-     RCC->APB1ENR |= RCC_APB1ENR_PWREN;  
-     PWR->CR |= PWR_CR_VOS;  
-   
-     
-     RCC->CFGR |= RCC_CFGR_HPRE_DIV1;  
-         
-     
-     RCC->CFGR |= RCC_CFGR_PPRE2_DIV2;  
-       
-     
-     RCC->CFGR |= RCC_CFGR_PPRE1_DIV4;  
-   
-     
-     RCC->PLLCFGR = PLL_M | (PLL_N << 6) | (((PLL_P >> 1) -1) << 16) |  
-                    (RCC_PLLCFGR_PLLSRC_HSE) | (PLL_Q << 24);  
-   
-     
-     RCC->CR |= RCC_CR_PLLON;  
-   
-     
-     while((RCC->CR & RCC_CR_PLLRDY) == 0)  
-     {  
-     }  
-      
-     
-     FLASH->ACR = FLASH_ACR_ICEN |FLASH_ACR_DCEN |FLASH_ACR_LATENCY_5WS;  
-   
-     
-     RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));  
-     RCC->CFGR |= RCC_CFGR_SW_PLL;  
-   
-     
-     while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS ) != RCC_CFGR_SWS_PLL);  
-     {  
-     }  
-   }  
-   else  
-   { 
-   }  
-   
- }</span>  
 
如果外部时钟启动失败,系统会使用内部时钟
 
默认配置:
HCLK = SYSCLK / 1 = 168MHz
PCLK2 = HCLK / 2 = 84MHz
PCLK1 = HCLK / 4 = 42MHz
STM32F4时钟配置分析
原文:http://www.cnblogs.com/Belye/p/5335559.html