system_stm32f10x.c文件了解

上接:https://www.cnblogs.com/otaganyuki/p/10310979.html

前面一些宏定义略过,但有一个后面用到提下

system_stm32f10x.c文件了解

这里定义了系统时钟频率为72mhz

从SystemInit开始讲,寄存器和时钟树参照stm32参考手册即可

system_stm32f10x.c文件了解

void SystemInit (void)

{

  /* Reset the RCC clock configuration to the default reset state(for debug purpose) */

  /* Set HSION bit */

  RCC->CR |= (uint32_t)0x00000001;//打开内部8MHz振荡器

 

  /* Reset SW, HPRE, PPRE1, PPRE2, ADCPRE and MCO bits
    SW 00:HSI设为系统时钟
   ADCPRE 00:ADC的时钟预分频设置为2
   PPRE2 000:APB2预分频器设置为1
   PPRE1 000:APB1预分频设置为1
   HPRE  000:AHB预分频设置为1
   MCO    00:MCO时钟输出设为无
  */

#ifndef STM32F10X_CL //CL就是类似HD的单片机型号选择

  RCC->CFGR &= (uint32_t)0xF8FF0000;

#else

  RCC->CFGR &= (uint32_t)0xF0FF0000;

#endif /* STM32F10X_CL */  

 

  /* Reset HSEON, CSSON and PLLON bits
    PLLON 0:关闭PLL
   CSSON 0:Clock detector OFF 
   HSEON 0: HSE oscillator OFF 
  */

  RCC->CR &= (uint32_t)0xFEF6FFFF;

 

  /* Reset HSEBYP bit
     0: external 4-16 MHz oscillator not bypassed 使用外部晶振
  */

  RCC->CR &= (uint32_t)0xFFFBFFFF;

 

  /* Reset PLLSRC, PLLXTPRE, PLLMUL and USBPRE/OTGFSPRE bits
   PLLSRC 0: HSI oscillator clock / 2 selected as PLL input clock 
   PLLXTPRE 0: HSE clock not divided 
   PLLMUL 0000: PLL input clock x 2 
 */

  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

}

system_stm32f10x.c文件了解

 SetSysClock函数 我这边时默认执行SetSysClockTo72子函数(之前开头宏定义过了),如下

 

system_stm32f10x.c文件了解

static void SetSysClockTo72(void)

{

  __IO uint32_t StartUpCounter = 0, HSEStatus = 0;

 

  /* SYSCLK, HCLK, PCLK2 and PCLK1 configuration ---------------------------*/   

  /* Enable HSE */   

  RCC->CR |= ((uint32_t)RCC_CR_HSEON);

 

  /* Wait till HSE is ready and if Time out is reached exit
   HSE_STARTUP_TIMEOUT就是之前在stm32f10x.h里提到的等待时钟稳定的时间
   下面就是在等HSERDY被置高,若超过设定的TIMEOUT,则跳出
  */

  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)

  {

    /* Enable Prefetch Buffer
    此寄存器在手册3.3节描述
   */

    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;

 

#ifdef STM32F10X_CL

    /* Configure PLLs ------------------------------------------------------*/

    /* PLL2 configuration: PLL2CLK = (HSE / 5) * 8 = 40 MHz */

    /* PREDIV1 configuration: PREDIV1CLK = PLL2 / 5 = 8 MHz */

       

    RCC->CFGR2 &= (uint32_t)~(RCC_CFGR2_PREDIV2 | RCC_CFGR2_PLL2MUL |

                              RCC_CFGR2_PREDIV1 | RCC_CFGR2_PREDIV1SRC);

    RCC->CFGR2 |= (uint32_t)(RCC_CFGR2_PREDIV2_DIV5 | RCC_CFGR2_PLL2MUL8 |

                             RCC_CFGR2_PREDIV1SRC_PLL2 | RCC_CFGR2_PREDIV1_DIV5);

 

    /* Enable PLL2 */

    RCC->CR |= RCC_CR_PLL2ON;

    /* Wait till PLL2 is ready */

    while((RCC->CR & RCC_CR_PLL2RDY) == 0)

    {

    }

   

  

    /* PLL configuration: PLLCLK = PREDIV1 * 9 = 72 MHz */

    RCC->CFGR &= (uint32_t)~(RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLSRC | RCC_CFGR_PLLMULL);

    RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLXTPRE_PREDIV1 | RCC_CFGR_PLLSRC_PREDIV1 |

                            RCC_CFGR_PLLMULL9);

#else   

    /*  PLL configuration: PLLCLK = HSE * 9 = 72 MHz */

    RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE |

                                        RCC_CFGR_PLLMULL));

    RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_HSE | RCC_CFGR_PLLMULL9);

#endif /* STM32F10X_CL */

 

    /* 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)0x08)

    {

    }

  }

  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 */

  }

}

system_stm32f10x.c文件了解

 

这样,这个文件剩下的只有SystemCoreClockUpdate没提了,其他函数基本类似或者没有用到,这个具体内容就不复制上来了,功能为:使SystemCoreClock变量保存当前的系统时钟频率,我稍微做了下测试,如果默认启动后调用此函数,SystemCoreClock自然就是72000000,如果把系统时钟切为HSI,即执行如下代码

   RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));

    RCC->CFGR |= (uint32_t)RCC_CFGR_SW_HSI;     

再调用此函数,SystemCoreClock的值就是8000000,当然,单片机的执行速度也慢了许多。

 

上一篇:LOJ 2551 「JSOI2018」列队——主席树+二分


下一篇:LOJ 2991 「THUSC 2016」补退选——trie+线段树合并或vector