精华内容
下载资源
问答
  • STM32】系统时钟RCC详解(超详细,超全面)

    万次阅读 多人点赞 2019-08-08 15:42:35
    1什么是时钟 时钟是单片机运行的基础,时钟信号推动单片机内各个部分执行相应的指令。时钟系统就是CPU的脉搏,...为什么 STM32 要有多个时钟源呢? STM32本身十分复杂,外设非常多 但我们实际使用的时候只会用到有...

    1什么是时钟

    时钟是单片机运行的基础,时钟信号推动单片机内各个部分执行相应的指令。时钟系统就是CPU的脉搏,决定cpu速率,像人的心跳一样 只有有了心跳,人才能做其他的事情,而单片机有了时钟,才能够运行执行指令,才能够做其他的处理 (点灯,串口,ADC),时钟的重要性不言而喻。

     

    为什么 STM32 要有多个时钟源呢?

    STM32本身十分复杂,外设非常多  但我们实际使用的时候只会用到有限的几个外设,使用任何外设都需要时钟才能启动,但并不是所有的外设都需要系统时钟那么高的频率,为了兼容不同速度的设备,有些高速,有些低速,如果都用高速时钟,势必造成浪费   并且,同一个电路,时钟越快功耗越快,同时抗电磁干扰能力也就越弱,所以较为复杂的MCU都是采用多时钟源的方法来解决这些问题。所以便有了STM32的时钟系统和时钟树

     

    总括:

    • STM32时钟系统主要的目的就是给相对独立的外设模块提供时钟,也是为了降低整个芯片的耗能
    • 系统时钟,是处理器运行时间基准(每一条机器指令一个时钟周期)
    • 时钟是单片机运行的基础,时钟信号推动单片机内各个部分执行相应的指令。
    • 一个单片机内提供多个不同的系统时钟,可以适应更多的应用场合。
    • 不同的功能模块会有不同的时钟上限,因此提供不同的时钟,也能在一个单片机内放置更多的功能模块。
      对不同模块的时钟增加开启和关闭功能,可以降低单片机的功耗
    • STM32为了低功耗,他将所有的外设时钟都设置为disable(不使能),用到什么外设,只要打开对应外设的时钟就可以, 其他的没用到的可以还是disable(不使能),这样耗能就会减少。  这就是为什么不管你配置什么功能都需要先打开对应的时钟的原因

     

    STM32的时钟系统框图

     

    乍一看很吓人,但其实很好理解,我们看系统时钟SYSCLK 的左边  系统时钟有很多种选择,而左边的部分就是设置系统时钟使用那个时钟源,   

    系统时钟SYSCLK 的右边,则是系统时钟通过AHB预分频器,给相对应的外设设置相对应的时钟频率

     

    从左到右可以简单理解为  各个时钟源--->系统时钟来源的设置--->各个外设时钟的设置

    时钟系统

    1各个时钟源    (左边的部分)

    STM32 有4个独立时钟源:HSI、HSE、LSI、LSE。
    ①、HSI是高速内部时钟,RC振荡器,频率为8MHz,精度不高。
    ②、HSE是高速外部时钟,可接石英/陶瓷谐振器,或者接外部时钟源,频率范围为4MHz~16MHz
    ③、LSI是低速内部时钟,RC振荡器,频率为40kHz,提供低功耗时钟。  
    ④、LSE是低速外部时钟,接频率为32.768kHz的石英晶体。

    其中LSI是作为IWDGCLK(独立看门狗)时钟源和RTC时钟源 而独立使用 

    而HSI高速内部时钟 HSE高速外部时钟 PLL锁相环时钟  这三个经过分频或者倍频 作为系统时钟来使用

     

    PLL为锁相环倍频输出,其时钟输入源可选择为HSI/2、HSE或者HSE/2。倍频可选择为2~16倍,但是其输出频率最大不得超过72MHz。  通过倍频之后作为系统时钟的时钟源

     

    举个例子:Keil编写程序是默认的时钟为72Mhz,其实是这么来的:外部晶振(HSE)提供的8MHz(与电路板上的晶振的相关)通过PLLXTPRE分频器后,进入PLLSRC选择开关,进而通过PLLMUL锁相环进行倍频(x9)后,为系统提供72MHz的系统时钟(SYSCLK)。之后是AHB预分频器对时钟信号进行分频,然后为低速外设提供时钟。

    或者内部RC振荡器(HSI) 为8MHz  /2 为4MHz 进入PLLSRC选择开关,通过PLLMUL锁相环进行倍频(x18)后 为72MHz

     

    PS:  网上有很多人说是5个时钟源,这种说法有点问题,学习之后就会发现PLL并不是自己产生的时钟源,而是通过其他三个时钟源倍频得到的时钟

    2系统时钟SYSCLK

    系统时钟SYSCLK可来源于三个时钟源:
    ①、HSI振荡器时钟
    ②、HSE振荡器时钟
    ③、PLL时钟
    最大为72Mhz

     

    3USB时钟

    STM32中有一个全速功能的USB模块,其串行接口引擎需要一个频率为48MHz的时钟源。该时钟源只能从PLL输出端获取(唯一的),,可以选择为1.5分频或者1分频,也就是,当需要使用USB模块时,PLL必须使能,并且时钟频率配置为48MHz或72MHz

    4把时钟信号输出到外部

    STM32可以选择一个时钟信号输出到MCO脚(PA8)上,可以选择为PLL输出的2分频、HSI、HSE、或者系统时钟。可以把时钟信号输出供外部使用

    5系统时钟通过AHB分频器给外设提供时钟(右边的部分)  重点

     

    从左到右可以简单理解为  系统时钟--->AHB分频器--->各个外设分频倍频器 --->   外设时钟的设置

     

    右边部分为:系统时钟SYSCLK通过AHB分频器分频后送给各模块使用,AHB分频器可选择1、2、4、8、16、64、128、256、512分频。其中AHB分频器输出的时钟送给5大模块使用: 

     ①内核总线:送给AHB总线、内核、内存和DMA使用的HCLK时钟。 

     ②Tick定时器:通过8分频后送给Cortex的系统定时器时钟。 

     ③I2S总线:直接送给Cortex的空闲运行时钟FCLK。 

     ④APB1外设:送给APB1分频器。APB1分频器可选择1、2、4、8、16分频,其输出一路供APB1外设使用(PCLK1,最大频率36MHz),另一路送给通用定时器使用。该倍频器可选择1或者2倍频,时钟输出供定时器2-7使用。 

     ⑤APB2外设:送给APB2分频器。APB2分频器可选择1、2、4、8、16分频,其输出一路供APB2外设使用(PCLK2,最大频率72MHz),另一路送给高级定时器。该倍频器可选择1或者2倍频,时钟输出供定时器1和定时器8使用。

     

    另外,APB2分频器还有一路输出供ADC分频器使用,分频后送给ADC模块使用。ADC分频器可选择为2、4、6、8分频。 

    需要注意的是,如果 APB 预分频器分频系数是 1,则定时器时钟频率 (TIMxCLK) 为 PCLKx。否则,定      时器时钟频率将为 APB 域的频率的两倍:TIMxCLK = 2xPCLKx。 

    APB1和APB2的对应外设

    F1系列

    APB1上面连接的是低速外设,包括电源接口、备份接口、CAN、USB、I2C1、I2C2、USART2、USART3、UART4、UART5、SPI2、SP3等;

    而APB2上面连接的是高速外设,包括UART1、SPI1、Timer1、ADC1、ADC2、ADC3、所有的普通I/O口(PA-PE)、第二功能I/O(AFIO)口等。


    F4系列

    这个和F1系列类似,我们就举几个特殊的

     APB2总线:高级定时器timer1, timer8以及通用定时器timer9, timer10, timer11   UTART1,USART6

     APB1总线:通用定时器timer2~timer5,通用定时器timer12~timer14以及基本定时器timer6,timer7  UTART2~UTART5

    F4系列的系统时钟频率最高能到168M

     

    具体  可以在 stm32f10x_rcc.h  和stm32f40x_rcc.h   中查看

    或者通过 STM32参考手册搜索“系统架构”或者“系统结构”  查看外设挂在哪个时钟下

     

    RCC相关寄存器:

    这里我们以F1系列为例

    RCC 寄存器结构,RCC_TypeDeff,在文件“stm32f10x.h”中定义如下:
    
    1059行->1081行。:  
    typedef struct  
    {  
    vu32 CR;                  //HSI,HSE,CSS,PLL等的使能  
    vu32 CFGR;              //PLL等的时钟源选择以及分频系数设定 
    vu32 CIR;                // 清除/使能 时钟就绪中断 
    vu32 APB2RSTR;      //APB2线上外设复位寄存器 
    vu32 APB1RSTR;      //APB1线上外设复位寄存器 
    vu32 AHBENR;         //DMA,SDIO等时钟使能 
    vu32 APB2ENR;       //APB2线上外设时钟使能 
    vu32 APB1ENR;      //APB1线上外设时钟使能 
    vu32 BDCR;           //备份域控制寄存器 
    vu32 CSR;             
    } RCC_TypeDef; 
    

    可以对上上面的时钟框图和RCC寄存器来学习,对STM32的时钟系统有个大概的了解   其实也就是我们上面介绍的流程,理解了自然也就能写出来

    RCC初始化:

    这里我们使用HSE(外部时钟),正常使用的时候也都是使用外部时钟

    使用HSE时钟,程序设置时钟参数流程:
    1、将RCC寄存器重新设置为默认值   RCC_DeInit;
    2、打开外部高速时钟晶振HSE       RCC_HSEConfig(RCC_HSE_ON);
    3、等待外部高速时钟晶振工作      HSEStartUpStatus = RCC_WaitForHSEStartUp();
    4、设置AHB时钟         RCC_HCLKConfig;
    5、设置高速AHB时钟     RCC_PCLK2Config;
    6、设置低速速AHB时钟   RCC_PCLK1Config;
    7、设置PLL              RCC_PLLConfig;
    8、打开PLL              RCC_PLLCmd(ENABLE);
    9、等待PLL工作          while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET)
    10、设置系统时钟        RCC_SYSCLKConfig;
    11、判断是否PLL是系统时钟     while(RCC_GetSYSCLKSource() != 0x08)
    12、打开要使用的外设时钟      RCC_APB2PeriphClockCmd()/RCC_APB1PeriphClockCmd()

    代码实现:

    对RCC的配置函数(使用外部8MHz晶振)  

    系统时钟72MHz,APH 72MHz,APB2 72MHz,APB1 32MHz,USB 48MHz TIMCLK=72M

    void RCC_Configuration(void)
    {
    	//----------使用外部RC晶振-----------
    	RCC_DeInit();			//初始化为缺省值
    	RCC_HSEConfig(RCC_HSE_ON);	//使能外部的高速时钟 
    	while(RCC_GetFlagStatus(RCC_FLAG_HSERDY) == RESET);	//等待外部高速时钟使能就绪
    	
    	FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);	//Enable Prefetch Buffer
    	FLASH_SetLatency(FLASH_Latency_2);		//Flash 2 wait state
    	
    	RCC_HCLKConfig(RCC_SYSCLK_Div1);		//HCLK = SYSCLK
    	RCC_PCLK2Config(RCC_HCLK_Div1);			//PCLK2 =  HCLK
    	RCC_PCLK1Config(RCC_HCLK_Div2);			//PCLK1 = HCLK/2
    	RCC_PLLConfig(RCC_PLLSource_HSE_Div1,RCC_PLLMul_9);	//PLLCLK = 8MHZ * 9 =72MHZ
    	RCC_PLLCmd(ENABLE);			//Enable PLLCLK
     
    	while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);	//Wait till PLLCLK is ready
        RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);	//Select PLL as system clock
    	while(RCC_GetSYSCLKSource()!=0x08);		//Wait till PLL is used as system clock source
    	
    	//---------打开相应外设时钟--------------------
    	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);	//使能APB2外设的GPIOA的时钟		 
    }
    

    也就是我们时钟树框图从左到右的配置,

    时钟监视系统(CSS)

    STM32还提供了一个时钟监视系统(CSS),用于监视高速外部时钟(HSE)的工作状态。倘若HSE失效,会自动切换(高速内部时钟)HSI作为系统时钟的输入,保证系统的正常运行。

     

     

    展开全文
  • STM32STM32F4时钟系统

    千次阅读 2020-08-29 14:53:33
    00. 目录 文章目录00. 目录01. STM32F4时钟系统概述02. STM32F4时钟系统图03. STM32F4时钟初始化配置04. 时钟配置总结05. 预留06. 附录07....为什么 STM32 要有多个时钟源呢? 因为首先 STM32 本身非

    00. 目录

    01. STM32F4时钟系统概述

    时钟系统是 CPU 的脉搏,就像人的心跳一样。所以时钟系统的重要性就不言而喻了。 STM32F4 的时钟系统比较复杂,不像简单的 51 单片机一个系统时钟就可以解决一切。于是有人要问,采用一个系统时钟不是很简单吗?为什么 STM32 要有多个时钟源呢? 因为首先 STM32 本身非常复杂,外设非常的多,但是并不是所有外设都需要系统时钟这么高的频率,比如看门狗以及 RTC 只需要几十 k 的时钟即可。同一个电路,时钟越快功耗越大,同时抗电磁干扰能力也会越弱,所以对于较为复杂的 MCU 一般都是采取多时钟源的方法来解决这些问题。

    02. STM32F4时钟系统图

    在这里插入图片描述

    在 STM32F4 中,有 5 个最重要的时钟源,为 HSI、HSE、LSI、LSE、PLL。其中 PLL 实际是分为两个时钟源,分别为主 PLL 和专用 PLL。从时钟频率来分可以分为高速时钟源和低速时钟源,在这 5 个中 HSI,HSE 以及 PLL 是高速时钟,LSI 和 LSE 是低速时钟。从来源可分为外部时钟源和内部时钟源,外部时钟源就是从外部通过接晶振的方式获取时钟源,其中 HSE 和LSE 是外部时钟源,其他的是内部时钟源。下面我们看看 STM32F4 的这 5 个时钟源,我们讲解顺序是按图中红圈标示的顺序:

    ①、LSI 是低速内部时钟,RC 振荡器,频率为 32kHz 左右。供独立看门狗和自动唤醒单元使用。
    ②、LSE 是低速外部时钟,接频率为 32.768kHz 的石英晶体。这个主要是 RTC 的时钟源。
    ③、HSE 是高速外部时钟,可接石英/陶瓷谐振器,或者接外部时钟源,频率范围为 4MHz~26MHz。我们的开发板接的是 8M 的晶振。HSE 也可以直接做为系统时钟或者 PLL 输入。
    ④、HSI 是高速内部时钟,RC 振荡器,频率为 16MHz。可以直接作为系统时钟或者用作 PLL输入。

    ⑤、PLL 为锁相环倍频输出。STM32F4 有两个 PLL:
    1) 主 PLL(PLL)由 HSE 或者 HSI 提供时钟信号,并具有两个不同的输出时钟。
    第一个输出 PLLP 用于生成高速的系统时钟(最高 168MHz)
    第二个输出 PLLQ 用于生成 USB OTG FS 的时钟(48MHz),随机数发生器的时钟和 SDIO时钟。
    2)专用 PLL(PLLI2S)用于生成精确时钟,从而在 I2S 接口实现高品质音频性能。

    A. 这里是看门狗时钟输入。从图中可以看出,看门狗时钟源只能是低速的 LSI 时钟。

    B. 这里是 RTC 时钟源,从图上可以看出,RTC 的时钟源可以选择 LSI,LSE,以及HSE 分频后的时钟,HSE 分频系数为 2~31。

    C. 这里是 STM32F4 输出时钟 MCO1 和 MCO2。MCO1 是向芯片的 PA8 引脚输出时钟。它有四个时钟来源分别为:HSI,LSE,HSE 和 PLL 时钟。MCO2 是向芯片的PC9 输出时钟,它同样有四个时钟来源分别为:HSE,PLL,SYSCLK 以及 PLLI2S时钟。MCO 输出时钟频率最大不超过 100MHz。

    D. 这里是系统时钟。从图 4.3.1 可以看出,SYSCLK 系统时钟来源有三个方面:HSI,HSE 和 PLL。在我们实际应用中,因为对时钟速度要求都比较高我们才会选用 STM32F4 这种级别的处理器,所以一般情况下,都是采用 PLL 作为 SYSCLK时钟源。根据前面的计算公式,大家就可以算出你的系统的 SYSCLK 是多少。

    E. 这里我们指的是以太网 PTP 时钟,AHB 时钟,APB2 高速时钟,APB1 低速时钟。这些时钟都是来源于 SYSCLK 系统时钟。其中以太网 PTP 时钟是使用系统时钟。AHB,APB2 和 APB1 时钟是经过 SYSCLK 时钟分频得来。这里大家记住,AHB最大时钟为168MHz, APB2高速时钟最大频率为84MHz,而APB1低速时钟最大频率为 42MHz。

    F. 这里是指 I2S 时钟源。从图 4.3.1 可以看出,I2S 的时钟源来源于 PLLI2S 或者映射到 I2S_CKIN 引脚的外部时钟。I2S 出于音质的考虑,对时钟精度要求很高。探索者 STM32F4 开发板使用的是内部 PLLI2SCLK。

    G. 这是 STM32F4 内部以太网 MAC 时钟的来源。对于 MII 接口来说,必须向外部PHY 芯片提供 25Mhz 的时钟,这个时钟,可以由 PHY 芯片外接晶振,或者使用STM32F4 的 MCO 输出来提供。然后,PHY 芯片再给 STM32F4 提供ETH_MII_TX_CLK 和 ETH_MII_RX_CLK 时钟。对于 RMII 接口来说,外部必须提供 50Mhz 的时钟驱动 PHY 和 STM32F4 的 ETH_RMII_REF_CLK,这个 50Mhz时钟可以来自 PHY、有源晶振或者 STM32F4 的 MCO。我们的开发板使用的是RMII 接 口 , 使 用 PHY 芯 片 提 供 50Mhz 时 钟 驱 动 STM32F4 的ETH_RMII_REF_CLK。

    H. 这里是指外部 PHY 提供的 USB OTG HS(60MHZ)时钟。

    03. STM32F4时钟初始化配置

    STM32F4 时钟系统初始化是在 system_stm32f4xx.c 中的 SystemInit()函数中完成的。对于系统时钟关键寄存器设置主要是在 SystemInit 函数中调用 SetSysClock()函数来设置的。我们可以先看看 SystemInit ()函数体。

    /**
      * @brief  Setup the microcontroller system
      *         Initialize the Embedded Flash Interface, the PLL and update the 
      *         SystemFrequency variable.
      * @param  None
      * @retval None
      */
    void SystemInit(void)
    {
      /* FPU settings ------------------------------------------------------------*/
      #if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
        SCB->CPACR |= ((3UL << 10*2)|(3UL << 11*2));  /* set CP10 and CP11 Full Access */
      #endif
      /* Reset the RCC clock configuration to the default reset state ------------*/
      /* Set HSION bit */
      RCC->CR |= (uint32_t)0x00000001;
    
      /* Reset CFGR register */
      RCC->CFGR = 0x00000000;
    
      /* Reset HSEON, CSSON and PLLON bits */
      RCC->CR &= (uint32_t)0xFEF6FFFF;
    
      /* Reset PLLCFGR register */
      RCC->PLLCFGR = 0x24003010;
    
      /* Reset HSEBYP bit */
      RCC->CR &= (uint32_t)0xFFFBFFFF;
    
      /* Disable all interrupts */
      RCC->CIR = 0x00000000;
    
    #if defined(DATA_IN_ExtSRAM) || defined(DATA_IN_ExtSDRAM)
      SystemInit_ExtMemCtl(); 
    #endif /* DATA_IN_ExtSRAM || DATA_IN_ExtSDRAM */
             
      /* Configure the System clock source, PLL Multiplier and Divider factors, 
         AHB/APBx prescalers and Flash settings ----------------------------------*/
      SetSysClock();
    
      /* Configure the Vector Table location add offset address ------------------*/
    #ifdef VECT_TAB_SRAM
      SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM */
    #else
      SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH */
    #endif
    }
    

    在设置完相关寄存器后,接下来 SystemInit 函数内部会调用 SetSysClock 函数。

    /**
      * @brief  Configures the System clock source, PLL Multiplier and Divider factors, 
      *         AHB/APBx prescalers and Flash settings
      * @Note   This function should be called only once the RCC clock configuration  
      *         is reset to the default reset state (done in SystemInit() function).   
      * @param  None
      * @retval None
      */
    static void SetSysClock(void)
    {
    #if defined(STM32F40_41xxx) || defined(STM32F427_437xx) || defined(STM32F429_439xx) || defined(STM32F401xx) || defined(STM32F412xG) || defined(STM32F413_423xx) || defined(STM32F446xx)|| defined(STM32F469_479xx)
    /******************************************************************************/
    /*            PLL (clocked by HSE) used as System clock source                */
    /******************************************************************************/
      __IO uint32_t StartUpCounter = 0, HSEStatus = 0;
      
      /* Enable HSE */ //HSE时钟使能
      RCC->CR |= ((uint32_t)RCC_CR_HSEON);
      //等待HSE时钟稳定
      /* 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)
      {
        /* Select regulator voltage output Scale 1 mode */
        RCC->APB1ENR |= RCC_APB1ENR_PWREN;
        PWR->CR |= PWR_CR_VOS;
    	//AHB不分频
        /* HCLK = SYSCLK / 1*/
        RCC->CFGR |= RCC_CFGR_HPRE_DIV1;
    
    #if defined(STM32F40_41xxx) || defined(STM32F427_437xx) || defined(STM32F429_439xx) ||  defined(STM32F412xG) || defined(STM32F446xx) || defined(STM32F469_479xx)    
        /* PCLK2 = HCLK / 2*/ //高速APB二分频
        RCC->CFGR |= RCC_CFGR_PPRE2_DIV2;
        
        /* PCLK1 = HCLK / 4*/ //低速APB4分频
        RCC->CFGR |= RCC_CFGR_PPRE1_DIV4;
    #endif /* STM32F40_41xxx || STM32F427_437x || STM32F429_439xx  || STM32F412xG || STM32F446xx || STM32F469_479xx */
    
    #if defined(STM32F401xx) || defined(STM32F413_423xx)
        /* PCLK2 = HCLK / 1*/
        RCC->CFGR |= RCC_CFGR_PPRE2_DIV1;
        
        /* PCLK1 = HCLK / 2*/
        RCC->CFGR |= RCC_CFGR_PPRE1_DIV2;
    #endif /* STM32F401xx || STM32F413_423xx */
    
    #if defined(STM32F40_41xxx) || defined(STM32F427_437xx) || defined(STM32F429_439xx) || defined(STM32F401xx) || defined(STM32F469_479xx)    
        /* Configure the main PLL */
        RCC->PLLCFGR = PLL_M | (PLL_N << 6) | (((PLL_P >> 1) -1) << 16) |
                       (RCC_PLLCFGR_PLLSRC_HSE) | (PLL_Q << 24);
    #endif /* STM32F40_41xxx || STM32F401xx || STM32F427_437x || STM32F429_439xx || STM32F469_479xx */
    
    #if  defined(STM32F412xG) || defined(STM32F413_423xx) || defined(STM32F446xx)
        /* Configure the main PLL */
        RCC->PLLCFGR = PLL_M | (PLL_N << 6) | (((PLL_P >> 1) -1) << 16) |
                       (RCC_PLLCFGR_PLLSRC_HSE) | (PLL_Q << 24) | (PLL_R << 28);
    #endif /* STM32F412xG || STM32F413_423xx || STM32F446xx */    
        
        /* Enable the main PLL */
        RCC->CR |= RCC_CR_PLLON;
    
        /* Wait till the main PLL is ready */
        while((RCC->CR & RCC_CR_PLLRDY) == 0)
        {
        }
       
    #if defined(STM32F427_437xx) || defined(STM32F429_439xx) || defined(STM32F446xx) || defined(STM32F469_479xx)
        /* Enable the Over-drive to extend the clock frequency to 180 Mhz */
        PWR->CR |= PWR_CR_ODEN;
        while((PWR->CSR & PWR_CSR_ODRDY) == 0)
        {
        }
        PWR->CR |= PWR_CR_ODSWEN;
        while((PWR->CSR & PWR_CSR_ODSWRDY) == 0)
        {
        }      
        /* Configure Flash prefetch, Instruction cache, Data cache and wait state */
        FLASH->ACR = FLASH_ACR_PRFTEN | FLASH_ACR_ICEN |FLASH_ACR_DCEN |FLASH_ACR_LATENCY_5WS;
    #endif /* STM32F427_437x || STM32F429_439xx || STM32F446xx || STM32F469_479xx */
    
    #if defined(STM32F40_41xxx)  || defined(STM32F412xG)  
        /* Configure Flash prefetch, Instruction cache, Data cache and wait state */
        FLASH->ACR = FLASH_ACR_PRFTEN | FLASH_ACR_ICEN |FLASH_ACR_DCEN |FLASH_ACR_LATENCY_5WS;
    #endif /* STM32F40_41xxx  || STM32F412xG */
    
    #if defined(STM32F413_423xx)  
        /* Configure Flash prefetch, Instruction cache, Data cache and wait state */
        FLASH->ACR = FLASH_ACR_PRFTEN | FLASH_ACR_ICEN |FLASH_ACR_DCEN |FLASH_ACR_LATENCY_3WS;
    #endif /* STM32F413_423xx */
    
    #if defined(STM32F401xx)
        /* Configure Flash prefetch, Instruction cache, Data cache and wait state */
        FLASH->ACR = FLASH_ACR_PRFTEN | FLASH_ACR_ICEN |FLASH_ACR_DCEN |FLASH_ACR_LATENCY_2WS;
    #endif /* STM32F401xx */
    
        /* Select the main PLL as system clock source */
        RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));
        RCC->CFGR |= RCC_CFGR_SW_PLL;
    
        /* Wait till the main PLL is used as system clock source */
        while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS ) != RCC_CFGR_SWS_PLL);
        {
        }
      }
      else
      { /* If HSE fails to start-up, the application will have wrong clock
             configuration. User can add here some code to deal with this error */
      }
    #elif defined(STM32F410xx) || defined(STM32F411xE)
    #if defined(USE_HSE_BYPASS) 
    /******************************************************************************/
    /*            PLL (clocked by HSE) used as System clock source                */
    /******************************************************************************/
      __IO uint32_t StartUpCounter = 0, HSEStatus = 0;
      
      /* Enable HSE and HSE BYPASS */
      RCC->CR |= ((uint32_t)RCC_CR_HSEON | RCC_CR_HSEBYP);
     
      /* 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)
      {
        /* Select regulator voltage output Scale 1 mode */
        RCC->APB1ENR |= RCC_APB1ENR_PWREN;
        PWR->CR |= PWR_CR_VOS;
    
        /* HCLK = SYSCLK / 1*/
        RCC->CFGR |= RCC_CFGR_HPRE_DIV1;
    
        /* PCLK2 = HCLK / 2*/
        RCC->CFGR |= RCC_CFGR_PPRE2_DIV1;
        
        /* PCLK1 = HCLK / 4*/
        RCC->CFGR |= RCC_CFGR_PPRE1_DIV2;
    
        /* Configure the main PLL */
        RCC->PLLCFGR = PLL_M | (PLL_N << 6) | (((PLL_P >> 1) -1) << 16) |
                       (RCC_PLLCFGR_PLLSRC_HSE) | (PLL_Q << 24);
        
        /* Enable the main PLL */
        RCC->CR |= RCC_CR_PLLON;
    
        /* Wait till the main PLL is ready */
        while((RCC->CR & RCC_CR_PLLRDY) == 0)
        {
        }
    
        /* Configure Flash prefetch, Instruction cache, Data cache and wait state */
        FLASH->ACR = FLASH_ACR_PRFTEN | FLASH_ACR_ICEN |FLASH_ACR_DCEN |FLASH_ACR_LATENCY_2WS;
    
        /* Select the main PLL as system clock source */
        RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));
        RCC->CFGR |= RCC_CFGR_SW_PLL;
    
        /* Wait till the main PLL is used as system clock source */
        while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS ) != RCC_CFGR_SWS_PLL);
        {
        }
      }
      else
      { /* If HSE fails to start-up, the application will have wrong clock
             configuration. User can add here some code to deal with this error */
      }
    #else /* HSI will be used as PLL clock source */
      /* Select regulator voltage output Scale 1 mode */
      RCC->APB1ENR |= RCC_APB1ENR_PWREN;
      PWR->CR |= PWR_CR_VOS;
      
      /* HCLK = SYSCLK / 1*/
      RCC->CFGR |= RCC_CFGR_HPRE_DIV1;
      
      /* PCLK2 = HCLK / 2*/
      RCC->CFGR |= RCC_CFGR_PPRE2_DIV1;
      
      /* PCLK1 = HCLK / 4*/
      RCC->CFGR |= RCC_CFGR_PPRE1_DIV2;
      
      /* Configure the main PLL */
      RCC->PLLCFGR = PLL_M | (PLL_N << 6) | (((PLL_P >> 1) -1) << 16) | (PLL_Q << 24); 
      
      /* Enable the main PLL */
      RCC->CR |= RCC_CR_PLLON;
      
      /* Wait till the main PLL is ready */
      while((RCC->CR & RCC_CR_PLLRDY) == 0)
      {
      }
      
      /* Configure Flash prefetch, Instruction cache, Data cache and wait state */
      FLASH->ACR = FLASH_ACR_PRFTEN | FLASH_ACR_ICEN |FLASH_ACR_DCEN |FLASH_ACR_LATENCY_2WS;
      
      /* Select the main PLL as system clock source */
      RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));
      RCC->CFGR |= RCC_CFGR_SW_PLL;
      
      /* Wait till the main PLL is used as system clock source */
      while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS ) != RCC_CFGR_SWS_PLL);
      {
      }
    #endif /* USE_HSE_BYPASS */  
    #endif /* STM32F40_41xxx || STM32F427_437xx || STM32F429_439xx || STM32F401xx || STM32F469_479xx */  
    }
    

    先使能外部时钟 HSE,等待 HSE 稳定之后,配置AHB,APB1,APB2 时钟相关的分频因子,也就是相关外设的时钟。等待这些都配置完成之后,打开主 PLL 时钟,然后设置主 PLL 作为系统时钟 SYSCLK 时钟源。如果 HSE 不能达到就绪状态(比如外部晶振不能稳定或者没有外部晶振),那么依然会是 HSI 作为系统时钟。

    在这里要特别提出来,在设置主 PLL 时钟的时候,会要设置一系列的分频系数和倍频系数参数。大家可以从 SetSysClock 函数的这行代码看出:

        /* Configure the main PLL */
        RCC->PLLCFGR = PLL_M | (PLL_N << 6) | (((PLL_P >> 1) -1) << 16) |
                       (RCC_PLLCFGR_PLLSRC_HSE) | (PLL_Q << 24);
    

    这些参数是通过宏定义标识符的值来设置的。默认的配置在 System_stm32f4xx.c 文件开头的地方配置。对于我们开发板,我们的设置参数值如下:

    #define PLL_M 8
    #define PLL_Q 7
    #define PLL_N 336
    #define PLL_P 2
    

    这里还有个特别需要注意的地方,就是我们还要同步修改 stm32f4xx.h 中宏定义标识符HSE_VALUE 的值为我们的外部时钟:

    #if !defined (HSE_VALUE)
    #define HSE_VALUE ((uint32_t)8000000) /*!< Value of the External oscillator in Hz */
    #endif /* HSE_VALUE */
    

    这里默认固件库配置的是 25000000,我们外部时钟为 8MHz,所以我们根据我们硬件情况修改为 8000000 即可。

    04. 时钟配置总结

    最后我们总结一下 SystemInit()函数中设置的系统时钟大小:

    SYSCLK(系统时钟) =168MHz

    AHB 总线时钟(HCLK=SYSCLK) =168MHz

    APB1 总线时钟(PCLK1=SYSCLK/4) =42MHz

    APB2 总线时钟(PCLK2=SYSCLK/2) =84MHz

    PLL 主时钟 =168MHz

    05. 预留

    06. 附录

    6.1 【STM32】STM32系列教程汇总

    网址:【STM32】STM32系列教程汇总

    07. 声明

    展开全文
  • STM32 时钟系统

    2020-08-11 08:19:07
    时钟系统是 CPU 的脉搏,就像人的心跳...为什么 STM32 要有多个时钟源呢? 因为首先STM32 本身非常复杂,外设非常的多,但是并不是所有外设都需要系统时钟这么高的频率,比如看门狗以及 RTC 只需要几十 k 的时钟即可。
  • 为什么 STM32 要有多个时钟源呢? 我们在学习51单片机时,其最小系统必有晶振电路,这块电路就是单片机的时钟来源,晶振的振荡频率直接影响单片机的处理速度。STM32相比51单片机就复杂得多,不仅是外设非常多,就连...

    时钟是处理器运行的基础,时钟信号推动处理器内各个部分执行相应的指令。时钟系统就是CPU的脉搏,决定CPU速率,像人的心跳一样 只有有了心跳,人才能做其他的事情,而单片机有了时钟,才能够运行执行指令,才能够做其他的处理 (点灯,串口,ADC),时钟的重要性不言而喻。

    为什么 STM32 要有多个时钟源呢?

    我们在学习51单片机时,其最小系统必有晶振电路,这块电路就是单片机的时钟来源,晶振的振荡频率直接影响单片机的处理速度。STM32相比51单片机就复杂得多,不仅是外设非常多,就连时钟来源就有四个。但我们实际使用的时候只会用到有限的几个外设,使用任何外设都需要时钟才能启动,但并不是所有的外设都需要系统时钟那么高的频率,为了兼容不同速度的设备,有些高速,有些低速,如果都用高速时钟,势必造成浪费,而且,同一个电路,时钟越快功耗越快,同时抗电磁干扰能力也就越弱,所以较为复杂的MCU都是采用多时钟源的方法来解决这些问题,因此便有了STM32的时钟系统和时钟树。



    在这里插入图片描述

    1 STM32时钟硬件电路

    STM32三个不同的时钟源可以用来驱动系统时钟(SYSCLK):

    ● HSI晶振时钟(高速内部时钟信号)
    ● HSE晶振时钟(高速外部时钟信号)
    ● PLL时钟

    STM32有两个二级时钟源:

    ● 40kHz的低速内部RC,它可以驱动独立看门狗,还可选择地通过程序选择驱动RTC。 RTC用于从停机/待机模式下自动唤醒系统。
    ● 32.768kHz的低速外部晶振,可选择它用来驱动RTC(RTCCLK)。
    每个时钟源在不使用时都可以单独被打开或关闭,这样就可以优化系统功耗。

    在这里插入图片描述

    图1时钟树

    当使用HSI作为PLL时钟的输入时,所能达到的最大系统时钟为64MHz。

    1.1 HSE时钟

    高速外部时钟信号(HSE)由以下两种时钟源产生:
    ● HSE外部晶体 / 陶瓷 谐振器(见图2(a))
    ● HSE用户外部时钟(见图2(b))
    在这里插入图片描述

    (a)外部时钟 (b)晶振时钟

    图2 HSE时钟

    1.外部时钟源(HSE旁路)
    在这种模式下,必须提供一个外部时钟源。它的频率可高达25MHz。外部时钟信号(占空比为50%的方波、 正弦波或三角波)必须连到OSC_IN引脚,同时保证OSC_OUT引脚悬空,见图2(a)。这个外部时钟源是指从其他处理器等引入的时钟源,STM32的demo板就是使用的这种方式,主控器MCU的外部时钟源来自ST Link处理器提供的时钟信号。

    2.外部晶体 / 陶瓷谐振器(HSE晶体)
    这个4~16MHz的外部晶振的优点在于能产生非常精确的主时钟。 图3显示了它需要的相关硬件配置。谐振器和负载电容需要尽可能近地靠近振荡器的引脚,以减小输出失真和启动稳定时间。负载电容值必须根据选定的晶振进行调节。这种方式也是我们常用的方式,具体电路如下所示。
    在这里插入图片描述

    图3外部晶体电路图

    1.2 LSE时钟

    低速外部时钟源(LSE)可以由两个可能的时钟源来产生:

    ● LSE外部晶体 / 陶瓷谐振器(见图4(a))
    ● LSE用户外部时钟(见图4(b))

    1.外部源(LSE 旁路)
    在这种模式下,必须提供一个外部时钟源。它的频率必须为32.768kHz。外部信号(占空比为50%的方波、 正弦波或三角波)必须连到OSC32_IN引脚,同时保证OSC_OUT引脚悬空。

    2.外部晶体 / 陶瓷谐振器(LSE晶体)
    这个LSE晶体是一个32.768kHz的低速外部晶体或陶瓷谐振器。它的优点在于能为实时时钟部件(RTC)提供一个低速的,但高精确的时钟源。 RTC可以用于时钟/日历或其它需要计时的场合。谐振器和加载电容需要尽可能近地靠近晶振引脚,这样能使输出失真和启动稳定时间减到最小。负载电容值必须根据选定的晶振进行调节。外部晶体时钟如图5所示。
    在这里插入图片描述

    (a)外部时钟 (b)晶振时钟

    图4 LSE时钟

    在这里插入图片描述

    图5外部RTC时钟源

    HSE和LSE外部晶体两时钟电路的两个电容式为了抗干扰。对抗自然界中的一些干扰,如雷击。

    2 STM32 的时钟系统

    STM32 芯片为了实现低功耗,设计了一个功能完善但却非常复杂的时钟系统。普通的MCU 一般只要配置好 GPIO 的寄存器就可以使用了,但 STM32 还有一个步骤,就是开启外设时钟。

    在这里插入图片描述

    图6 STM32的时钟树

    在 STM32 中,可分为五种时钟源,为 HSI、 HSE、 LSI、 LSE、 PLL。 从时钟频率来分可以分为高速时钟源和低速时钟源,其中 HIS, HSE 以及 PLL 是高速时钟, LSI 和 LSE 是低速时钟。从来源可分为外部时钟源和内部时钟源,外部时钟源就是从外部通过接晶振的方式获取时钟源,其中 HSE 和 LSE 是外部时钟源,其他的是内部时钟源。下面我们看看 STM32 的 5 个时钟源,我们讲解顺序是按图中红圈标示的顺序:

    1.HSI 是高速内部时钟, RC 振荡器,频率为 8MHz。

    2.HSE 是高速外部时钟,可接石英 /陶瓷谐振器,或者接外部时钟源,频率范围为4MHz~16MHz。 我们的开发板接的是 8M 的晶振。当使用有源晶振时,时钟从 OSC_IN 引脚进入, OSC_OUT 引脚悬空,当选用无源晶振时,时钟从 OSC_IN 和 OSC_OUT 进入,并且要配谐振电容。HSE 最常使用的就是 8M 的无源晶振。当确定 PLL 时钟来源的时候, HSE 可以不分频或者 2 分频,这个由时钟配置寄存器 CFGR 的位 17。

    3.LSI 是低速内部时钟,RC 振荡器,频率为 40kHz。独立看门狗的时钟源只能是 LSI,同时 LSI 还可以作为 RTC 的时钟源。

    4.LSE 是低速外部时钟,接频率为 32.768kHz 的石英晶体。这个主要是 RTC 的时钟源。

    5.PLL 为锁相环倍频输出,其时钟输入源可选择为 HSI/2、HSE 或者 HSE/2。倍频可选择为2~16 倍,但是其输出频率最大不得超过 72MHz。

    图中我们用 A~E 标示我们要讲解的地方。

    A. MCO 是 STM32 的一个时钟输出 IO(PA8),它可以选择一个时钟信号输出, 可以选择为 PLL 输出的 2 分频、 HSI、 HSE、或者系统时钟。这个时钟可以用来给外部其他系统提供时钟源。

    B. 这里是 RTC 时钟源,从图上可以看出, RTC 的时钟源可以选择 LSI, LSE,以及HSE 的 128 分频。

    C. 从图中可以看出 C 处 USB 的时钟是来自 PLL 时钟源。 STM32 中有一个全速功能的 USB 模块,其串行接口引擎需要一个频率为 48MHz 的时钟源。该时钟源只能从 PLL 输出端获取,可以选择为 1.5 分频或者 1 分频,也就是,当需要使用 USB模块时, PLL 必须使能,并且时钟频率配置为 48MHz 或 72MHz。

    D. D 处就是 STM32 的系统时钟 SYSCLK,它是供 STM32 中绝大部分部件工作的时钟源。系统时钟可选择为 PLL 输出、 HSI 或者 HSE。系统时钟最大频率为 72MHz,当然你也可以超频,不过一般情况为了系统稳定性是没有必要冒风险去超频的。

    E. 这里的 E 处是指其他所有外设了。从时钟图上可以看出,其他所有外设的时钟最终来源都是 SYSCLK。 SYSCLK 通过 AHB 分频器分频后送给各模块使用。这些模块包括:
    ①AHB 总线、内核、内存和 DMA 使用的 HCLK 时钟。
    ②通过 8 分频后送给 Cortex 的系统定时器时钟,也就是 systick 了。
    ③直接送给 Cortex 的空闲运行时钟 FCLK。
    ④送给 APB1 分频器。 APB1 分频器输出一路供 APB1 外设使用(PCLK1,最大频率 36MHz),另一路送给定时器(Timer)2、 3、 4 倍频器使用。
    ⑤送给 APB2 分频器。 APB2 分频器分频输出一路供 APB2 外设使用(PCLK2,最大频率 72MHz),另一路送给定时器(Timer)1 倍频器使用。
    其中需要理解的是 APB1 和 APB2 的区别, APB1 上面连接的是低速外设,包括电源接口、备份接口、 CAN、 USB、 I2C1、 I2C2、 UART2、 UART3 等等, APB2 上面连接的是高速外设包括 UART1、 SPI1、 Timer1、 ADC1、 ADC2、所有普通 IO 口(PA~PE)、第二功能 IO 口等。

    不同的总线有不同的频率,不同的外设挂在不同的总线下,为了更适合初学者查阅,笔者把常用的外设与总线的对应关系总结如下:
    在这里插入图片描述

    图7 STM32F1总线与外设对应关系

    SystemInit()函数中设置的系统时钟大小:

     SYSCLK(系统时钟) =72MHz
     AHB 总线时钟(使用 SYSCLK) =72MHz
     APB1 总线时钟(PCLK1) =36MHz
     APB2 总线时钟(PCLK2) =72MHz
     PLL 时钟 =72MHz

    具体代码请读者查看工程文件的system_stm32f10x.c文件。

    举个例子:Keil编写程序是默认的时钟为72Mhz,其实是这么来的:外部晶振(HSE)提供的8MHz(与电路板上的晶振的相关)通过PLLXTPRE分频器后,进入PLLSRC选择开关,进而通过PLLMUL锁相环进行倍频(x9)后,为系统提供72MHz的系统时钟(SYSCLK)。之后是AHB预分频器对时钟信号进行分频,然后为低速外设提供时钟。

    或者内部RC振荡器(HSI) 为8MHz /2 为4MHz 进入PLLSRC选择开关,通过PLLMUL锁相环进行倍频(x18)后 为72MHz。

    PS: 网上有很多人说是5个时钟源,这种说法有点问题,学习之后就会发现PLL并不是自己产生的时钟源,而是通过其他三个时钟源倍频得到的时钟,这点在前文已近讲解得很清楚了。

    3 Systick系统定时器工作原理分析

    SysTick 定时器被捆绑在 NVIC 中,用于产生 SysTick 异常(异常号 :15)。在以前,操作系统和所有使用了时基的系统都必须有一个硬件定时器来产生需要的“滴答”中断,作为整个系统的时基。滴答中断对操作系统尤其重要。例如,操作系统可以为多个任务分配不同数目的时间片,确保没有一个任务能霸占系统 ;或者将每个定时器周期的某个时间范围赐予特定的任务等,操作系统提供的各种定时功能都与这个滴答定时器有关。因此,需要一个定时器来产生周期性的中断,而且最好还让用户程序不能随意访问它的寄存器,以维持操作系统“心跳”的节律。

    Cortex-M3 在内核部分包含了一个简单的定时器——SysTick。因为所有的 CM3 芯片都带有这个定时器,软件在不同芯片生产厂商的 CM3 器件间的移植工作就得以简化。该定时器的时钟源可以是内部时钟(FCLK,CM3 上的自由运行时钟),或者是外部时钟( CM3 处理器上的 STCLK 信号)。不过,STCLK 的具体来源则由芯片设计者决定,因此不同产品之间的时钟频率可能大不相同。因此,需要阅读芯片的使用手册来确定选择什么作为时钟源。在 STM32 中 SysTick 以 HCLK(AHB 时钟)或 HCLK/8 作为运行时钟。

    SysTick 定时器能产生中断,CM3 为它专门开出一个异常类型,并且在向量表中有它的一席之地。它使操作系统和其他系统软件在 CM3 器件间的移植变得简单多了,因为在所有 CM3 产品间,SysTick 的处理方式都是相同的。SysTick 定时器除了能服务于操作系统之外,还能用于其他目的,如作为一个闹铃、用于测量时间等。Systick 定时器属于Cortex 内核部件,可以参考《ARM Cortex-M3 权威指南》((英)JosephYiu 著,宋岩译,北京航空航天大学出版社出版)或“STM32xxx-Cortex-M3programmingmanual”(这是 ST 官方提供的电子版编程手册,可以在 ST 官网下载)来了解。

    [ps]本文的时钟系统基于STM32F1,ST的其他系列的时钟系统类似。

    关于SysTick 定时器实现请看笔者博文:

    Systick系统定时器
    Systick系统定时器(HAL库)


    欢迎访问我的网站:

    BruceOu的哔哩哔哩
    BruceOu的主页
    BruceOu的博客
    BruceOu的CSDN博客
    BruceOu的简书

    接收更多精彩文章及资源推送,请订阅我的微信公众号:

    在这里插入图片描述

    展开全文
  • STM32时钟系统

    2018-12-16 17:46:46
    STM32 STM32的 时钟系统比较复杂,不像简单的 时钟系统比较复杂,不像简单的 时钟系统比较复杂,不像简单51 单片机一个系统时钟就可以解决...为什么 STM32 要有多个时钟源呢? 要有多个时钟源呢? 因为首先 STM32 ST...

    STM32 STM32的 时钟系统比较复杂,不像简单的 时钟系统比较复杂,不像简单的 时钟系统比较复杂,不像简单51 单片机一个系统时钟就可以解决切。于 单片机一个系统时钟就可以解决切。于 单片机一个系统时钟就可以解决切。于 是有人要问,采用一个系统时钟不很简单吗?为什么 是有人要问,采用一个系统时钟不很简单吗?为什么 STM32 要有多个时钟源呢? 要有多个时钟源呢? 因为首先 STM32 STM32本身非常复杂,外设的多但是并不所有都需要系统时钟这么高频率比 本身非常复杂,外设的多但是并不所有都需要系统时钟这么高频率比 本身非常复杂,外设的多但是并不所有都需要系统时钟这么高频率比 本身非常复杂,外设的多但是并不所有都需要系统时钟这么高频率比 本身非常复杂,外设的多但是并不所有都需要系统时钟这么高频率比 如看门狗以及 RTCRTC 只需要几十 只需要几十 k的时钟即可。同一个电路,越快功耗大抗磁干 的时钟即可。同一个电路,越快功耗大抗磁干 的时钟即可。同一个电路,越快功耗大抗磁干 的时钟即可。同一个电路,越快功耗大抗磁干 的时钟即可。同一个电路,越快功耗大抗磁干 扰能力也会越弱,所以对于较为复杂的 MCU 一般都是采取多时钟源的方法来解决这些问题。 一般都是采取多时钟源的方法来解决这些问题。 
    首先让我们来看 看 STM32 的时钟系统图吧: 
    这里写图片描述

    展开全文
  • STM 32 时钟系统

    2018-09-07 15:38:23
    众所周知,时钟系统是 CPU 的脉搏,就像人的心跳一样。所以时钟系统的重要性就不言而喻了。STM32 的时钟系统比较复杂,不像简单的 51 单片机一个系统时钟就可以解决一切。...为什么 STM32 要有多个时钟源呢?
  • STM32F767时钟树分析

    2019-11-10 18:15:19
    文章目录1、STM32F7 的时钟系统图2、STM...STM32F7的时钟系统比较复杂,有多个时钟源,为什么STM32要有多个时钟源呢?因为首先STM32本身非常复杂,外设非常的多,但是并不是所有外设都需要系统时钟这么高的频率,比...
  • STM32学习——时钟系统 众所周知,时钟系统是 CPU 的脉搏,就像人的心跳一样。...为什么 STM32 要有多个时钟源呢? 因为首先 STM32 本身非常复杂,外设非常的多,但是并不是所有外设都需要系统时钟这...
  • stm32f407】时钟树以及SystemInit剖析

    千次阅读 多人点赞 2017-06-02 16:35:06
    一. 时钟树 众所周知,时钟系统是CPU的脉搏,就像...为什么STM32要有多个时钟源呢?因为首先STM32本身非常复杂,外设非常的多,但是并不是所有外设都需要系统时钟这么高的频率,比如看门狗以及RTC只需要几十k的时钟即
  • STM32F4时钟树概述众所周知,时钟系统是CPU的脉搏,就像人的...为什么STM32要有多个时钟源呢?因为首先STM32本身非常复杂,外设非常的多,但是并不是所有外设都需要系统时钟这么高的频率,比如看门狗以及RTC只需要几...
  • stm32时钟详解

    2019-10-17 18:19:26
    众所周知,时钟系统是 CPU 的脉搏,就像人...为什么 STM32 要有多个时钟源呢? 因为首先STM32 本身非常复杂,外设非常的多,但是并不是所有外设都需要系统时钟这么高的频率,比如看门狗以及 RTC 只需要几十 k 的时钟...
  • STM32时钟系统以及配置及源码分析

    万次阅读 2018-11-07 20:48:07
    目录 1.STM32F429时钟概述 2.系统时钟的初始化寄存器源码分析 3.系统时钟的初始化HAL库函数源码分析 ...1.STM32F429时钟概述 ...为什么 STM32 要有多个时钟源呢? 因为首先 STM32 本身非常复杂,外设...
  • 1. 为什么 STM32 要有多个时钟源呢? 因为STM32非常复杂,外设多,但并不是所有外设都需要系统时钟这么高的频率,比如看门狗及RTC只需要几十k的时钟即可。同一电路,时钟越快功耗越大,同时抗电磁干扰能力也会越弱,...
  • 1.STM32时钟系统

    2020-11-09 14:48:09
    为什么 STM32 要有多个时钟源呢? STM32本身十分复杂,外设非常多 但我们实际使用的时候只会用到有限的几个外设,使用任何外设都需要时钟才能启动,但并不是所有的外设都需要系统时钟那么高的频率,...
  • STM32F4时钟树概述众所周知,时钟系统是CPU的脉搏,就像人的...为什么STM32要有多个时钟源呢?因为首先STM32本身非常复杂,外设非常的多,但是并不是所有外设都需要系统时钟这么高的频率,比如看门狗以及RTC只需要几...
  • 为什么 STM32 要有多个时钟源呢? STM32本身十分复杂,外设非常多 但我们实际使用的时候只会用到有限的几个外设,使用任何外设都需要时钟才能启动,但并不是所有的外设都需要系统时钟那么高的频.
  • 学习STM32F429时钟系统笔记

    千次阅读 2017-08-29 20:48:29
    1.为什么 STM32 要有多个时钟源呢? 因为首先 STM32 本身非常复杂,外设非常的多,但是并不是所有外设都需要系统时钟这么高的频率, 比如看门狗以及 RTC 只需要几十 k 的时钟即可。同一个电路,时钟越快功耗越大,...
  • 为什么STM32要有多个时钟源呢?因为首先STM32本身非常复杂,外设非常的多,但是并不是所有外设都需要系统时钟这么高的频率,比如看门狗以及RTC只需要几十k的时钟即可。同一个电路,时钟越快功耗越大,同时抗电磁干扰...
  • STM32为什么要有复杂的时钟系统 首先STM32 本身非常复杂,外设非常的,但是并不是所有外设都需要系统时钟这么高的频率,比如看门狗以及 RTC 只需要几十 k 的时钟源即可。同一电路,时钟越快功耗越大,同时抗电磁...

空空如也

空空如也

1 2
收藏数 39
精华内容 15
关键字:

为什么stm32要有多个时钟源