STM32f4学习之路--时钟

初学STM32,发现他的时钟系统有点复杂(相对于之前学的51单片机来说)。这是为什么?
–51单片机的I/O口少,外设简单,所以时钟一般来说都是固定的,这也导致了51单片机应用场景的局限性。
–stm32单片机之所以时钟系统的复杂,这与它芯片本身应用的场景有关,我们知道,32一般都是多引脚且外设多,应用场合也十分广泛,例如一些低功耗、高频率的场合,这些无疑都是得益于他的时钟系统。

1-STM32的时钟来源

stm32总共拥有5个时钟源:
①HSE,high-speed-extern(高速外部时钟)
②HSI,high-speed-inside(高速内部时钟)
③LSE,low-speed-extern(低速外部时钟)
④LSI,low-speed-inside(低速内部时钟)
⑤PLL,锁相环倍频输出时钟

HSE:外部晶振/陶瓷谐振器、精度高。ST官方推荐的外部晶振是8M,如果外接其他类型的晶振,须在stm32f4xx.h程序中修改宏,以及在system_stm32f4xx.c修改PLL
HSI:内部16MRC振荡器,启动速度比HSE快,但精度不及HSE。
LSE:外部晶振/陶瓷谐振器,一般用于实时时钟(RTC)的时钟源,功耗低且精度高。
LSI:内部32KHz振荡器,可作为停机/待机、独立看门狗、自动唤醒单元的时钟源。
PLL:分为主PLL和专用PLL。主PLL由HSE或HSI提供时钟信号,并输出两时钟(1个用于系统时钟168M,1个用于USB OTG FS时钟48M、随机数发生器<=48M、SDIO时钟<=48M);专用PLL与主PLL有相同的输入时钟,但其有专门的使能禁止和分频系数,为I2S提供时钟。
下面是stm32的时钟树,图片太大,我们分开来看。


2-各个功能的时钟来源

看门狗与RTC时钟

STM32f4学习之路--时钟
stm32内部的低速时钟(32KHz)可作为独立看门狗与RTC的时钟源,同时可以看到,RTC的时钟源有3个,另外的两个分别是LSE(32.768KHz)、(分频2-31)后的HSE。


微控制器时钟输出MCO

STM32f4学习之路--时钟
MCO1有4个时钟来源:HSE、HSI、PLL、LSE
MCO2有4个时钟来源:HSE、PLL、PLL2S、SYSCLK
MCO输出时钟不得超过100MHz(最大I/O速度)


系统与外设时钟

STM32f4学习之路--时钟
重点来了,敲黑板!
系统时钟SYSCLK经过分频(1-512)后供给外设使用,其时钟来源包括:HSE、HSI、主PLL
通常我们所说的168MHz其实的来源是:HSE外接8M晶振,经过8分频(/M,M系数为8),然后经过336倍频(*N,N为336),在经过2分频(/P,P为2)后,即(8/8)*336/2=168M
系统主时钟SYSCLK可直接为以太网PTP提供时钟, 也可经过分频(1-512)供给HCLK、AHB总线、内核、存储器、DMA,或者8分频后供给Cortex 系统定时器Systick;SYSCLK在经过AHB(一般不分频,保持168M)分频后再分频为APB1(4分频,因为APB1频率不得超过42M)和APB2(一般2分频,最大不得超过84M)提供时钟。APB1和APB2 各自挂载不同的外设,详细请看datasheet。


ST官方推荐的stm32外部晶振是8M,这样子的话,通常我们只需调用库函数system_stm32f4xx.c中的void SystemInit(void)函数即可进行时钟的配置,默认是168M系统时钟,APB1为42M,APB2为84M,如需要可自行修改。


3-后记

PS:这里刚开始有个疑问为什么TIM14(挂载在APB1)能达到84MHz,,看了时钟树之后才发现,定时器时钟做了另外的处理的,记录下;

从STM32F4的内部时钟树可知,当APB1和APB2分频数为1的时候,TIM1、TIM8~TIM11的时钟为APB2的时钟,TIM2~TIM7、TIM12~TIM14的时钟为APB1的时钟;而如果APB1和APB2分频数不为1,那么TIM1、TIM8~TIM11的时钟为APB2的时钟的两倍,TIM2~TIM7、TIM12~TIM14的时钟为APB1的时钟的两倍。

因为系统初始化SystemInit函数里初始化APB1总线时钟为4分频即42M,APB2总线时钟为2分频即84M,所以TIM1、TIM8~TIM11的时钟为APB2时钟的两倍即168M,TIM2~TIM7、TIM12~TIM14的时钟为APB1的时钟的两倍即84M

另外,TIM_ClockDivision是在采样时使用的时钟分频器,比如输入捕获时的采样时钟或计算互补输出的死区的时钟;时钟分频就一个PSC,还有一个重装载计数值ARR,一般只有设置这两个就够了,TIM_ClockDivision在输入捕获和PWM的互补输出时设置才有意义!