【STM32】初学者必读STM32时钟系统详解

目录

1 前言

2 时钟系统介绍

3 时钟源

3.1 系统时钟源

3.2 次级时钟源

3.3 时钟源特点

4 时钟

4.1 AHB总线时钟

4.2 APB1总线时钟

4.3 APB2总线时钟

扫描二维码关注公众号,回复: 16150403 查看本文章

5 时钟控制器

6 CubeMx配置时钟系统

6.1 选择单片机型号

6.2 选择时钟源

6.3 配置系统时钟

6.4 时钟系统初始化代码

7 结论

1 前言

        STM32的时钟系统比较复杂,初学者一看时钟树必然蒙圈,我该怎么用?怎么设置?搞不懂,就根据开发板源码很快完成设置,虽然能用起来,碰到问题或自己改代码时必然蒙圈。要做好底层驱动设计,还是要对STM32的时钟有深入的理解,本文将为大家详细介绍STM32的时钟。

2 时钟系统介绍

        STM32的时钟系统由三大部分组成:时钟源、时钟控制器、时钟。

        时钟源是产生时钟信号的电路,可以是晶振、RC震荡电路,产生方波信号,由时钟控制器分频或倍频后作为内核或外设的时钟。

        时钟可以理解为给外设提供工作频率的方波信号,该方波信号的频率是时钟源的倍频或分频。

        时钟控制器介于时钟源和时钟之间,对时钟源进行选择、分频、倍频控制,为内核及外设提供时钟。

        STM32F407的系统时钟框图如图 1所示,时钟控制器将HIS、HSE、主PLL时钟源转化为内核及外设所需的时钟,接收外部I2S时钟、PHY以太网时钟、USBPhy时钟,为I2S、MAC、USB等外设提供时钟。时钟控制器还提供2路时钟输出MCO1和MCO2,最大输出频率100MHz。

1 STM32F407时钟系统框图

        STM32F407的系统时钟树如图 2所示。

2 STM32F407时钟树

3 时钟源

        STM32的时钟源由系统时钟源和次级时钟源组成。

3.1 系统时钟源

        STM32单片机可以使用三种不同的时钟源来驱动系统时钟 (SYSCLK),三种时钟源分别为:

        ● HSI 振荡器时钟

        ● HSE 振荡器时钟

        ● 主 PLL (PLL) 时钟

        注意这里说的HIS、HSE或主PLL提供的是系统时钟(SystemClk),对于单片机而言,时钟源只有HSI或HSE,主PLL的时钟源也是HSI或HSE,经过PLL倍频后作为系统时钟的时钟源,提供高于HIS、HSE时钟频率的时钟源。将STM32F407的时钟树系统时钟源简化后的框图如图 2所示。

3 系统时钟源框图

3.2 次级时钟源

        STM32单片机器件具有两个次级时钟源,分别为:

        ● 32 kHz 低速内部 RC (LSI RC)。该 RC 用于驱动独立看门狗,也可选择提供给 RTC 用于停机/待机模式下的自动唤醒。

        ● 32.768 kHz 低速外部晶振( LSE 晶振),用于驱动 RTC 时钟 (RTCCLK)。

3.3 时钟源特点

        每个时钟源都可单独打开或者关闭,不用时关闭时钟源以降低功耗。

        时钟控制器为应用带来了高度的灵活性,用户在运行内核和外设时可选择使用外部晶振或者使用振荡器,既可采用最高的频率,也可为以太网、 USB OTG FS 以及 HS、 I2S 和 SDIO等需要特定时钟的外设保证合适的频率。

