先上代码
 __IO uint32_t StartUpCounter = 0, HSIStatus = 0;
   RCC->CR |=((uint32_t)RCC_CR_HSION);
   do
   {
           HSIStatus = RCC->CR & RCC_CR_HSIRDY;
           StartUpCounter++;       
   }while((HSIStatus == 0) && (StartUpCounter != HSI_STARTUP_TIMEOUT));
   if(RCC->CR & RCC_CR_HSIRDY)
   {
           HSIStatus = 0x01;
   }
   else
   {
           HSIStatus = 0x00;
   }
   if(HSIStatus == 0x01)
   {
  /* Enable Prefetch Buffer and set Flash Latency */
  FLASH->ACR = FLASH_ACR_PRFTBE | FLASH_ACR_LATENCY;
  /* HCLK = SYSCLK */
  RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1;
  
  /* PCLK = HCLK */
  RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE_DIV1;
  /* PLL configuration = HSI * 6 = 48 MHz */
  RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLMULL));
  RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_HSI_PREDIV | RCC_CFGR_PLLMULL6);
     
  /* Enable PLL */
  RCC->CR |= RCC_CR_PLLON;
  /* Wait till PLL is ready */
  while((RCC->CR & RCC_CR_PLLRDY) == 0)
  {
  }
  /* Select PLL as system clock source */
  RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));
  RCC->CFGR |= (uint32_t)RCC_CFGR_SW_PLL;  
  /* Wait till PLL is used as system clock source */
  while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)RCC_CFGR_SWS_PLL)
  {
  }
       
   }
接着来说明下,
很多人拿到官方的例程代码里面的时钟配置是基于使用外部晶振的,但是为了节省成本,所以很多人都选择使用内部RC,
下面是内部RC的配置流程,
首先配置
   RCC->CR |=((uint32_t)RCC_CR_HSION);
开启内部时钟,
在开启内部时钟之后,那么要等待内部时钟就绪,
   do
   {
           HSIStatus = RCC->CR & RCC_CR_HSIRDY;
           StartUpCounter++;       
   }while((HSIStatus == 0) && (StartUpCounter != HSI_STARTUP_TIMEOUT));
   if(RCC->CR & RCC_CR_HSIRDY)
   {
           HSIStatus = 0x01;
   }
   else
   {
           HSIStatus = 0x00;
   }
并设置好状态,
  /* Enable Prefetch Buffer and set Flash Latency */
  FLASH->ACR = FLASH_ACR_PRFTBE | FLASH_ACR_LATENCY;
  /* HCLK = SYSCLK */
  RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1;
  
  /* PCLK = HCLK */
  RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE_DIV1;
这一部分的代码是和外部晶振的代码配置一样的,
 RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_HSI_PREDIV | RCC_CFGR_PLLMULL6);
关键代码是这一句,
而配置外部时钟的时候
RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_PREDIV1 | RCC_CFGR_PLLXTPRE_PREDIV1 | RCC_CFGR_PLLMULL6);
语句是这样的,很多人都以为,
只要修改为内部时钟即可,但是很多的代码都是在PLL开启的时候限入死循环,
  /* Wait till PLL is ready */
  while((RCC->CR & RCC_CR_PLLRDY) == 0)
  {
  }
死在这里,
死在这里的原因是什么呢,
RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_PREDIV1 | RCC_CFGR_PLLXTPRE_PREDIV1 | RCC_CFGR_PLLMULL6);
的解释如下,,,RCC_CFGR_PLLXTPRE_PREDIV1
这一句说的是,PLLCLK INPUT的来源外部晶振,所以,这里不对,
那么要使用内部晶振的配置
RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_HSI_PREDIV | RCC_CFGR_PLLMULL6);
是这样的,这样的配置是,PLL的来源是来自内部晶振,而且这个来源的时钟不是通过2分频的,所以直接是通过8M来倍频的,
所以6X8是等于48M的,

