找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1855|回复: 0
打印 上一主题 下一主题
收起左侧

STM32F4系统时钟树

[复制链接]
跳转到指定楼层
楼主
ID:417196 发表于 2018-10-29 13:48 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
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.                              
6.                                               LDR     R0, =SystemInit
7.                                               BLX     R0
8.                                               LDR     R0, =__main
9.                                               BX      R0
10.                                           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.                           
13.                           
14.                          /* USB OTG FS, SDIO and RNG Clock = PLL_VCO / PLLQ */
15.                          #define PLL_Q      7
16.                           
17.                           
18.                          #if defined (STM32F40_41xxx)
19.                          #define PLL_N      336
20.                          /* SYSCLK = PLL_VCO / PLL_P */
21.                          #define PLL_P      2  //2           //2---168M  4---84M
22.                          #endif /* STM32F40_41xxx */
23.                           
24.                           
25.                          #if defined (STM32F427_437xx) || defined (STM32F429_439xx)
26.                          #define PLL_N      360
27.                          /* SYSCLK = PLL_VCO / PLL_P */
28.                          #define PLL_P      2
29.                          #endif /* STM32F427_437x || STM32F429_439xx */
30.                           
31.                           
32.                          #if defined (STM32F401xx)
33.                          #define PLL_N      336
34.                          /* SYSCLK = PLL_VCO / PLL_P */
35.                          #define PLL_P      4
36.                          #endif /* STM32F401xx */
37.                           
38.                           
39.                          #if defined (STM32F411xE)
40.                          #define PLL_N      400
41.                          /* SYSCLK = PLL_VCO / PLL_P */
42.                          #define PLL_P      4  
43.                          #endif /* STM32F411xx */
44.                           
45.                           
46.                          /******************************************************************************/
我使用的是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.                              
6.                              /* SYSCLK = PLL_VCO / PLL_P */  
7.                              #define PLL_P      2  
8.                              
9.                              /* USB OTG FS, SDIO and RNG Clock =  PLL_VCO / PLLQ */  
10.                          #define PLL_Q      7  
11.                           
12.                          /******************************************************************************/
·                  而晶振频率则是在文件stm32f4xx.h中进行设置:
·                  外部晶振:
1.                              #if !defined  (HSE_VALUE)
2.                                #defineHSE_VALUE    ((uint32_t)8000000) /*!< Value ofthe External oscillator in Hz */
3.                                
4.                              #endif /* HSE_VALUE */
·                  内部晶振:
1.                              #if !defined  (HSI_VALUE)  
2.                                #defineHSI_VALUE    ((uint32_t)16000000) /*!< Value ofthe 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 RCCclock configuration to the default reset state ------------*/
8.                                /* Set HSION bit */
9.                                RCC->CR |= (uint32_t)0x00000001;
10.                           
11.                            /* Reset CFGRregister */
12.                            RCC->CFGR = 0x00000000;
13.                           
14.                            /* Reset HSEON,CSSON and PLLON bits */
15.                            RCC->CR &=(uint32_t)0xFEF6FFFF;
16.                           
17.                            /* Reset PLLCFGRregister */
18.                            RCC->PLLCFGR =0x24003010;
19.                           
20.                            /* Reset HSEBYP bit*/
21.                            RCC->CR &=(uint32_t)0xFFFBFFFF;
22.                           
23.                            /* Disable allinterrupts */
24.                            RCC->CIR = 0x00000000;
25.                           
26.                          #if defined (DATA_IN_ExtSRAM) || defined(DATA_IN_ExtSDRAM)
27.                            SystemInit_ExtMemCtl();
28.                          #endif /* DATA_IN_ExtSRAM|| DATA_IN_ExtSDRAM */
29.                                   
30.                            /* Configure theSystem clock source, PLL Multiplier and Divider factors,
31.                               AHB/APBx prescalers and Flash settings----------------------------------*/
32.                            SetSysClock();
33.                           
34.                            /* Configure theVector Table location add offset address ------------------*/
35.                          #ifdef VECT_TAB_SRAM
36.                            SCB->VTOR =SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM*/
37.                          #else
38.                            SCB->VTOR =FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in InternalFLASH */
39.                          #endif
40.                          }
·                  SetSysClock函数分析,在SetSysClock函数中,配置了系统时钟,PLL倍频以及分频系数:
1.                              static void SetSysClock(void)  
2.                              {  
3.                              /******************************************************************************/  
4.                              /*            PLL (clocked by HSE) used as Systemclock source                */  
5.                              /******************************************************************************/  
6.                                __IO uint32_t StartUpCounter = 0, HSEStatus = 0;  
7.                                 
8.                                /* Enable HSE */  
9.                                RCC->CR |= ((uint32_t)RCC_CR_HSEON);  
10.                             
11.                            /* Wait till HSE isready and if Time out is reached exit */  
12.                            do  
13.                            {  
14.                              HSEStatus =RCC->CR & RCC_CR_HSERDY;  
15.                              StartUpCounter++;  
16.                            } while((HSEStatus == 0) &&(StartUpCounter != HSE_STARTUP_TIMEOUT));
17.                           
18.                            if ((RCC->CR &RCC_CR_HSERDY) != RESET)  
19.                            {  
20.                              HSEStatus = (uint32_t)0x01;  
21.                            }  
22.                            else  
23.                            {  
24.                              HSEStatus = (uint32_t)0x00;  
25.                            }  
26.                           
27.                            if (HSEStatus == (uint32_t)0x01)  
28.                            {  
29.                              /* Select regulatorvoltage output Scale 1 mode, System frequency up to 168 MHz */  
30.                              RCC->APB1ENR|= RCC_APB1ENR_PWREN;  
31.                              PWR->CR |= PWR_CR_VOS;  
32.                           
33.                              /* HCLK = SYSCLK /1*/  
34.                              RCC->CFGR |=RCC_CFGR_HPRE_DIV1;  
35.                                 
36.                              /* PCLK2 = HCLK /2*/  
37.                              RCC->CFGR |=RCC_CFGR_PPRE2_DIV2;  
38.                                
39.                              /* PCLK1 = HCLK /4*/  
40.                              RCC->CFGR |= RCC_CFGR_PPRE1_DIV4;  
41.                           
42.                              /* Configure themain PLL */  
43.                              RCC->PLLCFGR= PLL_M | (PLL_N << 6) | (((PLL_P >> 1) -1) << 16) |  
44.                                             (RCC_PLLCFGR_PLLSRC_HSE) |(PLL_Q << 24);  
45.                            点击打开链接
46.                              /* Enable the mainPLL */  
47.                              RCC->CR |=RCC_CR_PLLON;  
48.                           
49.                              /* Wait till themain PLL is ready */  
50.                              while((RCC->CR &RCC_CR_PLLRDY) == 0)  
51.                              {  
52.                              }  
53.                              
54.                              /* Configure Flashprefetch, Instruction cache, Data cache and wait state */  
55.                              FLASH->ACR =FLASH_ACR_ICEN |FLASH_ACR_DCEN |FLASH_ACR_LATENCY_5WS;  
56.                           
57.                              /* Select the mainPLL as system clock source */  
58.                              RCC->CFGR&= (uint32_t)((uint32_t)~(RCC_CFGR_SW));  
59.                              RCC->CFGR |=RCC_CFGR_SW_PLL;  
60.                           
61.                              /* Wait till themain PLL is used as system clock source */  
62.                              while ((RCC->CFGR &(uint32_t)RCC_CFGR_SWS) != RCC_CFGR_SWS_PLL);  
63.                              {  
64.                              }  
65.                            }  
66.                            else  
67.                            { /* If HSE fails tostart-up, the application will have wrong clock
68.                                   configuration. User can add here somecode to deal with this error */  
69.                            }  
70.                           
71.                          }


