STM32F407HAL库-2.系统时钟配置

在系统启动之后,程序会先执行HAL库定义的SystemInit函数,进行系统一些初始化配置。SystemInit程序如下:

void SystemInit(void)
{
  // FPU 设置
  #if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
    SCB->CPACR |= ((3UL << 10*2)|(3UL << 11*2));
  #endif

  // 复位RCC时钟配置为默认配置
  RCC->CR |= (uint32_t)0x00000001; // 打开HSION位
  RCC->CFGR = 0x00000000;  // 复位CFGR 
  RCC->CR &= (uint32_t)0xFEF6FFFF;  // 复位HSEON, CSSON 和 PLLON位
  RCC->PLLCFGR = 0x24003010;  // 复位寄存器PLLCFGR
  RCC->CR &= (uint32_t)0xFFFBFFFF;  // 复位HSEBYP位
  RCC->CIR = 0x00000000;  // 关闭所有中断


#if defined (DATA_IN_ExtSRAM) || defined (DATA_IN_ExtSDRAM)
  SystemInit_ExtMemCtl(); 
#endif /* DATA_IN_ExtSRAM || DATA_IN_ExtSDRAM */

  // 配置中断向量表地址 = 基地址 + 偏移地址
#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
}

从上面代码可以看出,SystemInit主要做了如下四个方面工作:

  1. FPU设置
  2. 复位RCC时钟配置为默认复位值(默认开始了HSI内部时钟)
  3. 外部存储器配置
  4. 中断向量表地址配置

HAL库的SystemInit函数并没有像标准库的SystemInit函数一样进行时钟的初始化配置。HAL库的SystemInit函数除了打开HSI之外,没有任何时钟相关配置,所以使用HAL库我们必须编写自己的时钟配置函数。

系统时钟配置函数如下(配置为168M):

// Systick时钟配置 168M 
void CLOCLK_Init(void)
{
    RCC_OscInitTypeDef RCC_OscInitStructure; // 定义初始化锁相环配置的结构体变量
    RCC_ClkInitTypeDef RCC_ClkInitStructure; // 定义初始化系统时钟源的结构体变量
		
    RCC_OscInitStructure.OscillatorType = RCC_OSCILLATORTYPE_HSE; // 晶振类型,外部高速时钟源
    RCC_OscInitStructure.HSEState = RCC_HSE_ON; // 打开HSE
    RCC_OscInitStructure.PLL.PLLState = RCC_PLL_ON; // 打开PLL
    RCC_OscInitStructure.PLL.PLLSource = RCC_PLLSOURCE_HSE; // PLL时钟源选择HSE
    RCC_OscInitStructure.PLL.PLLM = 8; // 主PLL和音频PLL分频系数(PLL之前的分频),取值范围:2~63.
    RCC_OscInitStructure.PLL.PLLN = 336; // 主PLL倍频系数(PLL倍频),取值范围:64~432.  
    RCC_OscInitStructure.PLL.PLLP = 2; // 系统时钟的主PLL分频系数(PLL之后的分频),取值范围:2,4,6,8.(仅限这4个值!)
    RCC_OscInitStructure.PLL.PLLQ = 7; // USB/SDIO/随机数产生器等的主PLL分频系数(PLL之后的分频),取值范围:2~15.
    if(HAL_RCC_OscConfig(&RCC_OscInitStructure) != HAL_OK) while(1); //初始化
	
    // 选中PLL作为系统时钟源并且配置HCLK,PCLK1和PCLK2
    RCC_ClkInitStructure.ClockType = RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2;
    RCC_ClkInitStructure.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; // 设置系统时钟时钟源为PLL
    RCC_ClkInitStructure.AHBCLKDivider = RCC_SYSCLK_DIV1; // AHB分频系数为1
    RCC_ClkInitStructure.APB1CLKDivider = RCC_HCLK_DIV4;  // APB1分频系数为4
    RCC_ClkInitStructure.APB2CLKDivider = RCC_HCLK_DIV2;  // APB2分频系数为2
    if(HAL_RCC_ClockConfig(&RCC_ClkInitStructure,FLASH_LATENCY_5))  while(1); // 同时设置FLASH延时周期为5WS,也就是6个CPU周期。
}

 

你可能感兴趣的:(STM32F4外设开发)