目录
注:本博文只是对正点原子课程的又一次重复,总结正点的教程、写一些自己的感悟,并非以原创之名做抄袭之事。
STM32F4与51相比有着复杂的时钟树,本篇博文旨在记录各个时钟之间的关系,理清STM32F4的时钟树。
一、时钟简介
1. 什么是时钟?
**时钟是单片机运行的基础,时钟信号推动单片机内各个部分执行相应的指令。**时钟系统就是CPU的脉搏,决定cpu速率,像人的心跳一样 只有有了心跳,人才能做其他的事情,而单片机有了时钟,才能够运行执行指令,才能够做其他的处理 (点灯,串口,ADC),时钟的重要性不言而喻。
参考:CSDN博主【Z小旋】的博客【STM32】系统时钟RCC详解(超详细,超全面)
2. 为什么 STM32 要有多个时钟源呢?
STM32本身十分复杂,外设非常多 但我们实际使用的时候只会用到有限的几个外设,使用任何外设都需要时钟才能启动,但并不是所有的外设都需要系统时钟那么高的频率,为了兼容不同速度的设备,有些高速,有些低速,如果都用高速时钟,势必造成浪费 并且,同一个电路,时钟越快功耗越快,同时抗电磁干扰能力也就越弱,所以较为复杂的MCU都是采用多时钟源的方法来解决这些问题。所以便有了STM32的时钟系统和时钟树。
二、时钟树示意图简介
首先放出时钟树示意图如下所示:
看似庞大的时钟树,我们对它分一下块(时钟 + 锁相环 + 外设),情况就会变得简单:
上图中,时钟①②③④ + 锁相环都是能产生时钟的部分,另外还有左下角没框出来的一堆如ETH_MI_TX_CLK_MII等可以产生时钟的器件,但它们不重要,暂时不考虑。
除了时钟+锁相环外,其他的基本都是外设,也就是接收并使用时钟的外部设备。如果没有时钟供应的话,单片机上的所有设备都是不能工作的。
除时钟、锁相环、外设以外,还有两种比较重要的设备:
① 分频器:
形如这个写着**/2到31**的方框,就是一个分频器,表示它可以将一个频率为f的时钟信号,转化为 f/2 ~ f/31 区间内任意频率大小的时钟信号。
② 选择器:
形如上图中的梯形,就是一个选择题,它从右边四个输入中选择一个,并在左边进行输出。
三、时钟①②③④+锁相环的介绍
1. 时钟①②③④的介绍
时钟①: LSI,低(Low)速(Speed)内部(Inter)时钟,由RC振荡器产生,频率为32kHZ左右,频率不稳定,供独立看门狗和自动唤醒单元使用。
时钟②: LSE,低(Low)速(Speed)外部(Extern)时钟, 由32.768kHZ的石英晶体产生,频率比较稳定,主要是 RTC(实时时钟Real_Time_Clock) 的时钟源。
时钟③: HSE,高速外部时钟,可由晶振或外部时钟源产生,频率范围为 4MHz~26MHz,可以直接作为系统时钟(图中的SYSCLK)或者 PLL(锁相环) 输入。
时钟④: HSI,高速内部时钟,由RC振荡器产生,频率为16MHZ,可以直接作为系统时钟或者用作 PLL(锁相环) 输入。
2. 锁相环(PLL)的介绍
2.1中介绍过,HSE和HSI都可作为锁相环的输入,那么锁相环在接收到这个时钟输入以后,做了什么呢?
通俗来讲,锁相环就是接受一个时钟输入,然后经过分频、倍频等操作,生成一个具有新频率的时钟信号,再输出出来。
下面我们对一个锁相环进行分析:
如上图所示,最右边的选择器选择一个时钟信号 f ,然后 f 向左经过分频器,得到 f / M,这就是锁相环的输入,此处记作 C = f / M;
C在锁相环中经过 压控振荡器(VCO) 或 倍频器(xN),得到一个具有新频率的时钟信号,我们此处以经过倍频器为例,得到 C x N,再向右经过三个分频器(/P,/Q,/R)中的任意一个(其实这个锁相环并没有在/R处设置输出,所以起作用的分频器只有/P和/Q两个),此处以经过/P为例,得到输出①为 C x N / P。
综上所述,频率为f的时钟信号经过分频器、锁相环后得到的输出时钟信号的频率计算公式为:
outF = (f / M) x N / P
3. STM32F4为什么有两个锁相环?
位于上方的锁相环①,叫做主PLL,输出的时钟信号可用于多种外设。
位于下方的锁相环②,叫做专用PLL,它是专门为I2S提供稳定、精确的时钟信号的(I2S对时钟信号要求较高)。
四、如何在程序中配置时钟
1. RCC寄存器
RCC(Reset and Clock Control)寄存器,汉语名称为复位和时钟控制寄存器,顾名思义,它既能控制时钟源的使能,也能控制外设时钟的使能,同时还能对外设进行复位。
在程序中配置时钟,实际上就是要配置RCC寄存器。
2. 如何配置RCC寄存器
在 STM32F4 标准固件库里,RCC相关函数控制着时钟源的选择以及时钟使能等,且这些函数都是在 RCC 相关固件库文件 stm32f4xx_rcc.h 和 stm32f4xx_rcc.c 中声明和定义的。
这些函数大致可以归结为三类(以下有第四类,但不常用):
① 一类是外设时钟使能函数;
② 一类是时钟源和分频因子配置函数,也就是配置选择器和分频器;
③ 还有一类是外设复位函数;
④ 最后还有少数几个获取时钟源配置的函数。
解释:
-
要想使用一个外设,就必须对外设的时钟进行使能,这对应上述①;
-
对外设时钟进行使能后,必须给它提供时钟信号,这就要使能时钟源,同时可能需要使能选择器和分频器,这对应上述②;
-
如果外设出现了问题,要进行复位,这对应上述③;
-
如果要知道某个时钟源的当前频率,这就要知道它的当前配置,这对应上述④。
2.1 如何使能外设时钟?
STM32F4共有五条总线 (AHB1、AHB2、AHB3、APB1、APB2) ,每条总线都挂载了一定数量的外设。
要想使能外设时钟,首先要知道这个外设挂在哪条总线下,比如GPIOA的所有引脚都挂在AHB1下,那么我们要对连接到GPIOA的外设时钟进行使能,就要调用如下函数:
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE);//使能 GPIOA 时钟
STM32F4的RCC固件库共给出了五个外设时钟使能函数,如下所示,分别对应着五条总线:
void RCC_AHB1PeriphClockCmd(uint32_t RCC_AHB1Periph, FunctionalState NewState);
void RCC_AHB2PeriphClockCmd(uint32_t RCC_AHB2Periph, FunctionalState NewState);
void RCC_AHB3PeriphClockCmd(uint32_t RCC_AHB3Periph, FunctionalState NewState);
void RCC_APB1PeriphClockCmd(uint32_t RCC_APB1Periph, FunctionalState NewState);
void RCC_APB2PeriphClockCmd(uint32_t RCC_APB2Periph, FunctionalState NewState);
查到外设在哪条总线下后,调用相应函数即可。
2.3 如何使能时钟源?
时钟源使能函数共有六个:
void RCC_HSICmd(FunctionalState NewState);
void RCC_LSICmd(FunctionalState NewState);
void RCC_PLLCmd(FunctionalState NewState);
void RCC_PLLI2SCmd(FunctionalState NewState);
void RCC_PLLSAICmd(FunctionalState NewState);
void RCC_RTCCLKCmd(FunctionalState NewState);
比如我们要使能PLL,那么就要如下调用:
RCC_PLLCmd(ENABLE);