如果外部时钟启动失败,系统会使用内部时钟
默认配置:
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.                                  ErrorStatusHSEStartUpStatus;
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.                                 
16.                                 
17.                                  RCC_DeInit();                                 //½«ËùóDRCCÖØÖÃÎa3õê¼Öμ
18.                                 
19.                                  RCC_HSEConfig(RCC_HSE_ON);
20.                                  HSEStartUpStatus= RCC_WaitForHSEStartUp();   //Ñ¡Ôñía2¿¾§Õñ(HSE)×÷Îaê±ÖóÔ′μè′yía2¿ê±Öó×¼±¸oÃ
21.                                 
22.                                 
23.                            if (HSEStartUpStatus ==SUCCESS)   //éèÖÃê±ÖóÎa168M
24.                            {
25.                              /* Enable PrefetchBuffer */
26.                              //FLASH_PrefetchBufferCmd(ENABLE);
27.                              
28.                              /* Flash 2 waitstate */
29.                              //FLASH_SetLatency(FLASH_Latency_5);
30.                                         
31.                                        //HSE_VALUE =8MHz,PLL_VCO input clock = (HSE_VALUE orHSI_VALUE)/PLL_M,½¨òé′ËÖμÎa1~2MHz,òò′Ëè¡PLL_M=8£¬
32.                                         //PLL_VCO inputclock = 1MHz;
33.                                         PLL_M_Temp= 8;
34.                              
35.                                         //PLL_VCO outputclock = (PLL_VCO input clock)*PLL_N
36.                                         //PLL_VCO outputclock = 336;
37.                                         PLL_N_Temp= 336;
38.                                         
39.                                         //System Clock =(PLL_VCO output clock)/PLL_P ,
40.                                         //System Clock =84MHz
41.                                         
42.                                         PLL_P_Temp= 4;
43.                                         
44.                                         //′ËÏμêyóÃóúéèÖÃSD¿¨¶áD′£¬USBμè1|Äü£¬ÔYê±2»óÃ
45.                                         PLL_Q_Temp= 7;
46.                                         
47.                              /* PLLconfiguration */
48.                              RCC_PLLConfig(RCC_PLLSource_HSE,PLL_M_Temp, PLL_N_Temp, PLL_P_Temp, PLL_Q_Temp);
49.                              /* Enable PLL */
50.                              RCC_PLLCmd(ENABLE);
51.                              
52.                              /* Wait till PLL isready */
53.                              while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET)
54.                              {
55.                              }
56.                              
57.                              /* Select PLL assystem clock source */
58.                              RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
59.                              
60.                              /* Wait till PLL isused as system clock source */
61.                              while(RCC_GetSYSCLKSource()!= 0x08)
62.                              {
63.                              }
64.                           
65.                            }

66.                          }


分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表