• STM32F40X之时钟树


    一、时钟树概述

    目前用到的STM32的许多片上外设都需要先打开相应的时钟,告诉当前这个器件是以什么频率在运行,而每个片上外设的时钟频率其实在出厂时已经固化。

    二、时钟树框架

    25M / 25 * 336 / 2 = 168M

    系统时钟计算公式:SYSCLK=PLLCLK = HSE / M *N / P = 168M

    系统时钟 (SYSCLK==168MHZ)可以来自以下三种不同的时钟源。 
    ● HSI 振荡器时钟 
    ● HSE 振荡器时钟 
    ● 主 PLL (PLL) 时钟 
    留心:芯片内部未使用时默认都是关闭的,目的是降低功耗,可以单独打开或者关闭。
    3概念补充:
    (1)MCO1/2: 微处理器的时钟输出,可以向外提供时钟源而且也可以测量芯片内部时钟是否稳定正确。
    (2)芯片内部的工作时钟可以由以下四个时钟提供:(重点)
    ①LSI(low speed inner):内部低速时钟:该时钟是芯片内部的一个32KHZ的RC振荡器,该时钟非常不稳定,一般很少使用。
    作用对象:独立看门狗和RTC
    ②LSE(外部低速时钟):该时钟是由芯片外部提供的的一个32.768KHZ的有源晶振,该时钟要求要很稳定,是RTC专用时钟。
    作用对象:RTC也可以向外提供一个时钟源。
    ③HSI(内部高速时钟):该时钟是芯片内部的一个16MHZ的RC振荡器,该时钟用途很多。
    作用对象:向外输出一个时钟源、给系统提供时钟、作为PLL时钟输入源。
    ④HSE(外部高速时钟):该时钟是由芯片外部提供的的一个25MHZ的有源晶振,该时钟非常稳定.
    作用对象:向外输出一个时钟源、给系统提供时钟、作为PLL时钟输入源,作为RTC的时钟输入源。
    (3)锁相环(PPL):使得输入和输出两个频率同步即具有稳定频率的作用。能使输出频率是输入频率的倍数,可以实现对输入输出信号的进行调制。

    在APB1总线上的外设时钟频率为42M,但是定时器的时钟频率是84M

    在APB2总线上的外设时钟频率为84M,但是定时器的时钟频率是168M

    框架分析思路:

    芯片要想工作需要一个时钟输入,对于该芯片(40x)时钟频率最高168Mhz,所以最终我们需要获得一个168MHZ(系统要求的) 的时钟作为系统时钟,再由该系统时钟经过分频得到各个模块的时钟。
    经分析:系统时钟可以来自以下三个输入源:即HIS/HSE/PLL(锁相环)

    由上图可知HIS(16MHZ)和HSE(25MHZ)都不能直接选为系统时钟(要求是168MHZ),经分析虽然HIS(16MHZ)和HSE(25MHZ)都不能直得到系统时钟(168MHZ),但是可以选择PLLCLK作为系统时钟,而PLLCLK的时钟要经过锁相环(PLL)处理才能得到。

    三、时钟树程序设计

    时钟设置步骤如下:                  
    1使能HSI 。
    2等待HSI打开成功。
    3设置电压调节器输出级别默认就行)。
    4打开电源开关(默认就行)
    5设置AHB/APB1/APB2的分频值。
    6关闭主锁相环锁 (可以不要)
    7等待关闭成功(可以不要)
    8配置PLL(M/N/P包括选择HSI作为锁相环输入时钟源)。
    9开启主PLL。
    10等待主锁相环稳定。
    11设置flash的相关参数(缓存,存取指令数据缓存,等待周期等 默认就可以)    
    12切换PLL为系统时钟源。
    13 等待PLL作为系统时钟切换成功。

    1. void SystemInit(void)
    2. {
    3. /* Reset the RCC clock configuration to the default reset state ------------*/
    4. /* Set HSION bit */
    5. RCC->CR |= (uint32_t)0x00000001;//把RCC的第0位置1
    6. /* Reset CFGR register */
    7. RCC->CFGR = 0x00000000; //CFGR寄存器全部复位
    8. /* Reset HSEON, CSSON and PLLON bits */
    9. RCC->CR &= (uint32_t)0xFEF6FFFF; //复位HSE,CSS,PLL
    10. /* Reset PLLCFGR register */
    11. RCC->PLLCFGR = 0x24003010;//对于后面需要配置的PLL相应的时钟复位成原本的值
    12. /* Reset HSEBYP bit */
    13. RCC->CR &= (uint32_t)0xFFFBFFFF;//复位HSEYP的位
    14. /* Disable all interrupts */
    15. RCC->CIR = 0x00000000; //复位中断
    16. }
    17. static void SetSysClock(void)
    18. {
    19. __IO uint32_t StartUpCounter = 0, HSEStatus = 0; //StartUpCounter 超时计数变量,HSEStatus 标志位
    20. /* Enable HSE */
    21. RCC->CR |= ((uint32_t)RCC_CR_HSEON);//使能HSE的振荡器
    22. do
    23. {
    24. HSEStatus = RCC->CR & RCC_CR_HSERDY;//要不就是0,要不就是非零值
    25. StartUpCounter++;//累加
    26. } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));
    27. //上面的do while出来的条件有两个:一个是HSE就绪,一个是等待的时间到了
    28. //判断HSE有没有就绪
    29. if ((RCC->CR & RCC_CR_HSERDY) != RESET)
    30. {
    31. HSEStatus = (uint32_t)0x01;
    32. }
    33. else
    34. {
    35. HSEStatus = (uint32_t)0x00;
    36. }
    37. if (HSEStatus == (uint32_t)0x01)
    38. {
    39. /* Select regulator voltage output Scale 1 mode */
    40. RCC->APB1ENR |= RCC_APB1ENR_PWREN;//使能电源接口时钟
    41. PWR->CR |= PWR_CR_VOS;
    42. /* HCLK = SYSCLK / 1*/
    43. RCC->CFGR |= RCC_CFGR_HPRE_DIV1;//AHB为1分频
    44. /* PCLK2 = HCLK / 2*/
    45. RCC->CFGR |= RCC_CFGR_PPRE2_DIV2;//APB22分频
    46. /* PCLK1 = HCLK / 4*/
    47. RCC->CFGR |= RCC_CFGR_PPRE1_DIV4;//APB14分频
    48. RCC->PLLCFGR = PLL_M | (PLL_N << 6) | (((PLL_P >> 1) -1) << 16) |
    49. (RCC_PLLCFGR_PLLSRC_HSE) | (PLL_Q << 24);
    50. //M分频是25,N倍频是336,P分频是2,选择 HSE 振荡器时钟作为 PLL 和 PLLI2S 时钟输入
    51. /* Enable the main PLL */
    52. RCC->CR |= RCC_CR_PLLON;//开启PLL时钟源
    53. /* Wait till the main PLL is ready */
    54. while((RCC->CR & RCC_CR_PLLRDY) == 0)//死等PLL就绪
    55. {
    56. }
    57. /* Select the main PLL as system clock source */
    58. RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));
    59. RCC->CFGR |= RCC_CFGR_SW_PLL; //选择PLL作为系统时钟源168M
    60. }


    HSE改为HSI最后还是168M

  • 相关阅读:
    Aria2 for Mac (免HomeBrew)
    LeetCode算法心得——和可被 K 整除的子数组(前缀和+HashMap)
    Mybatis实现(指标状态)的动态sql
    低代码平台:构建应用程序的“银弹”
    求两个递增链表的交集
    Mybatis 映射器中使用@InsertProvider,@UpdateProvider,@DeleteProvider,@SelectProvider
    Swift基础语法 - 枚举
    深度学习 LSTM长短期记忆网络原理与Pytorch手写数字识别
    前端工程化01-复习jQuery当中的AJAX
    SpringBoot3快速入门
  • 原文地址:https://blog.csdn.net/weixin_52483742/article/details/133952132