当前位置:   article > 正文

STM32F4如何设置系统时钟,非常重要_stm32f4时钟配置

stm32f4时钟配置

 

 

STM32F4的系统时钟非常重要,涉及到整个系统的运行结果,无论是什么操作,都需要时钟信号,不同型号的微控制器的默认系统时钟配置是不同的,这里,给出两种配置STM32F407系统时钟的方法。

方法一,采用官方库提供的配置(这里外部晶振8MHz,系统配置为168MHz)

  • STM32F4启动与STM32F10X不同,时钟已经默认配置好
  • 启动代码,文件:startup_stm32f4xx.s
  1. Reset_Handler PROC
  2. EXPORT Reset_Handler [WEAK]
  3. IMPORT SystemInit
  4. IMPORT __main
  5. LDR R0, =SystemInit
  6. BLX R0
  7. LDR R0, =__main
  8. BX R0
  9. ENDP

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

  • SystemInit函数分析:SystemInit函数位于system_stm32f4xx.c文件中.此文件提供几个宏定义可以设置各个时钟:
 
  1. /************************* PLL Parameters *************************************/
  2. #if defined (STM32F40_41xxx) || defined (STM32F427_437xx) || defined (STM32F429_439xx) || defined (STM32F401xx)
  3. /* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLL_M) * PLL_N */
  4. #define PLL_M      8
  5. #else /* STM32F411xE */
  6. #if defined (USE_HSE_BYPASS)
  7. #define PLL_M      8    
  8. #else /* STM32F411xE */   
  9. #define PLL_M      16
  10. #endif /* USE_HSE_BYPASS */
  11. #endif /* STM32F40_41xxx || STM32F427_437xx || STM32F429_439xx || STM32F401xx */  
  12. /* USB OTG FS, SDIO and RNG Clock =  PLL_VCO / PLLQ */
  13. #define PLL_Q      7
  14. #if defined (STM32F40_41xxx)
  15. #define PLL_N      336
  16. /* SYSCLK = PLL_VCO / PLL_P */
  17. #define PLL_P      2  //2            //2---168M   4---84M
  18. #endif /* STM32F40_41xxx */
  19. #if defined (STM32F427_437xx) || defined (STM32F429_439xx)
  20. #define PLL_N      360
  21. /* SYSCLK = PLL_VCO / PLL_P */
  22. #define PLL_P      2
  23. #endif /* STM32F427_437x || STM32F429_439xx */
  24. #if defined (STM32F401xx)
  25. #define PLL_N      336
  26. /* SYSCLK = PLL_VCO / PLL_P */
  27. #define PLL_P      4
  28. #endif /* STM32F401xx */
  29. #if defined (STM32F411xE)
  30. #define PLL_N      400
  31. /* SYSCLK = PLL_VCO / PLL_P */
  32. #define PLL_P      4   
  33. #endif /* STM32F411xx */
  34. /******************************************************************************/
我使用的是STM32F407,筛选可用信息如下:

 

 

  1. /************************* PLL Parameters *************************************/
  2. /* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLL_M) * PLL_N */
  3. #define PLL_M 8
  4. #define PLL_N 336
  5. /* SYSCLK = PLL_VCO / PLL_P */
  6. #define PLL_P 2
  7. /* USB OTG FS, SDIO and RNG Clock = PLL_VCO / PLLQ */
  8. #define PLL_Q 7
  9. /******************************************************************************/

 

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

  • 外部晶振:

  1. #if !defined (HSE_VALUE)
  2. #define HSE_VALUE ((uint32_t)8000000) /*!< Value of the External oscillator in Hz */
  3. #endif /* HSE_VALUE */
  • 内部晶振:
  1. #if !defined (HSI_VALUE)
  2. #define HSI_VALUE ((uint32_t)16000000) /*!< Value of the Internal oscillator in Hz*/
  3. #endif /* HSI_VALUE */

 

 

 

综上,如果使用外部晶振8MHz,则可以得出默认配置中: 

 

