历史上的今天
今天是:2024年09月15日(星期日)
2020年09月15日 | STM32F4时钟设置分析
2020-09-15 来源:eefocus
环境:
主机:WIN7
开发环境:MDK4.72
MCU:STM32F407VGT6
STM32F4启动与STM32F10X不同,时钟已经默认配置好.
1.启动代码:
文件:startup_stm32f4xx.s
[cpp] view plain copy
在CODE上查看代码片派生到我的代码片
; 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文件中.此文件提供几个宏定义可以设置各个时钟:
在CODE上查看代码片派生到我的代码片
/************************* 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中进行设置:
外部晶振:
在CODE上查看代码片派生到我的代码片
#if !defined (HSE_VALUE) #define HSE_VALUE ((uint32_t)25000000) /*!< Value of the External oscillator in Hz */ #endif /* HSE_VALUE */
内部晶振:
在CODE上查看代码片派生到我的代码片
#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函数代码:
在CODE上查看代码片派生到我的代码片
/** * @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倍频以及分频系数:
在CODE上查看代码片派生到我的代码片
/** * @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
史海拾趣
|
随着通用无线分组业务(GPRS)的推出并与现有GSM共存,移动网络运营商正面临新的挑战。与任何新系统一样,GPRS网络在发展初期也经历了成长的痛苦,运营商需要迅速解决用户的问题,从而争取更多用户并最大程度取得投资回报。本文介绍用协议测试仪对流 ...… 查看全部问答> |
|
2008年,对于中国来说,的确是不平凡的一年。大灾大幸,大起大落。奥运会刚刚闭幕,奶和油又掀起了新一轮的波澜。 “三鹿门”转瞬之间由小变大,数千个孩子的生命安全引起了全社会的关注。短短几天,二十多家奶制品厂被查出添加有毒物质,包括全国 ...… 查看全部问答> |
|
在读取文件目录时,调用sprintf函数时,总是出错,不知问题在哪里,高手帮忙啊。 /*************************************************************************************** FunctionName : AppScanFiles()* Description &nbs ...… 查看全部问答> |
|
SystemState status = new SystemState(SystemProperty.PowerBatteryBackupStrength); status.Changed += new ChangeEventHandler(status_Changed); status绑定的是现有电池量的changed事件 当我电视改变,应该调用status_Changed这个函数 我是 ...… 查看全部问答> |
|
刚学习vxWorks,今天碰到了一个问题,想请教一下各位!先谢谢了! 今天看到了一个这样的函数,是有关msgQSend的! int DataProcess(char *pData, int DataLen) { char *ReceivePack = NULL; MNREMSG msgSend; &n ...… 查看全部问答> |




