STM32_3 时钟初始化分析

在startup文件中,调用了2个函数,一个是System_Init, 另一个是main。

System_Init()在system_stm32f10x.c 这个文件中,先看一下时钟树,再分析一下这个文件。

上树:

首先:时钟源有4个:

OSC_IN / OSC_OUT

HSE

外部高速时钟

一般是8MHz

OSC32_IN / OSC32_OUT

LSE

外部低速系统时钟

32.768kHz

 

HSI

内部高速时钟

8MHz

 

LSI

内部低速时钟

40kHz

这3个时钟很有意思,因为stm32官方设计最高稳定频率是72MHz,来分析一下如何从8Mhz输入到72MHz.

主时钟是HSE,一般为8MHz输入,在图中找到外部的该时钟输入,用这里进入时钟树的分配,

1一开始就遇到2条路, 2 -- 直接到达PLLXTPRE控制器 8MHz 3 -- 2分频后到达 PLLXTPRE 4MHZ 4一般选择不分频,4MHz太小,后面会补充说明。 5PLLXTPRE是一个寄存器,控制是否2分频。

只有PLL还没使能的时候才能配置该寄存器

1继续往下走: 2来到PLLSRC 意味选择PLL时钟来源, 3 --HSE 8M 4 --HSL 必须经过2分频 4M 5配置为HSE,如果HES时钟没能起来,就会被迫切换成HSL时钟,4MHz 6 7然后PLLMUL PLL锁相环倍频,有2~16多种选择, 8因为stm32最高稳定时钟是72MHz,所以如果是HSE8MHz的话,这里就可以配置成9倍频,当然可以选择更高的,只是那样系统时钟不稳定。 9 10假设之前HSE选择2分频,4MHz,这里就算选择16倍频也只有64MHz,比72MHz低,这就为为什么不选择2分频的原因。 11同样,HSI时钟必须2分频,最高也只有64MHz,比72MHz慢,且受温漂影响。

1接下来是选定一种频率作为系统时钟。有3种来源 2 --HSI 8MHz (x) 3 --PLLCLKHSE*9=72MHz) (y) 4 --LSE 32.768kHz (x) 5 6以PLLCLK72MHz作为系统时钟,分出3条时钟总线 7--AHB 72MHz 高速 8--APB2 72MHz 高速 9--APB1 36MHz 慢速

包括其他的时钟也是用这种方法结合文档慢慢分析,以后遇到了再回来查阅手册。

再来看库是怎么实现时钟分配的。

首先找到system_init这个函数

//1,使能RCC_CR

1void SystemInit (void) 2{ 3 /* Reset the RCC clock configuration to the default reset state(for debug purpose) */ 4 /* Set HSION bit */ 5 RCC->CR |= (uint32_t)0x00000001; 6 7 /* Reset SW, HPRE, PPRE1, PPRE2, ADCPRE and MCO bits */ 8 RCC->CFGR &= (uint32_t)0xF0FF0000; 9 10 /* Reset HSEON, CSSON and PLLON bits */ 11 RCC->CR &= (uint32_t)0xFEF6FFFF; 12 13 /* Reset HSEBYP bit */ 14 RCC->CR &= (uint32_t)0xFFFBFFFF; 15 16 /* Reset PLLSRC, PLLXTPRE, PLLMUL and USBPRE/OTGFSPRE bits */ 17 RCC->CFGR &= (uint32_t)0xFF80FFFF; 18 19 /* Disable all interrupts and clear pending bits */ 20 RCC->CIR = 0x009F0000; 21 22 /* 以上,各种 reset,以下,开始配置时钟 */ 23 /* 跳转到SetSysClock() */ 24 /* Configure the System clock frequency, HCLK, PCLK2 and PCLK1 prescalers */ 25 /* Configure the Flash Latency cycles and enable prefetch buffer */ 26 SetSysClock(); 27 SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH. */ 28} 29 30/* 根据各种宏定义决定配置成什么样的系统时钟,在之前 */ 31static void SetSysClock(void) 32{ 33#ifdef SYSCLK_FREQ_HSE 34 SetSysClockToHSE(); 35#elif defined SYSCLK_FREQ_24MHz 36 SetSysClockTo24(); 37#elif defined SYSCLK_FREQ_36MHz 38 SetSysClockTo36(); 39#elif defined SYSCLK_FREQ_48MHz 40 SetSysClockTo48(); 41#elif defined SYSCLK_FREQ_56MHz 42 SetSysClockTo56(); 43#elif defined SYSCLK_FREQ_72MHz 44 SetSysClockTo72(); 45#endif 46 47 /* If none of the define above is enabled, the HSI is used as System clock 48 source (default after reset) */ 49}

在之前就已经定义好了配置为72MHz的宏,所以进入 SetSysClockTo72();

1static void SetSysClockTo72(void) 2{ 3 __IO uint32_t StartUpCounter = 0, HSEStatus = 0; 4 /* 这里是整个配置的重点函数 */ 5 /* SYSCLK, HCLK, PCLK2 and PCLK1 configuration ---------------------------*/ 6 /* Enable HSE 先使能HSE时钟*/ 7 RCC->CR |= ((uint32_t)RCC_CR_HSEON); 8 9 /* Wait till HSE is ready and if Time out is reached exit 要等待HSE时钟准备好后,跳出while循环,这里有超时机制 */ 10 do 11 { 12 HSEStatus = RCC->CR & RCC_CR_HSERDY; 13 StartUpCounter++; 14 } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT)); 15 16 if ((RCC->CR & RCC_CR_HSERDY) != RESET) 17 { 18 HSEStatus = (uint32_t)0x01; 19 } 20 else 21 { 22 HSEStatus = (uint32_t)0x00; 23 } 24 25 /* 如果HSE起来后,这里要配置2个flash预取指令相关 */ 26 if (HSEStatus == (uint32_t)0x01) 27 { 28 /* Enable Prefetch Buffer 允许预读指令 */ 29 FLASH->ACR |= FLASH_ACR_PRFTBE; 30 31 /* Flash 2 wait state 预读指令间隔2个时间周期 */ 32 FLASH->ACR &= (uint32_t)((uint32_t)~FLASH_ACR_LATENCY); 33 FLASH->ACR |= (uint32_t)FLASH_ACR_LATENCY_2; 34 35 36 /* HCLK = SYSCLK 配置PLLCLK为系统时钟*/ 37 RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1; 38 39 /* PCLK2 = HCLK 配置APB2时钟*/ 40 RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1; 41 42 /* PCLK1 = HCLK 配置APB1时钟*/ 43 RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV2; 44 45 /* PLL configuration: PLLCLK = HSE * 9 = 72 MHz PLL9倍频*/ 46 RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE | 47 RCC_CFGR_PLLMULL)); 48 RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_HSE | RCC_CFGR_PLLMULL9); 49 50 /* Enable PLL 使能PLL,注意,PLL未使能的情况下才能配置之前的参数。*/ 51 RCC->CR |= RCC_CR_PLLON; 52 53 /* Wait till PLL is ready 等待PLL准备好*/ 54 while((RCC->CR & RCC_CR_PLLRDY) == 0) 55 { 56 } 57 58 /* Select PLL as system clock source 选择PLL作为系统时钟*/ 59 RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW)); 60 RCC->CFGR |= (uint32_t)RCC_CFGR_SW_PLL; 61 62 /* Wait till PLL is used as system clock source 等待PLL作为系统时钟准备完毕 */ 63 while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)0x08) 64 { 65 } 66 } 67 else 68 { /* If HSE fails to start-up, the application will have wrong clock 69 configuration. User can add here some code to deal with this error 这里交给用户自己变成,如果HSE时钟没有成功,就会进入这里 */ 70 } 71} 72#endif