锁相环压腔振荡器时钟PLL_VCO =(HSE_VALUE/PLL_M)* PLL_N=8/ 8* 336 = 336MHz 

 

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

 

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

 

 

  • SystemInit函数代码:
  1. void SystemInit(void)
  2. {
  3. /* FPU settings ------------------------------------------------------------*/
  4. #if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
  5. SCB->CPACR |= ((3UL << 10*2)|(3UL << 11*2)); /* set CP10 and CP11 Full Access */
  6. #endif
  7. /* Reset the RCC clock configuration to the default reset state ------------*/
  8. /* Set HSION bit */
  9. RCC->CR |= (uint32_t)0x00000001;
  10. /* Reset CFGR register */
  11. RCC->CFGR = 0x00000000;
  12. /* Reset HSEON, CSSON and PLLON bits */
  13. RCC->CR &= (uint32_t)0xFEF6FFFF;
  14. /* Reset PLLCFGR register */
  15. RCC->PLLCFGR = 0x24003010;
  16. /* Reset HSEBYP bit */
  17. RCC->CR &= (uint32_t)0xFFFBFFFF;
  18. /* Disable all interrupts */
  19. RCC->CIR = 0x00000000;
  20. #if defined (DATA_IN_ExtSRAM) || defined (DATA_IN_ExtSDRAM)
  21. SystemInit_ExtMemCtl();
  22. #endif /* DATA_IN_ExtSRAM || DATA_IN_ExtSDRAM */
  23. /* Configure the System clock source, PLL Multiplier and Divider factors,
  24. AHB/APBx prescalers and Flash settings ----------------------------------*/
  25. SetSysClock();
  26. /* Configure the Vector Table location add offset address ------------------*/
  27. #ifdef VECT_TAB_SRAM
  28. SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM */
  29. #else
  30. SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH */
  31. #endif
  32. }
  • SetSysClock函数分析,在SetSysClock函数中,配置了系统时钟,PLL倍频以及分频系数:
  1. static void SetSysClock(void)
  2. {
  3. /******************************************************************************/
  4. /* PLL (clocked by HSE) used as System clock source */
  5. /******************************************************************************/
  6. __IO uint32_t StartUpCounter = 0, HSEStatus = 0;
  7. /* Enable HSE */
  8. RCC->CR |= ((uint32_t)RCC_CR_HSEON);
  9. /* Wait till HSE is ready and if Time out is reached exit */
  10. do
  11. {
  12. HSEStatus = RCC->CR & RCC_CR_HSERDY;
  13. StartUpCounter++;
  14. } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));
  15. if ((RCC->CR & RCC_CR_HSERDY) != RESET)
  16. {
  17. HSEStatus = (uint32_t)0x01;
  18. }
  19. else
  20. {
  21. HSEStatus = (uint32_t)0x00;
  22. }
  23. if (HSEStatus == (uint32_t)0x01)
  24. {
  25. /* Select regulator voltage output Scale 1 mode, System frequency up to 168 MHz */
  26. RCC->APB1ENR |= RCC_APB1ENR_PWREN;
  27. PWR->CR |= PWR_CR_VOS;
  28. /* HCLK = SYSCLK / 1*/
  29. RCC->CFGR |= RCC_CFGR_HPRE_DIV1;
  30. /* PCLK2 = HCLK / 2*/
  31. RCC->CFGR |= RCC_CFGR_PPRE2_DIV2;
  32. /* PCLK1 = HCLK / 4*/
  33. RCC->CFGR |= RCC_CFGR_PPRE1_DIV4;
  34. /* Configure the main PLL */
  35. RCC->PLLCFGR = PLL_M | (PLL_N << 6) | (((PLL_P >> 1) -1) << 16) |
  36. (RCC_PLLCFGR_PLLSRC_HSE) | (PLL_Q << 24);
  37. 点击打开链接
  38. /* Enable the main PLL */
  39. RCC->CR |= RCC_CR_PLLON;
  40. /* Wait till the main PLL is ready */
  41. while((RCC->CR & RCC_CR_PLLRDY) == 0)
  42. {
  43. }
  44. /* Configure Flash prefetch, Instruction cache, Data cache and wait state */
  45. FLASH->ACR = FLASH_ACR_ICEN |FLASH_ACR_DCEN |FLASH_ACR_LATENCY_5WS;
  46. /* Select the main PLL as system clock source */
  47. RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));
  48. RCC->CFGR |= RCC_CFGR_SW_PLL;
  49. /* Wait till the main PLL is used as system clock source */
  50. while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS ) != RCC_CFGR_SWS_PLL);
  51. {
  52. }
  53. }
  54. else
  55. { /* If HSE fails to start-up, the application will have wrong clock
  56. configuration. User can add here some code to deal with this error */
  57. }
  58. }
