STM32-时钟篇以及复位时时钟的配置过程

STM32-时钟篇以及复位时时钟的配置过程

时钟就是一个芯片的心脏,CPU的处理速度也是由时钟来直接决定,相比51单一的时钟源,STM32具有强大的时钟系统,我们的所有的外设都离不开时钟,时钟是学习STM32非常重要的部分。

一、时钟源

首先时钟都是由时钟源产生的,STM32的时钟可以由三个时钟源产生。
在这里插入图片描述

二、时钟树

在STM32的官方参考手册里面,RCC时钟的这一节里面有一个时钟树的图,如下,如果可以看懂这个图的话,就对STM32的时钟系统有了很清晰的了解,下面将会分部分对时钟树比较重要的部分进行简单的讲解。
在这里插入图片描述

1. 系统时钟部分

系统时钟部分一般被配置为72MHz,如下图,一般是由HSE(8MHz)经过PREDIV1不进行分频,然后经过PLLMUL进行9倍频,然后得到72MHz的系统时钟SYSCLK。
在这里插入图片描述

2. 实时时钟部分

如下图,实时时钟的时钟RTCCLK可以来源于三个地方,分别是40kHz的LSI(内部低速振荡器)和32.768kHz的LSE(外部低速振荡器)以及由HSE(外部高速振荡器进行128分频得到的时钟)。在这里插入图片描述

3. APB1、APB2、AHB三条总线的时钟

  1. AHB 总线时钟:AHB时钟即HCLK,直接来源于系统时钟可以选择进行分频,一般不分频,等于系统时钟的最高频率72MHz。
  2. APB1总线的时钟:即PCLK1,最高只能设置为36MHz,来源于AHB的时钟HCLK,可以选择进行分频,由于最高只能设置为36MHz,所以一般进行2分频得到PCLK1=36MHz。
  3. APB2总线的时钟:即PCLK2,最高可以设置为72MHz,来源于AHB的时钟HCLK,可以选择进行分频。
    挂载到APB1和APB2总线上的外设
    在这里插入图片描述

4. 定时器的时钟

定时器又分为高级定时器和通用定时器,高级定时器包括TIM1和TIM8,通用定时器包括TIM2~TIM7
如图中所示,如果APB1总线的预分频系数为1,那么到通用定时器的时钟就等于APB1总线的时钟PCLK1,否则等于APB1总线的时钟PCLK1*2。例如,APB1的时钟PCLK1配置为最高36MHz,APB1 prescaler=1那么通用定时器的时钟TIMxCLK=PCLK1=36MHz;如果APB1 prescaler不等于 1,那么TIMxCLK=PCLK1×2=72MHz。
与高级定时器有关的总线是APB2,和通用定时器类似,如果APB2总线的预分频系数为1,那么到通用定时器的时钟就等于APB2总线的时钟PCLK2,否则等于APB2总线的时钟PCLK2*2。有同学在这里可能会有一点点不了解,因为APB2总线的最高频率为72MHz,在这里乘以2,就是144MHz,这样理解是不对的,为什么呢?首先只有APB2 prescaler 不为1的后,才会乘以2,而系统时钟最高为72MHz,如果APB2 prescaler不为1,那么会被分频,然后到定时器的时钟再乘以2,也是始终不会超过72MHz的。
在这里插入图片描述

5. ADC的时钟

ADC的时钟没有什么好说的,就是来源于APB2,然后经过ADC的预分频器,得到ADCCLK,不过需要注意的是ADC的最高频率只能为14MHz,当APB2的频率为72MHz的时候,必须经过6分频,得到的是12MHz,通过自己实验以及在网上查找资料发现,即使没有经过6分频,ADC还是可以正常工作,但是需要注意的是,此时ADC会有误差。

三、系统复位时时钟的配置过程

在编写STM32的时候,会有一个启动文件startup_stm32f10x_md.s,关于启动文件的作用如下

  1. 初始化堆栈指针 SP;
  2. 初始化程序计数器指针 PC;
  3. 设置堆、栈的大小;
  4. 设置异常向量表的入口地址;
  5. 配置外部 SRAM 作为数据存储器(这个由用户配置,一般的开发板可没有外部 SRAM);
  6. 设置 C 库的分支入口__main(最终用来调用 main 函数);
  7. 在 3.5 版的启动文件还调用了在 system_stm32f10x.c 文件中的
    SystemInit() 函数配置系统时钟,在旧版本的工程中要用户进入
    main 函数自己调用 SystemInit() 函数。
    这次我们的重点不放在启动文件上面,主要是系统初始化函数SystemInit() ,我们在启动文件中可以找到一段代码,意思就是首先调用了SystemInit函数,返回之后,就进入我们的主函数main。我们定位到SystemInit鼠标右键选择go to definition of ‘SysttemInit’或者按键盘上面的F12进入该函数。
    在这里插入图片描述
    由于本篇针对的是STM32F103实用系列,函数里面一些是关于其他系列如互联型等,所以可以将SystemInit函数进行了一些简化,代码如下(来源于野火):
static void SetSysClockTo72(void)
{
    
    
  __IO uint32_t StartUpCounter = 0, HSEStatus = 0;
  
  /* SYSCLK, HCLK, PCLK2 and PCLK1 configuration ---------------------------*/    
  /* 使能 HSE */    
  RCC->CR |= ((uint32_t)RCC_CR_HSEON);
 
  /* 等待HSE就绪并做超时处理 */
  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;
  }  

  // 如果HSE启动成功,程序则继续往下执行
  if (HSEStatus == (uint32_t)0x01)
  {
    
    
    /* 使能预取指 */
    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 = 72M */
    RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1;
      
    /* PCLK2 = HCLK = 72M */
    RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1;
    
    /* PCLK1 = HCLK = 36M*/
    RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV2;
    
    /*  锁相环配置: 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);

    /* 使能 PLL */
    RCC->CR |= RCC_CR_PLLON;

    /* 等待PLL稳定 */
    while((RCC->CR & RCC_CR_PLLRDY) == 0)
    {
    
    
    }    
    /* 选择PLLCLK作为系统时钟*/
    RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));
    RCC->CFGR |= (uint32_t)RCC_CFGR_SW_PLL;    

    /* 等待PLLCLK切换为系统时钟 */
    while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)0x08)
    {
    
    
    }
  }
  else
  {
    
     /* 如果HSE 启动失败,用户可以在这里添加处理错误的代码 */
  }
}

这样我们就可以清楚的知道,搞明白了这些,这样在以后学习定时器或者ADC以及其他的资源的时候,就不会感觉到有一些迷惑,总是觉得不太自信的赶脚。。。哈哈

HCLK = SYSCLK = 72M
PCLK2 = HCLK = 72M
PCLK1 = HCLK = 36M
PLLCLK = HSE * 9 = 72 MHz

猜你喜欢

转载自blog.csdn.net/qq_43715171/article/details/113189556