顺便读一下RCC库函数

1RCC库函数。 2/* 函数库 按F12 跳转到函数体,就可以学习怎么使用 */ 3/** @defgroup RCC_Exported_Functions 4 * @{ 5 */ 6 7void RCC_DeInit(void); /* 重新初始化时钟配置,在自定义时钟时使用 */ 8void RCC_HSEConfig(uint32_t RCC_HSE); //配置HSE时钟 9ErrorStatus RCC_WaitForHSEStartUp(void); /* 等待HSE时钟准备完成 */ 10void RCC_AdjustHSICalibrationValue(uint8_t HSICalibrationValue); 11void RCC_HSICmd(FunctionalState NewState); 12void RCC_PLLConfig(uint32_t RCC_PLLSource, uint32_t RCC_PLLMul); /* PLL锁相环控制器 */ 13void RCC_PLLCmd(FunctionalState NewState); /* PLL 使能 */ 14 15void RCC_SYSCLKConfig(uint32_t RCC_SYSCLKSource);/* 配置系统时钟来源 1/3 */ 16uint8_t RCC_GetSYSCLKSource(void); 17void RCC_HCLKConfig(uint32_t RCC_SYSCLK); 18void RCC_PCLK1Config(uint32_t RCC_HCLK); 19void RCC_PCLK2Config(uint32_t RCC_HCLK); 20void RCC_ITConfig(uint8_t RCC_IT, FunctionalState NewState); 21 22void RCC_OTGFSCLKConfig(uint32_t RCC_OTGFSCLKSource); 23 24void RCC_ADCCLKConfig(uint32_t RCC_PCLK2); 25 26void RCC_LSEConfig(uint8_t RCC_LSE); 27void RCC_LSICmd(FunctionalState NewState); 28void RCC_RTCCLKConfig(uint32_t RCC_RTCCLKSource); 29void RCC_RTCCLKCmd(FunctionalState NewState); 30void RCC_GetClocksFreq(RCC_ClocksTypeDef* RCC_Clocks); 31void RCC_AHBPeriphClockCmd(uint32_t RCC_AHBPeriph, FunctionalState NewState); 32void RCC_APB2PeriphClockCmd(uint32_t RCC_APB2Periph, FunctionalState NewState); 33void RCC_APB1PeriphClockCmd(uint32_t RCC_APB1Periph, FunctionalState NewState); 34 35void RCC_APB2PeriphResetCmd(uint32_t RCC_APB2Periph, FunctionalState NewState); 36void RCC_APB1PeriphResetCmd(uint32_t RCC_APB1Periph, FunctionalState NewState); 37void RCC_BackupResetCmd(FunctionalState NewState); 38void RCC_ClockSecuritySystemCmd(FunctionalState NewState); 39void RCC_MCOConfig(uint8_t RCC_MCO); 40FlagStatus RCC_GetFlagStatus(uint8_t RCC_FLAG); 41void RCC_ClearFlag(void); 42ITStatus RCC_GetITStatus(uint8_t RCC_IT); 43void RCC_ClearITPendingBit(uint8_t RCC_IT);

实际例子://实现超频到16倍频

