zoukankan      html  css  js  c++  java
  • 时钟树讲解

         RCC : reset clock control 复位和时钟控制器。

          设置系统时钟 SYSCLK、设置 AHB 分频因子(决定 HCLK 等于多少) 、 设置 APB2 分频因子(决定 PCLK2 等于多少)、设置 APB1 分频因子(决定 PCLK1 等于多少)、设置各个外设的分频因子;控制 AHB、 APB2 和 APB1 这三条总线时钟的开启、控制每个外设的时钟的开启。对于 SYSCLK、 HCLK、 PCLK2、 PCLK1 这四个时钟的配置一般是: PCLK2 =HCLK = SYSCLK=PLLCLK = 72M, PCLK1=HCLK/2 = 36M。这个时钟配置也是库函数的标准配置,我们用的最多的就是这个.

    时钟树图

    1

    2

    1 系统时钟

    1.①HSE 高速外部时钟信号

         HSE 是高速的外部时钟信号,可以由有源晶振或者无源晶振提供,频率从 4-16MHZ不等。当使用有源晶振时,时钟从 OSC_IN 引脚进入, OSC_OUT 引脚悬空,当选用无源晶振时,时钟从 OSC_IN 和 OSC_OUT 进入,并且要配谐振电容

         HSE 最常使用的就是 8M 的无源晶振。当确定 PLL 时钟来源的时候, HSE 可以不分频或者 2 分频,这个由时钟配置寄存器 CFGR 的位 17: PLLXTPRE 设置,我们设置为 HSE不分频

    2. ②PLL 时钟源
         PLL 时钟来源可以有两个,一个来自 HSE,另外一个是 HSI/2,具体用哪个由时钟配置寄存器 CFGR 的位 16: PLLSRC 设置。 HSI 是内部高速的时钟信号,频率为 8M,根据温度和环境的情况频率会有漂移,一般不作为 PLL 的时钟来源。这里我选 HSE 作为PLL 的时钟来源

    3. ③PLL 时钟 PLLCLK
         通过设置 PLL 的倍频因子,可以对 PLL 的时钟来源进行倍频,倍频因子可以是:[2,3,4,5,6,7,8,9,10,11,12,13,14,15,16],具体设置成多少, 由时钟配置寄存器 CFGR 的位21-18: PLLMUL[3:0]设置。我们这里设置为 9 倍频,因为上一步我们设置 PLL 的时钟来源为 HSE=8M,所以经过 PLL 倍频之后的 PLL 时钟: PLLCLK = 8M *9 = 72M。 72M 是 ST官方推荐的稳定运行时钟,如果你想超频的话,增大倍频因子即可,最高为 128M。我们这里设置 PLL 时钟: PLLCLK = 8M *9 = 72M。

    4. ④系统时钟 SYSCLK

         系统时钟来源可以是: HSI、 PLLCLK、 HSE,具体的时钟配置寄存器 CFGR 的位 1-0:SW[1:0]设置。我们这里设置系统时钟: SYSCLK = PLLCLK = 72M

    5. ⑤AHB 总线时钟 HCLK

         系统时钟 SYSCLK 经过 AHB 预分频器分频之后得到时钟叫 APB 总线时钟,即 HCLK,分频因子可以是:[1,2,4, 8, 16, 64, 128, 256, 512],具体的由时钟配置寄存器 CFGR的位 7-4 : HPRE[3:0]设置。片上大部分外设的时钟都是经过 HCLK 分频得到,至于 AHB总线上的外设的时钟设置为多少,得等到我们使用该外设的时候才设置,我们这里只需粗线条的设置好 APB 的时钟即可。 我们这里设置为 1 分频,即 HCLK=SYSCLK=72M

    6. ⑥APB2 总线时钟 HCLK2
         APB2 总线时钟 PCLK2 由 HCLK 经过高速 APB2 预分频得到,分频因子可以是:[1,2,4, 8, 16],具体由时钟配置寄存器 CFGR 的位 13-11: PPRE2[2:0]决定。 HCLK2 属于高速的总线时钟,片上高速的外设就挂载到这条总线上,比如全部的 GPIO、 USART1、SPI1 等。至于 APB2 总线上的外设的时钟设置为多少,得等到我们使用该外设的时候才设置,我们这里只需粗线条的设置好 APB2 的时钟即可。我们这里设置为 1 分频,即 PCLK2= HCLK = 72M。

    7. ⑦APB1 总线时钟 HCLK1

         APB1 总线时钟 PCLK1 由 HCLK 经过低速 APB 预分频器得到,分频因子可以是:[1,2,4,8, 16],具体的由时钟配置寄存器 CFGR 的位 10-8: PRRE1[2:0]决定。HCLK1 属于低速的总线时钟,最高为 36M,片上低速的外设就挂载到这条总线上,比如USART2/3/4/5、 SPI2/3, I2C1/2 等。至于 APB1 总线上的外设的时钟设置为多少,得等到我们使用该外设的时候才设置,我们这里只需粗线条的设置好 APB1 的时钟即可。我们这里设置为 2 分频,即 PCLK1 = HCLK/2 = 36M。

    8. 设置系统时钟库函数
         上面的 7 个步骤对应的设置系统时钟库函数如下,该函数截取自固件库文件system_stm32f10x.c。 为了方便阅读,我已把互联型相关的代码删掉,把英文注释翻译成了中文,并把代码标上了序号,总共七个步骤。该函数是直接操作寄存器的,有关寄存器部分请参考数据手册的 RCC 的寄存器描述部分。

    static void SetSysClockTo72(void)
    {
     
      // SYSCLK HCLK PCLK2 PCLK1 Configuration
    __IO uint32_t StartUpCounter = 0, HSEStatus = 0;
    // ① 使能 HSE,并等待 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 预存取缓冲区 */
    FLASH->ACR |= FLASH_ACR_PRFTBE;
    // SYSCLK 周期与闪存访问时间的比例设置,这里统一设置成 2
    // 设置成 2 的时候, SYSCLK 低于 48M 也可以工作,如果设置成 0 或者 1 的时候,
    // 如果配置的 SYSCLK 超出了范围的话,则会进入硬件错误,程序就死了
    // 0: 0 < SYSCLK <= 24M
    // 1: 24< SYSCLK <= 48M
    // 2: 48< SYSCLK <= 72M */
    FLASH->ACR &= (uint32_t)((uint32_t)~FLASH_ACR_LATENCY);
    FLASH->ACR |= (uint32_t)FLASH_ACR_LATENCY_2;
    //------------------------------------------------------------
    // ② 设置 AHB、 APB2、 APB1 预分频因子
    // HCLK = SYSCLK
    RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1;
    //PCLK2 = HCLK
    RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1;
    //PCLK1 = HCLK/2
    RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV2;
    // ③ 设置 PLL 时钟来源,设置 PLL 倍频因子, PLLCLK = HSE * 9 = 72 MH
    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) {
    }
    // ⑥ 选择 PLL 作为系统时钟来源
    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 启动失败,用户可以在这里添加错误代码出来
    }
    }

    2 其他时钟

    1. A、 USB 时钟

         USB 时钟是由 PLLCLK 经过 USB 预分频器得到,分频因子可以是: [1,1.5], 具体的由时钟配置寄存器 CFGR 的位 22: USBPRE 配置。 USB 的时钟最高是 48M,根据分频因子反推过来算 , PLLCLK 只能是 48M 或者是 72M。一般我们设置 PLLCLK=72M,USBCLK=48M。 USB 对时钟要求比较高,所以 PLLCLK 只能是由 HSE 倍频得到,不能使用 HSI 倍频。

    2. B、 Cortex 系统时钟
         Cortex 系统时钟由 HCLK 8 分频得到,等于 9M, Cortex 系统时钟用来驱动内核的系统定时器 SysTick, SysTick 一般用于操作系统的时钟节拍,也可以用做普通的定时。

    3. C、 ADC 时钟
         ADC 时钟由 PCLK2 经过 ADC 预分频器得到,分频因子可以是[2,4,6,8],具体的由时钟配置寄存器 CFGR 的位 15-14: ADCPRE[1:0]决定。 很奇怪的是么没有 1 分频。 ADC时钟最高只能是 14M,如果采样周期设置成最短的 1.5 个周期的话, ADC 的转换时间可以达到最短的 1us。如果真要达到最短的转换时间 1us 的话,那 ADC 的时钟就得是 14M,反推 PCLK2 的时钟只能是: 28M、 56M、 84M、 112M,鉴于 PCLK2 最高是 72M,所以只能取 28M 和 56M。

    4. D、 RTC 时钟、独立看门狗时钟

         RTC 时钟可由 HSE/128 分频得到,也可由低速外部时钟信号 LSE 提供,频率为32.768KHZ,也可由低速内部时钟信号 HSI 提供,具体选用哪个时钟由备份域控制寄存器BDCR 的位 9-8: RTCSEL[1:0]配置。

          独立看门狗的时钟由 LSI 提供,且只能是由 LSI 提供,LSI 是低速的内部时钟信号,频率为 30~60KHZ 直接不等,一般取 40KHZ。

    5. E、 MCO 时钟输出

         MCO 是 microcontroller clock output 的缩写,是微控制器时钟输出引脚,在 STM32 F1系列中 PA8 复用所得,主要作用是可以对外提供时钟,相当于一个有源晶振。 MCO 的时钟来源可以是: PLLCLK/2、 HSI、 HSE、 SYSCLK,具体选哪个由时钟配置寄存器CFGR 的位 26-24: MCO[2:0]决定。 除了对外提供时钟这个作用之外, 我们还可以通过示波器监控 MCO 引脚的时钟输出来验证我们的系统时钟配置是否正确

     

  • 相关阅读:
    .net core读取appsettings.config中文乱码问题
    vs2017错误:当前页面的脚本发生错误
    VS Code中无法识别npm命令
    Visual Studio报错/plugin.vs.js,行:1074,错误:缺少标识符、字符串或数字
    记录一次在生成数据库服务器上出现The timeout period elapsed prior to completion of the operation or the server is not responding.和Exception has been thrown by the target of an invocation的解决办法
    Java集合框架
    java hash表
    Java Dictionary 类存储键值
    java数据结构 栈stack
    java封装
  • 原文地址:https://www.cnblogs.com/wenshinlee/p/8882046.html
Copyright © 2011-2022 走看看