点击打开链接 /* 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 */ } }
 

 

 

 

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

 

默认配置: 

 

HCLK = SYSCLK / 1 = 168MHz ,AHB总线时钟

 

PCLK2 = HCLK / 2 = 84MHz

 
PCLK1 = HCLK / 4 = 42MHz

 

定时器初始化设置时计算定时时间需要用到该定时器时钟频率,具体原因详细看我整理的一篇博客文章,链接如下:

点击打开链接

 

 

方法二,根据需要重新进行配置(这里外部晶振25MHz,系统配置为168MHz)

  • 自己根据自己外部晶振大小和需要进行配置
  1. /*******************************************************************************
  2. * Function Name : RCC_Configuration
  3. * Description : Configures the different system clocks.
  4. * Input : None
  5. * Output : None
  6. * Return : None
  7. *******************************************************************************/
  8. void RCC_Configuration(void)
  9. {
  10. ErrorStatus HSEStartUpStatus;
  11. uint32_t PLL_M_Temp = 0;
  12. uint32_t PLL_N_Temp = 0;
  13. uint32_t PLL_P_Temp = 0;
  14. uint32_t PLL_Q_Temp = 0;
  15. RCC_DeInit(); //½«ËùÓÐRCCÖØÖÃΪ³õʼֵ
  16. RCC_HSEConfig(RCC_HSE_ON);
  17. HSEStartUpStatus = RCC_WaitForHSEStartUp(); //Ñ¡ÔñÍⲿ¾§Õñ(HSE)×÷ΪʱÖÓÔ´ µÈ´ýÍⲿʱÖÓ×¼±¸ºÃ
  18. if (HSEStartUpStatus == SUCCESS) //ÉèÖÃʱÖÓΪ168M
  19. {
  20. /* Enable Prefetch Buffer */
  21. //FLASH_PrefetchBufferCmd(ENABLE);
  22. /* Flash 2 wait state */
  23. //FLASH_SetLatency(FLASH_Latency_5);
  24. //HSE_VALUE = 8MHz,PLL_VCO input clock = (HSE_VALUE or HSI_VALUE)/PLL_M,½¨Òé´ËֵΪ1~2MHz,Òò´ËÈ¡PLL_M=8£¬
  25. //PLL_VCO input clock = 1MHz;
  26. PLL_M_Temp = 8;
  27. //PLL_VCO output clock = (PLL_VCO input clock)*PLL_N
  28. //PLL_VCO output clock = 336;
  29. PLL_N_Temp = 336;
  30. //System Clock = (PLL_VCO output clock)/PLL_P ,
  31. //System Clock = 84MHz
  32. PLL_P_Temp = 4;
  33. //´ËϵÊýÓÃÓÚÉèÖÃSD¿¨¶Áд£¬USBµÈ¹¦ÄÜ£¬ÔÝʱ²»ÓÃ
  34. PLL_Q_Temp = 7;
  35. /* PLL configuration */
  36. RCC_PLLConfig(RCC_PLLSource_HSE, PLL_M_Temp, PLL_N_Temp, PLL_P_Temp, PLL_Q_Temp);
  37. /* Enable PLL */
  38. RCC_PLLCmd(ENABLE);
  39. /* Wait till PLL is ready */
  40. while (RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET)
  41. {
  42. }
  43. /* Select PLL as system clock source */
  44. RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
  45. /* Wait till PLL is used as system clock source */
  46. while(RCC_GetSYSCLKSource() != 0x08)
  47. {
  48. }
  49. }
  50. }





 

 

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/2023面试高手/article/detail/646721
推荐阅读
相关标签
  

闽ICP备14008679号