×
单片机 > 单片机程序设计 > 详情

stm32 时钟设置函数分析

发布时间:2020-06-03 发布时间:
|
__IO uint32_t StartUpCounter = 0, HSEStatus = 0;
  
  /* SYSCLK, HCLK, PCLK2 and PCLK1 configuration ---------------------------*/   
这个函数的主要目的是 设置以上4个时钟的,那这四个时钟主要是用来干什么的?
这个后面再分析。
先看怎么获取72M的频率 
  /* 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;  ///*!< SYSCLK not divided */    
 
    /* PCLK2 = HCLK */
    RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1;  ///*!< HCLK not divided */ 
 
    /* PCLK1 = HCLK */
    RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV2; // /*!< HCLK not divided */
 
#ifdef STM32F10X_CL
   这一段互联型的产品的描述 删掉 
#else    
 开始设置倍频 9倍频 
    /*  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 */ 打开PLL
    RCC->CR |= RCC_CR_PLLON;
 
    /* Wait till PLL is ready */ 等待PLL稳定 
    while((RCC->CR & RCC_CR_PLLRDY) == 0)
    {
    }
    
    /* Select PLL as system clock source */ 选中PLL 作为时钟源
  也就是切换系统时钟  
    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 */ 等待系统时钟源的切换 
  因为系统刚开始(从复位到这一步)不是以PLL作为时钟源的。
    while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)0x08)
    {
    }
  到这里,在来看刚刚开始问题 /* SYSCLK, HCLK, PCLK2 and PCLK1 configuration ---------------------------*/ 
这几个时钟 都是用来做什么的。
 配置情况 
  /* HCLK = SYSCLK */ 
    RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1;  ///*!< SYSCLK not divided */  
    /* PCLK2 = HCLK */
    RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1;  ///*!< HCLK not divided */
    /* PCLK1 = HCLK */
    RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV2; // /*!< HCLK not divided */
还是要看时钟树:
时钟树:
 可以看出HCLK就是 AHB的时钟
PCLK2 就是APB2时钟
PCLK1 就是APB1时钟 ,系统里面的注释还有点错误,APB1应该=1/2 HCLk 
SYSCLK就是PLL时钟输入


『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
8051单片机的函数发生器的设计