在stm32中,时钟系统是非常重要的一环,他控制着整个系统的频率。因此,我们有理由好好学一下时钟系统。
什么是时钟?
时钟是具有周期性的脉冲信号,一般我们常用占空比为50%的方波。可以形象的说,时钟就是单片机的脉搏。
在我常用的stm32F1系列中,分别有HSE(高速外部),LSE(低速外部),HSI(高速内部),LSI(低速内部)。高速的两个一般用于滴答时钟,低速的两个一般用于RTC。其中还有两个比较少见的,分别是CSS(时钟安全系统)和FCLK(自由运行时钟)。CSS作用为若HSE启动失败,自动切换HSI,且其可以进NMI中断。FCLK用于采样中断和调试模块记时。休眠时仍然有效。
接着我们来看一下stm32f103的时钟树简图。如图所示,如果HSE和HSI直接给SYSCLK频率,很明显是够不着st公司为SYSCLK设定的官方最大频率的。那他是怎么做到的呢?那就是分频+PLL(锁相环)。分频就是使频率变为输入的频率的整数分之一,具体由代码实现。PLL原理在此不细说,总而言之就是他可以使分频后的频率乘以一个2~16的数,使得输出的频率变大。若如图的,72MHZ就有可能是8*9=72MHZ。
在进入SYSCLK(系统时钟)以后,会继续分频输出一个频率给HCLK(AHB总线时钟),在AHB总线上挂载了内核系统时间和外设,同时继续分频给PCLK1和PCLK2,其分别是APB1总线和APB2总线的时钟,接着在配置链接在这两个总线上的众多外设。
系统时针配置步骤
1.配置HSE_VALUE
配置HSE_VALUE主要是高速HAL库外部的晶振频率。使用的头文件是stm32xxxx_hal_conf.h
2.调用SystemInit()函数
在启动文件中调用,在system_stm32xxxx.c中进行定义。如果不需要,可以直接注释掉。
3.选择时钟源,配置PLL
通过HAL_RCC_OscConfig()函数进行设置,其主要选择时HSI还是HSE时钟。其中Osc的意思是振荡器。便是晶振。
HAL_RCC_OscConfig()的形参为一个结构体,名字为RCC_OscInitTypeDef。该结构体决定的就是各个振荡器的参数。并且对于PLL结构体还有一个结构体,这个结构体便是决定PLL的的信号来源,倍数和开启与否。
4.选择系统时钟源,配置总线分频器
通过HAL_RCC_ClockConfig()函数进行设置,他有两个形参,分别是RCC_ClkInitTypeDef*类型的数据和FLatency参数。第一个是用来初始化时钟的,他决定了分频的时候的系数。第二个是用来决定FLASH等待多少周期的,当系统时针周期在0<SYSCLK<<24MHZ的话,选择下图的0个等待周期,24MHZ<SYSCLK<<48MHZ选择一个等待周期,48MHZ<SYSCLK<<72MHZ选择一个等待周期。一般对于stm32f1系列是选择2个等待周期。
ATTENTION!
不知道前面有没有同学注意到,其实我讲漏了一个非常重要的部分,那就是时钟的使能与失能 __HAL_RCC_GPIOA_CLK_ENABLE(); 使能GPIO时钟
__HAL_RCC_GPIOA_CLK_DISABLE(); 失能GPIO时钟