打印
[STM32F4]

(转)STM32F4时钟设置分析

[复制链接]
1353|3
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
renzheshengui|  楼主 | 2018-8-16 09:34 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本文博客链接:http://blog.csdn.net/jdh99


环境:

主机:WIN7

开发环境:MDK4.72

MCU:STM32F407VGT6


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

1.启动代码:

文件:startup_stm32f4xx.s




  • ; Reset handler



  • Reset_Handler    PROC



  •                  EXPORT  Reset_Handler             [WEAK]



  •         IMPORT  SystemInit



  •         IMPORT  __main







  •                  LDR     R0, =SystemInit



  •                  BLX     R0



  •                  LDR     R0, =__main



  •                  BX      R0



  •                  ENDP


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


2.SystemInit函数分析

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




  • /************************* 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







  • /******************************************************************************/



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

外部晶振:




  • #if !defined  (HSE_VALUE)



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



  • #endif /* HSE_VALUE */



内部晶振:



  • #if !defined  (HSI_VALUE)   



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



  • #endif /* HSI_VALUE */



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

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

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

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

时钟图:


SystemInit函数代码:




  • /**



  •   * @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



  • }



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


  • /**



  •   * @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 */



  •   }







  • }



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

默认配置:

HCLK = SYSCLK / 1 = 168MHz

PCLK2 = HCLK / 2 = 84MHz

PCLK1 = HCLK / 4 = 42MHz


沙发
wakayi| | 2018-8-16 09:48 | 只看该作者
用cube也可以自己生成

使用特权

评论回复
板凳
renzheshengui|  楼主 | 2018-8-17 09:23 | 只看该作者
wakayi 发表于 2018-8-16 09:48
用cube也可以自己生成

是的 但是hal太臃肿

使用特权

评论回复
地板
wakayi| | 2018-8-17 09:26 | 只看该作者
renzheshengui 发表于 2018-8-17 09:23
是的 但是hal太臃肿

是的 像这种小程序直接操作寄存器就可以了

使用特权

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

本版积分规则

78

主题

4079

帖子

2

粉丝