标签:
//学习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