前言
时钟树为单片机及其外设提供系统时钟,以维持他们的正常运转。当然不同的外设正常工作的时钟频率也是不同的,所以为了满足不同的外设都能够以正常的状态运行,这就需要用到时钟树的配置,在时钟树里有许多种不同的配置方法,同时也有不同的时钟源,接下里就对时钟树进行展开。
1.时钟树的结构
上图是时钟树的基本结构,看起来十分复杂,实际上可以分为两大部分,左边是时钟源,右边则通过一系列的操作,来使得输入外设的时钟能够得到满足。
同时由于时钟树寄存器较多,这里就不一一单独介绍,而是在需要用到寄存器的地方最对其进行介绍。
时钟树的时钟源有四个从上到下分别为:HSI内部低速时钟、HSE外部高速时钟、LSE外部低速时钟、LSI内部低速时钟,其中还包含PLL(Phase-Locked Loop)锁相环的时钟输出,接下来一一进行介绍。
2.时钟源
2.1数据选择器的介绍
在介绍时钟源之前,需要对结构中的梯形结构数据选择器进行介绍,方便对后续的时钟理解。
2.1.1 PLLSRC (PLL输入时钟源)(PLL entry clock source)
需要明确一点,数据选择器的配置都在在RCC_CFGR时钟配置寄存器中,所以接下对症下药,查看该寄存器的大致结构。
可以看到,在这个32为的寄存器中,不均匀的分布着许多数据选择器的控制位。
查看我们所需要的PLLSRC也就是第16位:
该位是用来配置PLL(Phase-Locked Loop)锁相环的输入时钟源的,时钟源可以是HSI内部低速时钟经过2分频后或者HSE外部高速时钟直接作为时钟源,对PLLSRC数据选择器置0或者1来实现。
2.1.2 PLLMUL PLL倍频系数 (PLL multiplication factor)
PLLMUL倍频系数选择器是在PLLSRC选择完输入时钟源的情况下,将输入的时钟源在PLLMUL中进行倍频操作,以此来提高系统时钟的频率输出,来满足需要高频时钟的外设。
同样在CFGR寄存器中找到对应的位:
该数据选择器占用了四位,也就对应16种不同的倍频输出,也就是2~16,可以注意到1110和1111实现的结果是一样的,因为1倍频等价位不倍频。若不倍频的化就不需要进入到PLL时钟线路中了,HSE和HSI都可以直接作为系统时钟输入源,无需多此一举,所以0000对应的就是2倍频时钟输出,而1110和1111实现的结果是一样的。
通过对CFGR寄存器的位21到18进行位设置,就能够得到所需要的倍频。
需要注意的是,PLL锁相环倍频输出的频率不能够超过72MHz,这里不需要知道原理,而我们一般用的也就是72MHz,就是通过HSE输出的8MHz经过PLL锁相环9倍频得到的72MHz系统时钟。
72MHz系统时钟源的选择
为什么不选用HSI的8MHz来进行时钟倍频呢?
首先,我们一般需要的是72MHz的系统时钟,而HSI需要除上2才能够进入到PLL锁相环,也就是 4MHz,经过最大倍频(16倍频)得到的系统时钟也只有64MHz,不满足72MHz。
同时HSI内部是由RC振荡的来的时钟源,即使在校准之后它的时钟频率精度仍较差,所以使用精度更高的HSE通过9倍频来的得到72MHz系统时钟。
2.1.3 SW[1:0]系统时钟切换(System clock switch)
然后是上图右边的带有SW字样的数据选择器,同样可以看到在寄存器的低2位SW[1:0],查找到对应的寄存器位描述:
该选择的输入有HSI内部高速时钟、PLLCKL锁相环时钟、HSE外部高速时钟,可以通过SW数据选择器进行选择,实际上就是通过对CFGR寄存器的低2位SW[1:0]来设置的。
SW[1:0] | 对应选择的时钟源 |
00 | HSI作为系统时钟 |
01 | HSE作为系统时钟 |
10 | PLL作为系统时钟 |
11 | 不可用 |
2.1.4 PLLXTPRE HSE分频器作为PLL输入 (HSE divider for PLL entry)
接下来对PLLXTPRE数据选择器进行介绍:
同样在寄存器中找到对应的控制位:
这个数据选择器的针对HSE对PLL输入的控制选择,可以直接将HSE时钟输入到PLL,或是2分频后再进行输入到PLL锁相环中,如下图所示:
同时结合前面的PLLSRC(PLL输入时钟源)若需要HSE的时钟输入,则需要先将PLLSRC位(也就是RCC_CFGR寄存器的第16位)置1,然后再对PLLXTPRE进行输入控制选择。
2.1.5 RTCSEL[1:0] RTC时钟源选择 (RTC clock source selection)
通过查找CFGR寄存器中的位,并未找到对应的位。
由于数据选择器的输出是RTCCLK也就是RTC时钟,所以需要在RTC时钟寄存器中寻找。
可以看到,这是一个备份域控制寄存器,图中的注意也就是为什么这些控制位会单独出现在RCC_BDCR备份域控制寄存器中,这些位在复位后会进入写保护状态(不能写操作),只有电源控制寄存器PWR_CR中的DBP位置1才能进行写操作来改变这些位的状态。
而RTCSEL[1:0]在该寄存器的第8和第9位中,找到对应的位描述:
很简单,就是对RTC时钟源的选择,需要注意的是一旦通过软件设置了RTCSEL[1:0]位来选择一个RTC时钟源,这个选择就会一直保持,直到下一次后备域被复位。这意味着在正常运行期间,你不能简单地通过修改RCC_BDCR寄存器来改变RTC的时钟源。如果你确实需要更改RTC的时钟源,你需要执行以下步骤:
1.禁用RTC:首先,你需要通过软件禁用RTC,或者至少确保在更改时钟源时RTC的操作不会受到干扰。
2.重置后备域:通过设置RCC_BDCR寄存器中的BDRST(第16位)位来重置后备域。这将清除后备域的所有配置,包括RTC的时钟源设置。请注意,这也会导致后备寄存器和RTC(如果它正在运行)中的数据丢失。
3.重新配置RTC:在后备域重置后,你可以重新设置RTC的时钟源和其他相关参数。
通过对RTCSEL[1:0]位的设置,可以选择LSE、LSI或者HSE128分频后作为RTC时钟。
2.1.6 MCO 微控制器时钟输出 (Microcontroller clock output)
最后是MCO主时钟输出,在CFGR寄存器找到对应的位:
MCO属于单片对外的时钟输出,来源可以为PLLCLK锁相环时钟除2、HSI、HSE、SYSCLK(系统时钟),对MCO进行位设置即可实现选择时钟操作。
以上是对时钟树的数据选择器进行描述,接下来对时钟源进行展开。
2.2内部低速时钟HSI(High-Speed Internal Clock)
2.3外部高速时钟HSE(High-Speed External Clock)
2.4外部低速时钟LSE(Low-Speed External Clock)
LSE晶体是一个32.768kHz的低速外部晶体或陶瓷谐振器。它为实时时钟或者其他定时功能提供一个低功耗且精确的时钟源。
2.5内部低速时钟LSI(Low-Speed Internal Clock)
2.6锁相环时钟PLL(Phase-Locked Loop Clock)
2.7CSS时钟安全系统(CSS)
2.8系统时钟的输入来源
图中的黑色、紫色、红色,分别对应HSI、PLL、HSE的时钟输出,最终输出到SYSCLK系统时钟,供外设使用。
3.时钟的分频
类似的,72MHz系统时钟经过APB2预分频器1分频,作为时钟输入PCLK2,同时如果APB2预分频系数为1,则频率不变,否则×2。输入到TIM1和TIM8中的TIM定时器也为72MHz所以可以得出,TIMx所有定时器的输入时钟频率都为72MHz。
同样的,这72MHz系统时钟还输入到DMA,ADC、SDIO等外设,这些就自行探索,这里就不在进行展开。
在固件库中,ST公司已经帮我们配置好了时钟树的开启,在SystemInit函数中,感兴趣的可以去了解。
4.总结
最后希望这篇文章能够帮助到有需要的人,也欢迎各位讨论及指正。