STM32F1 - 源码解析SystemInit()

SystemInit

  • 1> SystemInit( )调用位置
  • 2> SystemInit ()函数
  • 3> SetSysClock()函数
  • 4> SetSysClockTo72()函数


1> SystemInit( )调用位置

startup_stm32f10x_hd.s文件中:

; Reset handler
Reset_Handler   PROC
                EXPORT  Reset_Handler             [WEAK]
                IMPORT  __main
                IMPORT  SystemInit 
                LDR     R0, =SystemInit
                BLX     R0               
                LDR     R0, =__main
                BX      R0
                ENDP

复位中,在调用__main()函数时,
先调用了SystemInit(), 他干了点啥活呢?


2> SystemInit ()函数

// 文件system_stm32f10x.h:

/**
  * @brief  Setup the microcontroller system
  *         Initialize the Embedded Flash Interface, the PLL and update the 
  *         SystemCoreClock variable.
  * @note   This function should be used only after reset.
  * @param  None
  * @retval None
  */
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 */
  RCC->CFGR &= (uint32_t)0xF8FF0000; // 1111 1000 1111 1111 0000 0000 0000 0000
时钟配置寄存器CFGR全为0, 则系统时钟源选择高速内部时钟HSI

  /* Reset HSEON, CSSON and PLLON bits */
  RCC->CR &= (uint32_t)0xFEF6FFFF; // 1111 1110 1111 0110 1111 1111 1111 1111
关闭外部高速时钟HSE,时钟监测器关闭,PLL关闭

  /* Reset HSEBYP bit */
  RCC->CR &= (uint32_t)0xFFFBFFFF; // 1011 1111 1111 1111 1111
外部4-16MHz振荡器没有旁路, 分析到,发现,写库的人不爱用移位运算,这点随我

  /* Reset PLLSRC, PLLXTPRE, PLLMUL and USBPRE/OTGFSPRE bits */
  // 1111 1111 1000 0000 1111 1111 1111 1111
  RCC->CFGR &= (uint32_t)0xFF80FFFF; 
HSI振荡器时钟经过2分频后,作为PLL输入时钟;
PLL 2倍频输出, 那就是8MHz ÷ 2 *2 还是8MHz
  
  /* Disable all interrupts and clear pending bits  */
  RCC->CIR = 0x009F0000; // 0000 0000 1001 1111 0000 0000 0000 0000
配置时钟中断 寄存器

  /* Configure the System clock frequency, HCLK, PCLK2 and PCLK1 prescalers */
  /* Configure the Flash Latency cycles and enable prefetch buffer */
  SetSysClock();
  
  /* Vector Table Relocation in Internal FLASH. */
  SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; 
  这句话,非常重要,把异常向量表映射到Flash起始地址0x0800 0000
  }

STM32F1 - 源码解析SystemInit()_第1张图片

STM32F1 - 源码解析SystemInit()_第2张图片

RCC->CFGR &= (uint32_t)0xF8FF0000;
时钟配置寄存器CFGR,全为0, 重点关注SW,HSI作为系统时钟;
STM32F1 - 源码解析SystemInit()_第3张图片
方法:看程序,对着参考手册, 看程序配置了哪些寄存器;

总结:

配置内部高速时钟HSI为时钟源,
调用 SetSysClock();
中断向量表放到Flash起始地址0x0800 0000;


3> SetSysClock()函数

// 文件system_stm32f10x.c:
#define SYSCLK_FREQ_72MHz  72000000
/**
  * @brief  Configures the System clock frequency, HCLK, PCLK2 and PCLK1 prescalers.
  * @param  None
  * @retval None
  */
static void SetSysClock(void)
{
#ifdef SYSCLK_FREQ_HSE
// ...
#elif defined SYSCLK_FREQ_72MHz
  SetSysClockTo72();
#endif
}

根据条件编译,调用SetSysClockTo72();


4> SetSysClockTo72()函数

/**
  * @brief  Sets System clock frequency to 72MHz and configure HCLK, PCLK2 
  *         and PCLK1 prescalers. 
  * @note   This function should be used only after reset.
  * @param  None
  * @retval None
  */
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 */
  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 */
    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;

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

    /* 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)
    {
    }
  }
}

你可能感兴趣的:(STM32F1-外设驱动,stm32,单片机,嵌入式硬件)