1#include "myclk.h" 2 3/** 4 * 1.学习系统时钟配置过程 5 * 2.超频一下看会是什么情况 6 * 3.MCO输出时钟 7 */ 8 9void HSE_SetSystem(uint32_t RCC_PLLMul) 10{ 11 ErrorStatus HSEStatus; 12 13 /* 要先将已有的时钟初始化 */ 14 RCC_DeInit(); 15 16 /* HSE时钟使能 */ 17 RCC_HSEConfig(RCC_HSE_ON); 18 19 /* 等待HSE时钟准备好 */ 20 HSEStatus = RCC_WaitForHSEStartUp(); 21 if( HSEStatus == SUCCESS ) /* HSE 时钟准备好了 */ 22 { 23 /* HSE success*/ 24 /* Flash 预取值 */ 25 FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable); 26 27 /* Flash 等待周期 */ 28 FLASH_SetLatency(FLASH_Latency_2); 29 30 /* 配置3条时钟总线 */ 31 RCC_HCLKConfig(RCC_SYSCLK_Div1); 32 RCC_PCLK1Config(RCC_HCLK_Div1); 33 RCC_PCLK2Config(RCC_HCLK_Div2); 34 35 /* PLL倍频 倍频数放在参数传进来*/ 36 RCC_PLLConfig(RCC_PLLSource_HSE_Div1,RCC_PLLMul); 37 RCC_PLLCmd(ENABLE); 38 39 /* 等待PLL 使能成功 */ 40 while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET); 41 42 RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK); 43 44 while(RCC_GetSYSCLKSource() != 0x08); 45 46 47 }else /* HSE 时钟未能初始化 */ 48 { 49 /* 错误处理 */ 50 } 51} 52 53/* MCO 是GPIOA 8的复用输出功能 */ 54void MCO_GPIO_Config(void) 55{ 56 GPIO_InitTypeDef GPIO_InitStruct; 57 58 RCC_APB2PeriphClockCmd(MCO_GPIO_CLK,ENABLE); 59 60 GPIO_InitStruct.GPIO_Pin = MCO_GPIO_PIN; 61 GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP; 62 GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; 63 64 GPIO_Init(MCO_GPIO_PORT,&GPIO_InitStruct); 65} 66 67/** 68 ****************************************************************************** 69 * @file system_stm32f10x.c 70 * @author MCD Application Team 71 * @version V3.5.0 72 * @date 11-March-2011 73 * @brief CMSIS Cortex-M3 Device Peripheral Access Layer System Source File. 74 * 75 * 1. This file provides two functions and one global variable to be called from 76 * user application: 这个文件提供2个函数 和 1个全局变量 以供用户调用。 77 * - SystemInit(): Setups the system clock (System clock source, PLL Multiplier 78 * factors, AHB/APBx prescalers and Flash settings). 79 * This function is called at startup just after reset and 80 * before branch to main program. This call is made inside 81 * the "startup_stm32f10x_xx.s" file. 82 // 设置系统时钟,分配系统时钟,PLL锁相环,AHB/APB1和APB2的时钟和flsah的预取指令的设置,这个函数在 系统复位后,main函数被调用前执行,被启动文件所调用。 83 * 84 * - SystemCoreClock variable: Contains the core clock (HCLK), it can be used 85 * by the user application to setup the SysTick 86 * timer or configure other parameters. 87 * 88 //systemCoreClock 包含了HCLK,这个变量可以被用于配置SysTick 或其他 变量配置。 89 90 * - SystemCoreClockUpdate(): Updates the variable SystemCoreClock and must 91 * be called whenever the core clock is changed 92 * during program execution. 93 * // 94 95 * 2. After each device reset the HSI (8 MHz) is used as system clock source. 96 * Then SystemInit() function is called, in "startup_stm32f10x_xx.s" file, to 97 * configure the system clock before to branch to main program. 98 * 99 * 3. If the system clock source selected by user fails to startup, the SystemInit() 100 * function will do nothing and HSI still used as system clock source. User can 101 * add some code to deal with this issue inside the SetSysClock() function. 102 * 103 * 4. The default value of HSE crystal is set to 8 MHz (or 25 MHz, depedning on 104 * the product used), refer to "HSE_VALUE" define in "stm32f10x.h" file. 105 * When HSE is used as system clock source, directly or through PLL, and you 106 * are using different crystal you have to adapt the HSE value to your own 107 * configuration. 108 * 109 ****************************************************************************** 110 * @attention 111 * 112 * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS 113 * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE 114 * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY 115 * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING 116 * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE 117 * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. 118 * 119 * <h2><center>&copy; COPYRIGHT 2011 STMicroelectronics</center></h2> 120 ****************************************************************************** 121 */ 122 123/** @addtogroup CMSIS 124 * @{ 125 */ 126 127/** @addtogroup stm32f10x_system 128 * @{ 129 */ 130 131/** @addtogroup STM32F10x_System_Private_Includes 132 * @{ 133 */ 134 135#include "stm32f10x.h" 136 137/** 138 * @} 139 */ 140 141/** @addtogroup STM32F10x_System_Private_TypesDefinitions 142 * @{ 143 */ 144 145/** 146 * @} 147 */ 148 149/** @addtogroup STM32F10x_System_Private_Defines 150 * @{ 151 */ 152 153/*!< Uncomment the line corresponding to the desired System clock (SYSCLK) 154 frequency (after reset the HSI is used as SYSCLK source) 155 156 IMPORTANT NOTE: 157 ============== 158 1. After each device reset the HSI is used as System clock source. 159 160 2. Please make sure that the selected System clock doesn't exceed your device's 161 maximum frequency. 162 163 3. If none of the define below is enabled, the HSI is used as System clock 164 source. 165 166 4. The System clock configuration functions provided within this file assume that: 167 - For Low, Medium and High density Value line devices an external 8MHz 168 crystal is used to drive the System clock. 169 - For Low, Medium and High density devices an external 8MHz crystal is 170 used to drive the System clock. 171 - For Connectivity line devices an external 25MHz crystal is used to drive 172 the System clock. 173 If you are using different crystal you have to adapt those functions accordingly. 174 */ 175 176#if defined (STM32F10X_LD_VL) || (defined STM32F10X_MD_VL) || (defined STM32F10X_HD_VL) 177/* #define SYSCLK_FREQ_HSE HSE_VALUE */ 178 #define SYSCLK_FREQ_24MHz 24000000 179#else 180/* #define SYSCLK_FREQ_HSE HSE_VALUE */ 181/* #define SYSCLK_FREQ_24MHz 24000000 */ 182/* #define SYSCLK_FREQ_36MHz 36000000 */ 183/* #define SYSCLK_FREQ_48MHz 48000000 */ 184/* #define SYSCLK_FREQ_56MHz 56000000 */ 185#define SYSCLK_FREQ_72MHz 72000000 186#endif 187 188/*!< Uncomment the following line if you need to use external SRAM mounted 189 on STM3210E-EVAL board (STM32 High density and XL-density devices) or on 190 STM32100E-EVAL board (STM32 High-density value line devices) as data memory */ 191#if defined (STM32F10X_HD) || (defined STM32F10X_XL) || (defined STM32F10X_HD_VL) 192/* #define DATA_IN_ExtSRAM */ 193#endif 194 195/*!< Uncomment the following line if you need to relocate your vector Table in 196 Internal SRAM. */ 197/* #define VECT_TAB_SRAM */ 198#define VECT_TAB_OFFSET 0x0 /*!< Vector Table base offset field. 199 This value must be a multiple of 0x200. */ 200 201 202/** 203 * @} 204 */ 205 206/** @addtogroup STM32F10x_System_Private_Macros 207 * @{ 208 */ 209 210/** 211 * @} 212 */ 213 214/** @addtogroup STM32F10x_System_Private_Variables 215 * @{ 216 */ 217 218/******************************************************************************* 219* Clock Definitions 220*******************************************************************************/ 221#ifdef SYSCLK_FREQ_HSE 222 uint32_t SystemCoreClock = SYSCLK_FREQ_HSE; /*!< System Clock Frequency (Core Clock) */ 223#elif defined SYSCLK_FREQ_24MHz 224 uint32_t SystemCoreClock = SYSCLK_FREQ_24MHz; /*!< System Clock Frequency (Core Clock) */ 225#elif defined SYSCLK_FREQ_36MHz 226 uint32_t SystemCoreClock = SYSCLK_FREQ_36MHz; /*!< System Clock Frequency (Core Clock) */ 227#elif defined SYSCLK_FREQ_48MHz 228 uint32_t SystemCoreClock = SYSCLK_FREQ_48MHz; /*!< System Clock Frequency (Core Clock) */ 229#elif defined SYSCLK_FREQ_56MHz 230 uint32_t SystemCoreClock = SYSCLK_FREQ_56MHz; /*!< System Clock Frequency (Core Clock) */ 231#elif defined SYSCLK_FREQ_72MHz 232 uint32_t SystemCoreClock = SYSCLK_FREQ_72MHz; /*!< System Clock Frequency (Core Clock) */ 233#else /*!< HSI Selected as System Clock source */ 234 uint32_t SystemCoreClock = HSI_VALUE; /*!< System Clock Frequency (Core Clock) */ 235#endif 236 237__I uint8_t AHBPrescTable[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9}; 238/** 239 * @} 240 */ 241 242/** @addtogroup STM32F10x_System_Private_FunctionPrototypes 243 * @{ 244 */ 245 246static void SetSysClock(void); 247 248#ifdef SYSCLK_FREQ_HSE 249 static void SetSysClockToHSE(void); 250#elif defined SYSCLK_FREQ_24MHz 251 static void SetSysClockTo24(void); 252#elif defined SYSCLK_FREQ_36MHz 253 static void SetSysClockTo36(void); 254#elif defined SYSCLK_FREQ_48MHz 255 static void SetSysClockTo48(void); 256#elif defined SYSCLK_FREQ_56MHz 257 static void SetSysClockTo56(void); 258#elif defined SYSCLK_FREQ_72MHz 259 static void SetSysClockTo72(void); 260#endif 261 262#ifdef DATA_IN_ExtSRAM 263 static void SystemInit_ExtMemCtl(void); 264#endif /* DATA_IN_ExtSRAM */ 265 266/** 267 * @} 268 */ 269 270/** @addtogroup STM32F10x_System_Private_Functions 271 * @{ 272 */ 273 274/** 275 * @brief Setup the microcontroller system 276 * Initialize the Embedded Flash Interface, the PLL and update the 277 * SystemCoreClock variable. 278 * @note This function should be used only after reset. 279 * @param None 280 * @retval None 281 */ 282void SystemInit (void) 283{ 284 /* Reset the RCC clock configuration to the default reset state(for debug purpose) */ 285 /* Set HSION bit */ 286 RCC->CR |= (uint32_t)0x00000001; 287 288 /* Reset SW, HPRE, PPRE1, PPRE2, ADCPRE and MCO bits */ 289#ifndef STM32F10X_CL 290 RCC->CFGR &= (uint32_t)0xF8FF0000; 291#else 292 RCC->CFGR &= (uint32_t)0xF0FF0000; 293#endif /* STM32F10X_CL */ 294 295 /* Reset HSEON, CSSON and PLLON bits */ 296 RCC->CR &= (uint32_t)0xFEF6FFFF; 297 298 /* Reset HSEBYP bit */ 299 RCC->CR &= (uint32_t)0xFFFBFFFF; 300 301 /* Reset PLLSRC, PLLXTPRE, PLLMUL and USBPRE/OTGFSPRE bits */ 302 RCC->CFGR &= (uint32_t)0xFF80FFFF; 303 304#ifdef STM32F10X_CL 305 /* Reset PLL2ON and PLL3ON bits */ 306 RCC->CR &= (uint32_t)0xEBFFFFFF; 307 308 /* Disable all interrupts and clear pending bits */ 309 RCC->CIR = 0x00FF0000; 310 311 /* Reset CFGR2 register */ 312 RCC->CFGR2 = 0x00000000; 313#elif defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) || (defined STM32F10X_HD_VL) 314 /* Disable all interrupts and clear pending bits */ 315 RCC->CIR = 0x009F0000; 316 317 /* Reset CFGR2 register */ 318 RCC->CFGR2 = 0x00000000; 319#else 320 /* Disable all interrupts and clear pending bits */ 321 RCC->CIR = 0x009F0000; 322#endif /* STM32F10X_CL */ 323 324#if defined (STM32F10X_HD) || (defined STM32F10X_XL) || (defined STM32F10X_HD_VL) 325 #ifdef DATA_IN_ExtSRAM 326 SystemInit_ExtMemCtl(); 327 #endif /* DATA_IN_ExtSRAM */ 328#endif 329 330 /* Configure the System clock frequency, HCLK, PCLK2 and PCLK1 prescalers */ 331 /* Configure the Flash Latency cycles and enable prefetch buffer */ 332 SetSysClock(); 333 334#ifdef VECT_TAB_SRAM 335 SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM. */ 336#else 337 SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH. */ 338#endif 339} 340 341/** 342 * @brief Update SystemCoreClock variable according to Clock Register Values. 343 * The SystemCoreClock variable contains the core clock (HCLK), it can 344 * be used by the user application to setup the SysTick timer or configure 345 * other parameters. 346 * 347 * @note Each time the core clock (HCLK) changes, this function must be called 348 * to update SystemCoreClock variable value. Otherwise, any configuration 349 * based on this variable will be incorrect. 350 * 351 * @note - The system frequency computed by this function is not the real 352 * frequency in the chip. It is calculated based on the predefined 353 * constant and the selected clock source: 354 * 355 * - If SYSCLK source is HSI, SystemCoreClock will contain the HSI_VALUE(*) 356 * 357 * - If SYSCLK source is HSE, SystemCoreClock will contain the HSE_VALUE(**) 358 * 359 * - If SYSCLK source is PLL, SystemCoreClock will contain the HSE_VALUE(**) 360 * or HSI_VALUE(*) multiplied by the PLL factors. 361 * 362 * (*) HSI_VALUE is a constant defined in stm32f1xx.h file (default value 363 * 8 MHz) but the real value may vary depending on the variations 364 * in voltage and temperature. 365 * 366 * (**) HSE_VALUE is a constant defined in stm32f1xx.h file (default value 367 * 8 MHz or 25 MHz, depedning on the product used), user has to ensure 368 * that HSE_VALUE is same as the real frequency of the crystal used. 369 * Otherwise, this function may have wrong result. 370 * 371 * - The result of this function could be not correct when using fractional 372 * value for HSE crystal. 373 * @param None 374 * @retval None 375 */ 376void SystemCoreClockUpdate (void) 377{ 378 uint32_t tmp = 0, pllmull = 0, pllsource = 0; 379 380#ifdef STM32F10X_CL 381 uint32_t prediv1source = 0, prediv1factor = 0, prediv2factor = 0, pll2mull = 0; 382#endif /* STM32F10X_CL */ 383 384#if defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) || (defined STM32F10X_HD_VL) 385 uint32_t prediv1factor = 0; 386#endif /* STM32F10X_LD_VL or STM32F10X_MD_VL or STM32F10X_HD_VL */ 387 388 /* Get SYSCLK source -------------------------------------------------------*/ 389 tmp = RCC->CFGR & RCC_CFGR_SWS; 390 391 switch (tmp) 392 { 393 case 0x00: /* HSI used as system clock */ 394 SystemCoreClock = HSI_VALUE; 395 break; 396 case 0x04: /* HSE used as system clock */ 397 SystemCoreClock = HSE_VALUE; 398 break; 399 case 0x08: /* PLL used as system clock */ 400 401 /* Get PLL clock source and multiplication factor ----------------------*/ 402 pllmull = RCC->CFGR & RCC_CFGR_PLLMULL; 403 pllsource = RCC->CFGR & RCC_CFGR_PLLSRC; 404 405#ifndef STM32F10X_CL 406 pllmull = ( pllmull >> 18) + 2; 407 408 if (pllsource == 0x00) 409 { 410 /* HSI oscillator clock divided by 2 selected as PLL clock entry */ 411 SystemCoreClock = (HSI_VALUE >> 1) * pllmull; 412 } 413 else 414 { 415 #if defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) || (defined STM32F10X_HD_VL) 416 prediv1factor = (RCC->CFGR2 & RCC_CFGR2_PREDIV1) + 1; 417 /* HSE oscillator clock selected as PREDIV1 clock entry */ 418 SystemCoreClock = (HSE_VALUE / prediv1factor) * pllmull; 419 #else 420 /* HSE selected as PLL clock entry */ 421 if ((RCC->CFGR & RCC_CFGR_PLLXTPRE) != (uint32_t)RESET) 422 {/* HSE oscillator clock divided by 2 */ 423 SystemCoreClock = (HSE_VALUE >> 1) * pllmull; 424 } 425 else 426 { 427 SystemCoreClock = HSE_VALUE * pllmull; 428 } 429 #endif 430 } 431#else 432 pllmull = pllmull >> 18; 433 434 if (pllmull != 0x0D) 435 { 436 pllmull += 2; 437 } 438 else 439 { /* PLL multiplication factor = PLL input clock * 6.5 */ 440 pllmull = 13 / 2; 441 } 442 443 if (pllsource == 0x00) 444 { 445 /* HSI oscillator clock divided by 2 selected as PLL clock entry */ 446 SystemCoreClock = (HSI_VALUE >> 1) * pllmull; 447 } 448 else 449 {/* PREDIV1 selected as PLL clock entry */ 450 451 /* Get PREDIV1 clock source and division factor */ 452 prediv1source = RCC->CFGR2 & RCC_CFGR2_PREDIV1SRC; 453 prediv1factor = (RCC->CFGR2 & RCC_CFGR2_PREDIV1) + 1; 454 455 if (prediv1source == 0) 456 { 457 /* HSE oscillator clock selected as PREDIV1 clock entry */ 458 SystemCoreClock = (HSE_VALUE / prediv1factor) * pllmull; 459 } 460 else 461 {/* PLL2 clock selected as PREDIV1 clock entry */ 462 463 /* Get PREDIV2 division factor and PLL2 multiplication factor */ 464 prediv2factor = ((RCC->CFGR2 & RCC_CFGR2_PREDIV2) >> 4) + 1; 465 pll2mull = ((RCC->CFGR2 & RCC_CFGR2_PLL2MUL) >> 8 ) + 2; 466 SystemCoreClock = (((HSE_VALUE / prediv2factor) * pll2mull) / prediv1factor) * pllmull; 467 } 468 } 469#endif /* STM32F10X_CL */ 470 break; 471 472 default: 473 SystemCoreClock = HSI_VALUE; 474 break; 475 } 476 477 /* Compute HCLK clock frequency ----------------*/ 478 /* Get HCLK prescaler */ 479 tmp = AHBPrescTable[((RCC->CFGR & RCC_CFGR_HPRE) >> 4)]; 480 /* HCLK clock frequency */ 481 SystemCoreClock >>= tmp; 482} 483 484/** 485 * @brief Configures the System clock frequency, HCLK, PCLK2 and PCLK1 prescalers. 486 * @param None 487 * @retval None 488 */ 489static void SetSysClock(void) 490{ 491#ifdef SYSCLK_FREQ_HSE 492 SetSysClockToHSE(); 493#elif defined SYSCLK_FREQ_24MHz 494 SetSysClockTo24(); 495#elif defined SYSCLK_FREQ_36MHz 496 SetSysClockTo36(); 497#elif defined SYSCLK_FREQ_48MHz 498 SetSysClockTo48(); 499#elif defined SYSCLK_FREQ_56MHz 500 SetSysClockTo56(); 501#elif defined SYSCLK_FREQ_72MHz 502 SetSysClockTo72(); 503#endif 504 505 /* If none of the define above is enabled, the HSI is used as System clock 506 source (default after reset) */ 507} 508 509/** 510 * @brief Setup the external memory controller. Called in startup_stm32f10x.s 511 * before jump to __main 512 * @param None 513 * @retval None 514 */ 515#ifdef DATA_IN_ExtSRAM 516/** 517 * @brief Setup the external memory controller. 518 * Called in startup_stm32f10x_xx.s/.c before jump to main. 519 * This function configures the external SRAM mounted on STM3210E-EVAL 520 * board (STM32 High density devices). This SRAM will be used as program 521 * data memory (including heap and stack). 522 * @param None 523 * @retval None 524 */ 525void SystemInit_ExtMemCtl(void) 526{ 527/*!< FSMC Bank1 NOR/SRAM3 is used for the STM3210E-EVAL, if another Bank is 528 required, then adjust the Register Addresses */ 529 530 /* Enable FSMC clock */ 531 RCC->AHBENR = 0x00000114; 532 533 /* Enable GPIOD, GPIOE, GPIOF and GPIOG clocks */ 534 RCC->APB2ENR = 0x000001E0; 535 536/* --------------- SRAM Data lines, NOE and NWE configuration ---------------*/ 537/*---------------- SRAM Address lines configuration -------------------------*/ 538/*---------------- NOE and NWE configuration --------------------------------*/ 539/*---------------- NE3 configuration ----------------------------------------*/ 540/*---------------- NBL0, NBL1 configuration ---------------------------------*/ 541 542 GPIOD->CRL = 0x44BB44BB; 543 GPIOD->CRH = 0xBBBBBBBB; 544 545 GPIOE->CRL = 0xB44444BB; 546 GPIOE->CRH = 0xBBBBBBBB; 547 548 GPIOF->CRL = 0x44BBBBBB; 549 GPIOF->CRH = 0xBBBB4444; 550 551 GPIOG->CRL = 0x44BBBBBB; 552 GPIOG->CRH = 0x44444B44; 553 554/*---------------- FSMC Configuration ---------------------------------------*/ 555/*---------------- Enable FSMC Bank1_SRAM Bank ------------------------------*/ 556 557 FSMC_Bank1->BTCR[4] = 0x00001011; 558 FSMC_Bank1->BTCR[5] = 0x00000200; 559} 560#endif /* DATA_IN_ExtSRAM */ 561 562#ifdef SYSCLK_FREQ_HSE 563/** 564 * @brief Selects HSE as System clock source and configure HCLK, PCLK2 565 * and PCLK1 prescalers. 566 * @note This function should be used only after reset. 567 * @param None 568 * @retval None 569 */ 570static void SetSysClockToHSE(void) 571{ 572 __IO uint32_t StartUpCounter = 0, HSEStatus = 0; 573 574 /* SYSCLK, HCLK, PCLK2 and PCLK1 configuration ---------------------------*/ 575 /* Enable HSE */ 576 RCC->CR |= ((uint32_t)RCC_CR_HSEON); 577 578 /* Wait till HSE is ready and if Time out is reached exit */ 579 do 580 { 581 HSEStatus = RCC->CR & RCC_CR_HSERDY; 582 StartUpCounter++; 583 } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT)); 584 585 if ((RCC->CR & RCC_CR_HSERDY) != RESET) 586 { 587 HSEStatus = (uint32_t)0x01; 588 } 589 else 590 { 591 HSEStatus = (uint32_t)0x00; 592 } 593 594 if (HSEStatus == (uint32_t)0x01) 595 { 596 597#if !defined STM32F10X_LD_VL && !defined STM32F10X_MD_VL && !defined STM32F10X_HD_VL 598 /* Enable Prefetch Buffer */ 599 FLASH->ACR |= FLASH_ACR_PRFTBE; 600 601 /* Flash 0 wait state */ 602 FLASH->ACR &= (uint32_t)((uint32_t)~FLASH_ACR_LATENCY); 603 604#ifndef STM32F10X_CL 605 FLASH->ACR |= (uint32_t)FLASH_ACR_LATENCY_0; 606#else 607 if (HSE_VALUE <= 24000000) 608 { 609 FLASH->ACR |= (uint32_t)FLASH_ACR_LATENCY_0; 610 } 611 else 612 { 613 FLASH->ACR |= (uint32_t)FLASH_ACR_LATENCY_1; 614 } 615#endif /* STM32F10X_CL */ 616#endif 617 618 /* HCLK = SYSCLK */ 619 RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1; 620 621 /* PCLK2 = HCLK */ 622 RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1; 623 624 /* PCLK1 = HCLK */ 625 RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV1; 626 627 /* Select HSE as system clock source */ 628 RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW)); 629 RCC->CFGR |= (uint32_t)RCC_CFGR_SW_HSE; 630 631 /* Wait till HSE is used as system clock source */ 632 while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)0x04) 633 { 634 } 635 } 636 else 637 { /* If HSE fails to start-up, the application will have wrong clock 638 configuration. User can add here some code to deal with this error */ 639 } 640} 641#elif defined SYSCLK_FREQ_24MHz 642/** 643 * @brief Sets System clock frequency to 24MHz and configure HCLK, PCLK2 644 * and PCLK1 prescalers. 645 * @note This function should be used only after reset. 646 * @param None 647 * @retval None 648 */ 649static void SetSysClockTo24(void) 650{ 651 __IO uint32_t StartUpCounter = 0, HSEStatus = 0; 652 653 /* SYSCLK, HCLK, PCLK2 and PCLK1 configuration ---------------------------*/ 654 /* Enable HSE */ 655 RCC->CR |= ((uint32_t)RCC_CR_HSEON); 656 657 /* Wait till HSE is ready and if Time out is reached exit */ 658 do 659 { 660 HSEStatus = RCC->CR & RCC_CR_HSERDY; 661 StartUpCounter++; 662 } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT)); 663 664 if ((RCC->CR & RCC_CR_HSERDY) != RESET) 665 { 666 HSEStatus = (uint32_t)0x01; 667 } 668 else 669 { 670 HSEStatus = (uint32_t)0x00; 671 } 672 673 if (HSEStatus == (uint32_t)0x01) 674 { 675#if !defined STM32F10X_LD_VL && !defined STM32F10X_MD_VL && !defined STM32F10X_HD_VL 676 /* Enable Prefetch Buffer */ 677 FLASH->ACR |= FLASH_ACR_PRFTBE; 678 679 /* Flash 0 wait state */ 680 FLASH->ACR &= (uint32_t)((uint32_t)~FLASH_ACR_LATENCY); 681 FLASH->ACR |= (uint32_t)FLASH_ACR_LATENCY_0; 682#endif 683 684 /* HCLK = SYSCLK */ 685 RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1; 686 687 /* PCLK2 = HCLK */ 688 RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1; 689 690 /* PCLK1 = HCLK */ 691 RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV1; 692 693#ifdef STM32F10X_CL 694 /* Configure PLLs ------------------------------------------------------*/ 695 /* PLL configuration: PLLCLK = PREDIV1 * 6 = 24 MHz */ 696 RCC->CFGR &= (uint32_t)~(RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLSRC | RCC_CFGR_PLLMULL); 697 RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLXTPRE_PREDIV1 | RCC_CFGR_PLLSRC_PREDIV1 | 698 RCC_CFGR_PLLMULL6); 699 700 /* PLL2 configuration: PLL2CLK = (HSE / 5) * 8 = 40 MHz */ 701 /* PREDIV1 configuration: PREDIV1CLK = PLL2 / 10 = 4 MHz */ 702 RCC->CFGR2 &= (uint32_t)~(RCC_CFGR2_PREDIV2 | RCC_CFGR2_PLL2MUL | 703 RCC_CFGR2_PREDIV1 | RCC_CFGR2_PREDIV1SRC); 704 RCC->CFGR2 |= (uint32_t)(RCC_CFGR2_PREDIV2_DIV5 | RCC_CFGR2_PLL2MUL8 | 705 RCC_CFGR2_PREDIV1SRC_PLL2 | RCC_CFGR2_PREDIV1_DIV10); 706 707 /* Enable PLL2 */ 708 RCC->CR |= RCC_CR_PLL2ON; 709 /* Wait till PLL2 is ready */ 710 while((RCC->CR & RCC_CR_PLL2RDY) == 0) 711 { 712 } 713#elif defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) || defined (STM32F10X_HD_VL) 714 /* PLL configuration: = (HSE / 2) * 6 = 24 MHz */ 715 RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLMULL)); 716 RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_PREDIV1 | RCC_CFGR_PLLXTPRE_PREDIV1_Div2 | RCC_CFGR_PLLMULL6); 717#else 718 /* PLL configuration: = (HSE / 2) * 6 = 24 MHz */ 719 RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLMULL)); 720 RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_HSE | RCC_CFGR_PLLXTPRE_HSE_Div2 | RCC_CFGR_PLLMULL6); 721#endif /* STM32F10X_CL */ 722 723 /* Enable PLL */ 724 RCC->CR |= RCC_CR_PLLON; 725 726 /* Wait till PLL is ready */ 727 while((RCC->CR & RCC_CR_PLLRDY) == 0) 728 { 729 } 730 731 /* Select PLL as system clock source */ 732 RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW)); 733 RCC->CFGR |= (uint32_t)RCC_CFGR_SW_PLL; 734 735 /* Wait till PLL is used as system clock source */ 736 while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)0x08) 737 { 738 } 739 } 740 else 741 { /* If HSE fails to start-up, the application will have wrong clock 742 configuration. User can add here some code to deal with this error */ 743 } 744} 745#elif defined SYSCLK_FREQ_36MHz 746/** 747 * @brief Sets System clock frequency to 36MHz and configure HCLK, PCLK2 748 * and PCLK1 prescalers. 749 * @note This function should be used only after reset. 750 * @param None 751 * @retval None 752 */ 753static void SetSysClockTo36(void) 754{ 755 __IO uint32_t StartUpCounter = 0, HSEStatus = 0; 756 757 /* SYSCLK, HCLK, PCLK2 and PCLK1 configuration ---------------------------*/ 758 /* Enable HSE */ 759 RCC->CR |= ((uint32_t)RCC_CR_HSEON); 760 761 /* Wait till HSE is ready and if Time out is reached exit */ 762 do 763 { 764 HSEStatus = RCC->CR & RCC_CR_HSERDY; 765 StartUpCounter++; 766 } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT)); 767 768 if ((RCC->CR & RCC_CR_HSERDY) != RESET) 769 { 770 HSEStatus = (uint32_t)0x01; 771 } 772 else 773 { 774 HSEStatus = (uint32_t)0x00; 775 } 776 777 if (HSEStatus == (uint32_t)0x01) 778 { 779 /* Enable Prefetch Buffer */ 780 FLASH->ACR |= FLASH_ACR_PRFTBE; 781 782 /* Flash 1 wait state */ 783 FLASH->ACR &= (uint32_t)((uint32_t)~FLASH_ACR_LATENCY); 784 FLASH->ACR |= (uint32_t)FLASH_ACR_LATENCY_1; 785 786 /* HCLK = SYSCLK */ 787 RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1; 788 789 /* PCLK2 = HCLK */ 790 RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1; 791 792 /* PCLK1 = HCLK */ 793 RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV1; 794 795#ifdef STM32F10X_CL 796 /* Configure PLLs ------------------------------------------------------*/ 797 798 /* PLL configuration: PLLCLK = PREDIV1 * 9 = 36 MHz */ 799 RCC->CFGR &= (uint32_t)~(RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLSRC | RCC_CFGR_PLLMULL); 800 RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLXTPRE_PREDIV1 | RCC_CFGR_PLLSRC_PREDIV1 | 801 RCC_CFGR_PLLMULL9); 802 803 /*!< PLL2 configuration: PLL2CLK = (HSE / 5) * 8 = 40 MHz */ 804 /* PREDIV1 configuration: PREDIV1CLK = PLL2 / 10 = 4 MHz */ 805 806 RCC->CFGR2 &= (uint32_t)~(RCC_CFGR2_PREDIV2 | RCC_CFGR2_PLL2MUL | 807 RCC_CFGR2_PREDIV1 | RCC_CFGR2_PREDIV1SRC); 808 RCC->CFGR2 |= (uint32_t)(RCC_CFGR2_PREDIV2_DIV5 | RCC_CFGR2_PLL2MUL8 | 809 RCC_CFGR2_PREDIV1SRC_PLL2 | RCC_CFGR2_PREDIV1_DIV10); 810 811 /* Enable PLL2 */ 812 RCC->CR |= RCC_CR_PLL2ON; 813 /* Wait till PLL2 is ready */ 814 while((RCC->CR & RCC_CR_PLL2RDY) == 0) 815 { 816 } 817 818#else 819 /* PLL configuration: PLLCLK = (HSE / 2) * 9 = 36 MHz */ 820 RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLMULL)); 821 RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_HSE | RCC_CFGR_PLLXTPRE_HSE_Div2 | RCC_CFGR_PLLMULL9); 822#endif /* STM32F10X_CL */ 823 824 /* Enable PLL */ 825 RCC->CR |= RCC_CR_PLLON; 826 827 /* Wait till PLL is ready */ 828 while((RCC->CR & RCC_CR_PLLRDY) == 0) 829 { 830 } 831 832 /* Select PLL as system clock source */ 833 RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW)); 834 RCC->CFGR |= (uint32_t)RCC_CFGR_SW_PLL; 835 836 /* Wait till PLL is used as system clock source */ 837 while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)0x08) 838 { 839 } 840 } 841 else 842 { /* If HSE fails to start-up, the application will have wrong clock 843 configuration. User can add here some code to deal with this error */ 844 } 845} 846#elif defined SYSCLK_FREQ_48MHz 847/** 848 * @brief Sets System clock frequency to 48MHz and configure HCLK, PCLK2 849 * and PCLK1 prescalers. 850 * @note This function should be used only after reset. 851 * @param None 852 * @retval None 853 */ 854static void SetSysClockTo48(void) 855{ 856 __IO uint32_t StartUpCounter = 0, HSEStatus = 0; 857 858 /* SYSCLK, HCLK, PCLK2 and PCLK1 configuration ---------------------------*/ 859 /* Enable HSE */ 860 RCC->CR |= ((uint32_t)RCC_CR_HSEON); 861 862 /* Wait till HSE is ready and if Time out is reached exit */ 863 do 864 { 865 HSEStatus = RCC->CR & RCC_CR_HSERDY; 866 StartUpCounter++; 867 } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT)); 868 869 if ((RCC->CR & RCC_CR_HSERDY) != RESET) 870 { 871 HSEStatus = (uint32_t)0x01; 872 } 873 else 874 { 875 HSEStatus = (uint32_t)0x00; 876 } 877 878 if (HSEStatus == (uint32_t)0x01) 879 { 880 /* Enable Prefetch Buffer */ 881 FLASH->ACR |= FLASH_ACR_PRFTBE; 882 883 /* Flash 1 wait state */ 884 FLASH->ACR &= (uint32_t)((uint32_t)~FLASH_ACR_LATENCY); 885 FLASH->ACR |= (uint32_t)FLASH_ACR_LATENCY_1; 886 887 /* HCLK = SYSCLK */ 888 RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1; 889 890 /* PCLK2 = HCLK */ 891 RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1; 892 893 /* PCLK1 = HCLK */ 894 RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV2; 895 896#ifdef STM32F10X_CL 897 /* Configure PLLs ------------------------------------------------------*/ 898 /* PLL2 configuration: PLL2CLK = (HSE / 5) * 8 = 40 MHz */ 899 /* PREDIV1 configuration: PREDIV1CLK = PLL2 / 5 = 8 MHz */ 900 901 RCC->CFGR2 &= (uint32_t)~(RCC_CFGR2_PREDIV2 | RCC_CFGR2_PLL2MUL | 902 RCC_CFGR2_PREDIV1 | RCC_CFGR2_PREDIV1SRC); 903 RCC->CFGR2 |= (uint32_t)(RCC_CFGR2_PREDIV2_DIV5 | RCC_CFGR2_PLL2MUL8 | 904 RCC_CFGR2_PREDIV1SRC_PLL2 | RCC_CFGR2_PREDIV1_DIV5); 905 906 /* Enable PLL2 */ 907 RCC->CR |= RCC_CR_PLL2ON; 908 /* Wait till PLL2 is ready */ 909 while((RCC->CR & RCC_CR_PLL2RDY) == 0) 910 { 911 } 912 913 914 /* PLL configuration: PLLCLK = PREDIV1 * 6 = 48 MHz */ 915 RCC->CFGR &= (uint32_t)~(RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLSRC | RCC_CFGR_PLLMULL); 916 RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLXTPRE_PREDIV1 | RCC_CFGR_PLLSRC_PREDIV1 | 917 RCC_CFGR_PLLMULL6); 918#else 919 /* PLL configuration: PLLCLK = HSE * 6 = 48 MHz */ 920 RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLMULL)); 921 RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_HSE | RCC_CFGR_PLLMULL6); 922#endif /* STM32F10X_CL */ 923 924 /* Enable PLL */ 925 RCC->CR |= RCC_CR_PLLON; 926 927 /* Wait till PLL is ready */ 928 while((RCC->CR & RCC_CR_PLLRDY) == 0) 929 { 930 } 931 932 /* Select PLL as system clock source */ 933 RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW)); 934 RCC->CFGR |= (uint32_t)RCC_CFGR_SW_PLL; 935 936 /* Wait till PLL is used as system clock source */ 937 while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)0x08) 938 { 939 } 940 } 941 else 942 { /* If HSE fails to start-up, the application will have wrong clock 943 configuration. User can add here some code to deal with this error */ 944 } 945} 946 947#elif defined SYSCLK_FREQ_56MHz 948/** 949 * @brief Sets System clock frequency to 56MHz and configure HCLK, PCLK2 950 * and PCLK1 prescalers. 951 * @note This function should be used only after reset. 952 * @param None 953 * @retval None 954 */ 955static void SetSysClockTo56(void) 956{ 957 __IO uint32_t StartUpCounter = 0, HSEStatus = 0; 958 959 /* SYSCLK, HCLK, PCLK2 and PCLK1 configuration ---------------------------*/ 960 /* Enable HSE */ 961 RCC->CR |= ((uint32_t)RCC_CR_HSEON); 962 963 /* Wait till HSE is ready and if Time out is reached exit */ 964 do 965 { 966 HSEStatus = RCC->CR & RCC_CR_HSERDY; 967 StartUpCounter++; 968 } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT)); 969 970 if ((RCC->CR & RCC_CR_HSERDY) != RESET) 971 { 972 HSEStatus = (uint32_t)0x01; 973 } 974 else 975 { 976 HSEStatus = (uint32_t)0x00; 977 } 978 979 if (HSEStatus == (uint32_t)0x01) 980 { 981 /* Enable Prefetch Buffer */ 982 FLASH->ACR |= FLASH_ACR_PRFTBE; 983 984 /* Flash 2 wait state */ 985 FLASH->ACR &= (uint32_t)((uint32_t)~FLASH_ACR_LATENCY); 986 FLASH->ACR |= (uint32_t)FLASH_ACR_LATENCY_2; 987 988 /* HCLK = SYSCLK */ 989 RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1; 990 991 /* PCLK2 = HCLK */ 992 RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1; 993 994 /* PCLK1 = HCLK */ 995 RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV2; 996 997#ifdef STM32F10X_CL 998 /* Configure PLLs ------------------------------------------------------*/ 999 /* PLL2 configuration: PLL2CLK = (HSE / 5) * 8 = 40 MHz */ 1000 /* PREDIV1 configuration: PREDIV1CLK = PLL2 / 5 = 8 MHz */ 1001 1002 RCC->CFGR2 &= (uint32_t)~(RCC_CFGR2_PREDIV2 | RCC_CFGR2_PLL2MUL | 1003 RCC_CFGR2_PREDIV1 | RCC_CFGR2_PREDIV1SRC); 1004 RCC->CFGR2 |= (uint32_t)(RCC_CFGR2_PREDIV2_DIV5 | RCC_CFGR2_PLL2MUL8 | 1005 RCC_CFGR2_PREDIV1SRC_PLL2 | RCC_CFGR2_PREDIV1_DIV5); 1006 1007 /* Enable PLL2 */ 1008 RCC->CR |= RCC_CR_PLL2ON; 1009 /* Wait till PLL2 is ready */ 1010 while((RCC->CR & RCC_CR_PLL2RDY) == 0) 1011 { 1012 } 1013 1014 1015 /* PLL configuration: PLLCLK = PREDIV1 * 7 = 56 MHz */ 1016 RCC->CFGR &= (uint32_t)~(RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLSRC | RCC_CFGR_PLLMULL); 1017 RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLXTPRE_PREDIV1 | RCC_CFGR_PLLSRC_PREDIV1 | 1018 RCC_CFGR_PLLMULL7); 1019#else 1020 /* PLL configuration: PLLCLK = HSE * 7 = 56 MHz */ 1021 RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLMULL)); 1022 RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_HSE | RCC_CFGR_PLLMULL7); 1023 1024#endif /* STM32F10X_CL */ 1025 1026 /* Enable PLL */ 1027 RCC->CR |= RCC_CR_PLLON; 1028 1029 /* Wait till PLL is ready */ 1030 while((RCC->CR & RCC_CR_PLLRDY) == 0) 1031 { 1032 } 1033 1034 /* Select PLL as system clock source */ 1035 RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW)); 1036 RCC->CFGR |= (uint32_t)RCC_CFGR_SW_PLL; 1037 1038 /* Wait till PLL is used as system clock source */ 1039 while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)0x08) 1040 { 1041 } 1042 } 1043 else 1044 { /* If HSE fails to start-up, the application will have wrong clock 1045 configuration. User can add here some code to deal with this error */ 1046 } 1047} 1048 1049#elif defined SYSCLK_FREQ_72MHz 1050/** 1051 * @brief Sets System clock frequency to 72MHz and configure HCLK, PCLK2 1052 * and PCLK1 prescalers. 1053 * @note This function should be used only after reset. 1054 * @param None 1055 * @retval None 1056 */ 1057static void SetSysClockTo72(void) 1058{ 1059 __IO uint32_t StartUpCounter = 0, HSEStatus = 0; 1060 1061 /* SYSCLK, HCLK, PCLK2 and PCLK1 configuration ---------------------------*/ 1062 /* Enable HSE */ 1063 RCC->CR |= ((uint32_t)RCC_CR_HSEON); 1064 1065 /* Wait till HSE is ready and if Time out is reached exit */ 1066 do 1067 { 1068 HSEStatus = RCC->CR & RCC_CR_HSERDY; 1069 StartUpCounter++; 1070 } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT)); 1071 1072 if ((RCC->CR & RCC_CR_HSERDY) != RESET) 1073 { 1074 HSEStatus = (uint32_t)0x01; 1075 } 1076 else 1077 { 1078 HSEStatus = (uint32_t)0x00; 1079 } 1080 1081 if (HSEStatus == (uint32_t)0x01) 1082 { 1083 /* Enable Prefetch Buffer */ 1084 FLASH->ACR |= FLASH_ACR_PRFTBE; 1085 1086 /* Flash 2 wait state */ 1087 FLASH->ACR &= (uint32_t)((uint32_t)~FLASH_ACR_LATENCY); 1088 FLASH->ACR |= (uint32_t)FLASH_ACR_LATENCY_2; 1089 1090 1091 /* HCLK = SYSCLK */ 1092 RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1; 1093 1094 /* PCLK2 = HCLK */ 1095 RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1; 1096 1097 /* PCLK1 = HCLK */ 1098 RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV2; 1099 1100#ifdef STM32F10X_CL 1101 /* Configure PLLs ------------------------------------------------------*/ 1102 /* PLL2 configuration: PLL2CLK = (HSE / 5) * 8 = 40 MHz */ 1103 /* PREDIV1 configuration: PREDIV1CLK = PLL2 / 5 = 8 MHz */ 1104 1105 RCC->CFGR2 &= (uint32_t)~(RCC_CFGR2_PREDIV2 | RCC_CFGR2_PLL2MUL | 1106 RCC_CFGR2_PREDIV1 | RCC_CFGR2_PREDIV1SRC); 1107 RCC->CFGR2 |= (uint32_t)(RCC_CFGR2_PREDIV2_DIV5 | RCC_CFGR2_PLL2MUL8 | 1108 RCC_CFGR2_PREDIV1SRC_PLL2 | RCC_CFGR2_PREDIV1_DIV5); 1109 1110 /* Enable PLL2 */ 1111 RCC->CR |= RCC_CR_PLL2ON; 1112 /* Wait till PLL2 is ready */ 1113 while((RCC->CR & RCC_CR_PLL2RDY) == 0) 1114 { 1115 } 1116 1117 1118 /* PLL configuration: PLLCLK = PREDIV1 * 9 = 72 MHz */ 1119 RCC->CFGR &= (uint32_t)~(RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLSRC | RCC_CFGR_PLLMULL); 1120 RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLXTPRE_PREDIV1 | RCC_CFGR_PLLSRC_PREDIV1 | 1121 RCC_CFGR_PLLMULL9); 1122#else 1123 /* PLL configuration: PLLCLK = HSE * 9 = 72 MHz */ 1124 RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE | 1125 RCC_CFGR_PLLMULL)); 1126 RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_HSE | RCC_CFGR_PLLMULL9); 1127#endif /* STM32F10X_CL */ 1128 1129 /* Enable PLL */ 1130 RCC->CR |= RCC_CR_PLLON; 1131 1132 /* Wait till PLL is ready */ 1133 while((RCC->CR & RCC_CR_PLLRDY) == 0) 1134 { 1135 } 1136 1137 /* Select PLL as system clock source */ 1138 RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW)); 1139 RCC->CFGR |= (uint32_t)RCC_CFGR_SW_PLL; 1140 1141 /* Wait till PLL is used as system clock source */ 1142 while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)0x08) 1143 { 1144 } 1145 } 1146 else 1147 { /* If HSE fails to start-up, the application will have wrong clock 1148 configuration. User can add here some code to deal with this error */ 1149 } 1150} 1151#endif 1152 1153/** 1154 * @} 1155 */ 1156 1157/** 1158 * @} 1159 */ 1160 1161/** 1162 * @} 1163 */ 1164/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
点赞
收藏

评论区

加载中...

相关推荐

MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1

文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s

Oracle 分组与拼接字符串同时使用

SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(

MySQL部分从库上面因为大量的临时表tmp_table造成慢查询

背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_

皕杰报表之UUID

​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为

手写Java HashMap源码

HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22

2020年前端实用代码段,为你的工作保驾护航

有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )

STM32_3 时钟初始化分析 - HelloWorld