• STM32时钟系统


    STM32时钟系统

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

    在这里插入图片描述

    蓝色框的是5个主要的时钟源,STM32F1所有时钟都来自于这5个时钟源

    绿色框的是分频器,可以将输入的时钟频率根据系数分频,就是直接除以系数后的结果

    灰色框的是选择器,可以选择任意一路输入,作为输出

    STM32有5个时钟源:HSI、HSE、LSI、LSE、PLL

    HSI:高速内部时钟,频率约8MHz,RC振荡器产生的时钟不稳定,所以是约8MHz,精度不高

    HSE:高速外部时钟,可接石英/陶瓷谐振器,或者接外部时钟源,一般外接8M,频率范围为4MHZ~16MHz

    LSE:低速外部时钟,接频率为32.768kHz的石英晶体,作用一般是给RTC时钟提供振荡源

    LSI:低速内部时钟,RC振荡器,约40KHz,提供低功耗时钟,一般作为独立看门狗的时钟

    PLL:锁相环倍频输出,用来倍频,其时钟输入源可选择为HSI/2、 HSE或者HSE/2。倍频可选择为2~16倍,但是其输出频率最大不得超过72MHZ。可通过系数来选择多少倍频;假如系统时钟要的频率是72M,由前面两个选择器过来的时钟频率,假如是8M,经过PLL,则倍频系数是9,倍频后就可以输入到系统时钟进行使用,倍频系数通过相关寄存器配置

    系统时钟SYSCLK可来源于三个时钟源:

    1.HSI振荡器时钟

    2.HSE振荡器时钟

    3.PLL时钟

    几个重要的时钟:

    SYSCLK(系统时钟):一般由外部高速时钟HSE,直接经过锁相环PLL,倍频系数为9,8 * 9 = 72MHz,所以系统时钟一般为72MHz

    AHB总线时钟

    APB1总线时钟(低速):速度最高36MHz

    APB2总线时钟(高速):速度最高72MHz

    PLL时钟

    注意事项

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

    任何一个外设在使用之前,必须首先使能其相应的时钟。

    CSS:时钟监视系统,一般系统时钟会选择HSE作为时钟源,HSE是由外部晶振产生的,具有不稳定性,假如外部晶振坏了,HSE失效了,CSS会检测到,然后自动切换到HSI,使用内部振荡器作为系统时钟,使系统继续工作

    APB1 上面连接的是低速外设,包括电源接口、 备份接口、CAN、USB、I2C1、I2C2、UART2、UART3 等等,APB2 上面连接的是高速外设包 括 UART1、SPI1、Timer1、ADC1、ADC2、所有普通 IO 口(PA~PE)、第二功能 IO 口等。

    RCC相关配置寄存器

    typedef struct
    {
      __IO uint32_t CR;					//HSI,HSE,CSS,PLL等的使能和就绪标志位		————常用
      __IO uint32_t CFGR;				//PLL等的时钟源选择,分频系数设定			————常用
      __IO uint32_t CIR;				//清除/使能时钟就绪中断
      __IO uint32_t APB2RSTR;			//APB2线上外设复位寄存器
      __IO uint32_t APB1RSTR;			//APB1线上外设复位寄存器
      __IO uint32_t AHBENR;				//DMA, SDIO等时钟使能			————常用
      __IO uint32_t APB2ENR;			//APB2线上外设时钟使能			————常用
      __IO uint32_t APB1ENR;			//APB1线上外设时钟使能			——
      __IO uint32_t BDCR;				//备份域控制寄存器
      __IO uint32_t CSR;				//控制状态寄存器
    
    #ifdef STM32F10X_CL  
      __IO uint32_t AHBRSTR;
      __IO uint32_t CFGR2;
    #endif /* STM32F10X_CL */ 
    
    #if defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) || defined (STM32F10X_HD_VL)   
      uint32_t RESERVED0;
      __IO uint32_t CFGR2;
    #endif /* STM32F10X_LD_VL || STM32F10X_MD_VL || STM32F10X_HD_VL */ 
    } RCC_TypeDef;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    RCC固件库相关函数说明

    在这里插入图片描述

    时钟初始化的值

    这里总结一下 SystemInit()函数中设置的系统时钟大小:

    SYSCLK(系统时钟) =72MHz

    AHB 总线时钟(使用 SYSCLK) =72MHz

    APB1 总线时钟(PCLK1) =36MHz

    APB2 总线时钟(PCLK2) =72MHz

    PLL 时钟 =72MHz

    KEIL软件通过调式查看语句执行时间

    STM32系统时钟选择72MHz,硬件仿真的时钟也选择72MHz,两者保持一致,keil设置硬件仿真时钟如下

    在这里插入图片描述

    在这里插入图片描述

    然后使用LED灯闪烁的程序,插上开发板,点击开始调试按钮,进入调试界面

    左下角的Sec就是程序运行的时间,在代码的11,12行加上断点,按全速运行,执行到11行就停下来,但并没有执行delay_ms函数,再按一次全速运行,执行到12行,此时delay_ms函数就被执行了,主要通过Sec查看延时函数运行的时间

    在这里插入图片描述

    执行完delay_ms函数后,时间大概是1秒左右

    在这里插入图片描述

    也可以将STM32系统时钟设置为35MHz,仿真时钟也设为36MHz,再看delay_ms函数的运行时间,与72MHz的会不同

  • 相关阅读:
    设备通过国标GB28181/海康Ehome接入EasyCVR,视频无法打开的原因分析及解决方法
    写论文工具:LaTex在线网站
    ThreeJS进阶之动画系统(Animation system)
    虚幻引擎5亮点整理,5大核心一目了然
    JS逆向-新榜数据nonce和xyz参数分析
    WPF/C#:显示分组数据的两种方式
    深入探讨梯度下降:优化机器学习的关键步骤(一)
    【练习题】一.线性表
    List获取差集产生的问题
    【学习笔记】AGC009/AGC019/AGC029/AGC035
  • 原文地址:https://blog.csdn.net/weixin_46251230/article/details/126557087