-
STM32时钟设计的比较复杂,各个时钟基本都是可控的,任何外设都
有对应的时钟控制开关,这样的设计,对降低功耗是非常有用的,不用的外设不开启时钟,就可以大大降低其功耗。下面插入时钟树图。

Stm32与51单片机在时钟上有很大不同。51单片机只有唯一的时钟源,而且是12分频,这些在设计之初就是规定好的。Stm32就有很大的灵活性,stm32的时钟来源有好几个我在下面的图中把他标记出来。
Stm32的时钟不是直接使用而且通过寄存器进行配置以后使用。
上面提到过51单片机的是系统设计12分频,stm32的时钟是通过寄存器进行配置,你可以进行倍频也可以分频。
下面看看整个时钟树

我们从上到下从左到右介绍一下,在图中的箭头可以看出来,PLLXTPRE输出的时钟的来源可能是来自HSE OSC也可能是HSE OSC经过二分频,这些是通过寄存器配置。PLLXTPRE输出到PLLSRC,PLLRC时钟来源有PLLXTPRE或者2分频后的8M HSIRC(同样都是经过寄存器配置)。PLLSRC输出后到PLLMUL进行倍频,最大可以16倍的倍频也是经过寄存器配置。

最后就来到sw,系统时钟就是从这里开始选择的。可以来自HSI,PLLCLK,HSE。其他就按照整个线走下来的。
下面引用《stm32开发指南》的部分内容
上图从左往右看,就是整个STM32的时钟走向。这里,我们挑选出5个重要的地方进行
介绍(图5.2.2.1中标出的1~5)。
1、 PLLMUL
PLLMUL用于设置STM32的PLLCLK,STM32支持2~16倍频设置。我们常用
的是8M 外部晶振+9倍频设置,刚好得到72Mhz 的PLLCLK。从上图可以看出,
PLLMUL的时钟源,可以来自内部8M RC振荡/2或者外部高速晶振(4~16Mhz)。这
里切记PLLMUL设置后的频率不要超过72Mhz(想超也是可以,最大128M也可以跑,
不过一旦出问题ST是不负责的!)。
2、 SW
SW是STM32的SYSCLK(系统时钟)切换开关,从上图可以看出,SYSCLK的
来源可以是3个:HSI、PLLCLK和HSE。我们一般选择PLLCLK作为SYSCLK。SYSCLK
最大为72M。这里提示一下大家:STM32刚上电的时候,用的是系统内部8M RC时
钟,之后运行程序才会把时钟源设置为其他。
3、 系统滴答时钟(SYSTICK)
SYSTICK就是CortexM3的系统滴答时钟,上图清楚的表明SYSTICK的来源是
AHB分频后再8分频,因为我们一般设置AHB不分频,所以SYSTICK的频率就等于
SYSCLK/8,如果SYSCLK为72M,那么SYSTICK的频率就是9Mhz。前面介绍的延
时函数,就是基于SYSTICK来实现的。
4、 PCLK1
PCLK1是APB1总线上外设的时钟,最大为36Mhz,所有挂载在APB1上的外设,
最大时钟都是36Mhz(定时器除外,原因见上图),比如串口2~5、SPI2和SPI3等,
在使用的时候,要特别留意。PCLK1的时钟可以通过APB1预分频器设置,我们默认
一般设置为2分频。
5、 PCLK2
PCLK2是APB2总线上外设的时钟,最大为72Mhz,所有挂载在APB2上的外设,
最大时钟都是72Mhz,比如GPIOA~G、串口1、SPI1、ADC1~3等。 PCLK2的时钟
可以通过APB2预分频器设置,我们默认一般设置为1,也就是不分频。
关于时钟的详细介绍,在《STM32参考手册》第6.2节(55~60页)有详细介绍。有不明
白的地方,可以对照手册仔细研究。
有句很重要的话我单独列出来
从上图可以看出STM32的时钟设计的比较复杂,各个时钟基本都是可控的,任何外设都
有对应的时钟控制开关,这样的设计,对降低功耗是非常有用的,不用的外设不开启时钟,就可以大大降低其功耗。
时钟初始化代码
void Stm32_Clock_Init(u8 PLL)
{
unsigned char temp=0;
MYRCC_DeInit(); //复位并配置向量表
RCC->CR|=0x00010000; //外部高速时钟势能HSEON
while(!(RCC->CR>>17));//等待外部时钟就绪[其他位的初始值为0]
RCC->CFGR=0X00000400; //APB1=DIV2;APB2=DIV1;AHB=DIV1;
PLL-=2;//设置pll的值
RCC->CFGR|=PLL<<18; //设置pll的值为2~16
RCC->CFGR|=1<<16; //PLLSRC ON [HSE时钟作为pll输入时钟]
FLASH->ACR|=0x32; //falsh2个延时周期
RCC->CR|=0x01000000; //PLLON
while(!(RCC->CR>>25));//等待pll锁定
RCC->CFGR|=0x00000002;//pll作为系统时钟
while(temp!=0x02) //等待PLL作为时钟设置成功
{
temp=RCC->CFGR>>2;
temp&=0x03;
}
}
有两个个寄存器要对着stm32参考手册看看,分别是:时钟控制寄存器(RCC_CR) ,时钟配置寄存器(RCC_CFGR)。
首先开启即将设置的时钟,我们使用的是外部时钟,开启外部时钟。开启需要一段时间,等待开启的标志位变成1.接下来就按照箭头指示挨个设置寄存器。
在sw的位置,选择pll作为时钟来源。然后等待时钟设置成功,就完成了系统时钟的初始化。
其他的时钟设置就在使用的时候开启,设置。