void RCC_Configuration(void) { RCC_DeInit(); RCC_HSICmd(ENABLE); while(RCC_GetFlagStatus(RCC_FLAG_HSIRDY) == RESET) {} if(1) { /* Enable Prefetch Buffer */ FLASH->ACR |= FLASH_ACR_PRFTBE; /* Flash 2 wait state */ FLASH->ACR &= (uint32_t)((uint32_t)~FLASH_ACR_LATENCY); FLASH->ACR |= (uint32_t)FLASH_ACR_LATENCY_2; /* HCLK = SYSCLK */ RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1; /* PCLK2 = HCLK */ RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1; /* PCLK1 = HCLK */ RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV2; //Configure PLLs RCC_PLLConfig(RCC_PLLSource_HSI_Div2, RCC_PLLMul_16); //Enable PLL2 RCC_PLLCmd(ENABLE); //Wait till PLL2 is ready while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET) { } //Select PLL as system clock source RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK); //Wait till PLL is used as system clock source // 0x00:HSI // 0x04:HSE // 0x08:PLL while(RCC_GetSYSCLKSource() != 0x08) { } } }
通过这个代码在对比SystemInit函数对系统初始化的整个过程就清楚许多。我们先看这个HSI作为时钟源的初始化过程,首先调用RCC_DeInit()将外设rcc寄存器设置为缺省值,就是将系统时钟从新设置为默认方式,这样就将系统恢复为HSI时钟,然后使能HSI时钟(这个使能其实有点多余,因为去掉之后也根本没有作用,但是对于SystemInit函数的理解具有一定的作用),然后系统等待时钟的启动完毕,HSI时钟启动之后就开始进入系统其他时钟总线的设置,前面是flash的设置(具体含义不太明白),在系统设置中也有相同的设置,然后设置HCLK=sysclk,系统时钟的分频系数,然后分别设置PLCK2、PLCK1,这三个就是我们的系统时钟、APB2时钟、APB1时钟的分频系数的设置,然后设置PLL,设置锁相环时钟来源以及倍频系数,这里设置的是HSI二分频作为时钟源,16倍频,设置之后对PLL锁相环进行使能,等待PLL启动完成,设置锁相环作为时钟源,最后等待设置成功。这就是整个设置的过程。而SystemInit()函数的设置过程与上面的一致,只是在程序直观表达上不太容易理解,下面就是SystemInit函数的代码我们可以通过第一个设置代码来理解这个系统时钟的初始化过程。
void SystemInit (void) { /* Reset the RCC clock configuration to the default reset state(for debug purpose) */ /* Set HSION bit */ RCC->CR |= (uint32_t)0x00000001; /* Reset SW, HPRE, PPRE1, PPRE2, ADCPRE and MCO bits */ #ifndef STM32F10X_CL RCC->CFGR &= (uint32_t)0xF8FF0000; #else RCC->CFGR &= (uint32_t)0xF0FF0000; #endif /* STM32F10X_CL */ /* Reset HSEON, CSSON and PLLON bits */ RCC->CR &= (uint32_t)0xFEF6FFFF; /* Reset HSEBYP bit */ RCC->CR &= (uint32_t)0xFFFBFFFF; /* Reset PLLSRC, PLLXTPRE, PLLMUL and USBPRE/OTGFSPRE bits */ RCC->CFGR &= (uint32_t)0xFF80FFFF; #ifdef STM32F10X_CL /* Reset PLL2ON and PLL3ON bits */ RCC->CR &= (uint32_t)0xEBFFFFFF; /* Disable all interrupts and clear pending bits */ RCC->CIR = 0x00FF0000; /* Reset CFGR2 register */ RCC->CFGR2 = 0x00000000; #elif defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) || (defined STM32F10X_HD_VL) /* Disable all interrupts and clear pending bits */ RCC->CIR = 0x009F0000; /* Reset CFGR2 register */ RCC->CFGR2 = 0x00000000; #else /* Disable all interrupts and clear pending bits */ RCC->CIR = 0x009F0000; #endif /* STM32F10X_CL */ #if defined (STM32F10X_HD) || (defined STM32F10X_XL) || (defined STM32F10X_HD_VL) #ifdef DATA_IN_ExtSRAM SystemInit_ExtMemCtl(); #endif /* DATA_IN_ExtSRAM */ #endif /* Configure the System clock frequency, HCLK, PCLK2 and PCLK1 prescalers */ /* Configure the Flash Latency cycles and enable prefetch buffer */ SetSysClock(); #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 }