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;
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的会不同