4 时钟

        通过前文介绍,了解到STM32F407的时钟包括以太网ptp时钟、系统时钟SystemClk、AHB时钟、APB时钟等。APB时钟分为高速 APB (APB2) 和低速 APB (APB1),时钟控制器可对这些时钟的频率进行配置。这些时钟为单片机的AHB总线、AHB1总线、APB1总线、APB总线提供工作时钟,各外设分别连接到各个总线上,获得相应的工作时钟,时钟频率收到总线工作时钟最大频率限制。以STM32F407为例,AHB 的最大频率为 168 MHz,低速 APB1 的最大允许频率为 42 MHz,高速 APB2 的最大允许频率为 84 MHz。

        STM32F407总线如图 4所示。

4 STM32F407总线

4.1 AHB总线时钟

        AHB 总线时钟的最大频率为系统时钟SystemClk,以STM32F407为例,最大为 168 MHz。AHB总线的外设如图 5所示。

5 AHB总线外设

4.2 APB1总线时钟

        APB1为APB低速总线,最大频率为系统时钟SystemClk的4分频,以STM32F407为例,最大为 42MHz。APB1总线的外设如图 6所示。

6 APB1总线外设

4.3 APB2总线时钟

        APB2为APB高速总线,最大频率为系统时钟SystemClk的2分频,以STM32F407为例,最大为 84MHz。APB2总线的外设如图 7所示。

7 APB2总线外设

5 时钟控制器

        STM32单片机的时钟控制通过配置RCC时钟控制寄存器、RCC PLL配置寄存器、RCC时钟配置寄存器、RCC时钟中断寄存器、RCC外设复位寄存器、RCC外设时钟寄存器等组成。这里不在赘述,详细可查阅《STM32F4xx参考手册》。

6 CubeMx配置时钟系统

6.1 选择单片机型号

        NewProjectà选择单片机型号,以STM32F407为例。如图 8所示。

8 选择单片机型号

6.2 选择时钟源

        如图 9所示,标注1的为时钟源选项,可以设置HSE、LSE,如选择Disable,则配置为内部RC振荡器,如选择外部晶体振荡器,则硬件上需设计有晶振支持,这里选择为外部晶振。

        标注2为配置是否允许MCO1、MCO2时钟输出,这里未允许。标注3为配置是否允许I2S外部时钟输入,这里未允许。

9 时钟源选择

6.3 配置系统时钟

        STM32F407最大允许系统时钟168M,其配置方法如下:

  • 选择Clock Configuration选项卡。
  • 选择HSE。
  • 选择PLLCLK
  • 设置HCLK为168MHz

        如图 10所示,可查询到系统时钟、APB1、APB2等总线时钟,方便外设使用时的时钟设置。

10 系统时钟配置

6.4 时钟系统初始化代码

        时钟系统初始化相关函数如表 1所示

1 时钟系统初始化相关函数

序号

函数名称

函数功能说明

1

SystemClock_Config(void)

系统时钟配置

        代码具体如下:

void SystemClock_Config(void)
{

  RCC_OscInitTypeDef RCC_OscInitStruct;
  RCC_ClkInitTypeDef RCC_ClkInitStruct;

    /**Configure the main internal regulator output voltage 
    */
  __HAL_RCC_PWR_CLK_ENABLE();

  __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);

    /**Initializes the CPU, AHB and APB busses clocks 
    */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
  RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  RCC_OscInitStruct.PLL.PLLM = 25;
  RCC_OscInitStruct.PLL.PLLN = 336;
  RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
  RCC_OscInitStruct.PLL.PLLQ = 4;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }

    /**Initializes the CPU, AHB and APB busses clocks 
    */
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;

  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }

    /**Configure the Systick interrupt time 
    */
  HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);

    /**Configure the Systick 
    */
  HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);

  /* SysTick_IRQn interrupt configuration */
  HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);
}

7 结论

        看过本文后,相信您对复杂的时钟系统有了新的认识,在未来的设计中,不会因为STM32的复杂时钟踩坑。请关注博主,学习更多实战经验,后续会陆续推出更多实战经验,还请多多关注、批评指正!

猜你喜欢

转载自blog.csdn.net/m0_54916619/article/details/130182697