开始我们今天的内容,今天主要讲解systeminit ,
参考《STM32中文参考手册》、STM32库函数开发
回顾一下上一讲有五个的时钟来源
1.LSI 低速的内部时钟
2.LSE 低速的外部时钟
3HSI 高速的内部时钟
4PLLCLK 通过锁相环
5 HSE高速的外部时钟
SYSCLK 系统时钟,他的主要来源有1HSI 2HSE 3PLLCLK,大部分情况都是用PLLCLK,应为F4芯片可以跑到168Mhz,PLLCLK主要来自主PLLCLK的锁相环,时钟 法人计算方法 之前已经说过,主PLLCLK的锁相环可以选择HSI、HSE作为时钟输入,在我们系统初始化的时候(正点原子)使用的是HSE(高速的外部时钟),这里选用的HSE是8M,计算公式在上一讲已经讲过,经过计算后 就得到168Mhz的时钟。正点原子的SYSteminit()函数在system——stm32xx.h里面,在系统复位之后 是先执行这个SYSteminit()函数的,
在系统复位之后,为什么要先调用这个函数再调用mian函数呢?在CORE文件中的startup_stm32f40_41xx.s中有几行代码, 这几行代码我们不深究,他是说明在执行mian函数之前先执行systeminit这个函数。
接下来我们看systeminit()这个函数,
FPU seting是 浮点运算的配置,到后面再讲解
下面这几行代码是将CR寄存器的最低位设置成1,作用:打开HSI时钟,
CR 寄存器的作用: 使能一些时钟
我们来看一下CR寄存器的最低位,位0使能HSI( 内部高速时钟) 位1内部高速时钟就绪标志。
我们要使用这些时钟的步骤(以LSI为例)
1打开时钟源
2等待 时钟就绪(等待时钟稳定)
systeminit函数还有5行代码,都是Reset,就是将相应的位设置为0
这里先把CFGR寄存器全部设置为0,然后把这个CR寄存器相应的位设置为0,并把不用的时钟也设置为0(关闭),
并关闭了所有的中断(上图这些位的设置我们可以对照寄存器去 设置)
下面我们举例说明这些寄存器的设置,CR&0xFEF6FFFF(1111 1110 0110 1111 1111 1111 1111)
可以看出这里把第16位设为0,关闭HSE,第19位为0,关闭时钟安全系统(CSSON)
CSS作用:当外部晶振坏了,就会将时钟切换到HSI,
第24位PLLON 为0 将主PLL 关闭,其他的可以对照寄存器去看
接下来就到 SetSysClock();这个是一个关键
我们进入SetSysClock()函数看一下:
正点原子这里用了8M的外部晶振。
下面这句就是等待外部时钟稳定
如果时钟就绪,就将HSEstatus设置为1
当HSEstatus稳定并被设置为1, 就开始执行下面 的代码
1.打开了PWR的时钟,配置PWR相关寄存器,
下面这个寄存器是操作这个CFGR寄存器HCLK=SYSCLK,其中HCLK是由SYSCLK经过AHB的预分频器产生的,也就是说这里AHB的预分频系数是1,(不分频)
下图是CFGR预分频器的第7-4位,上面这里设为全0,就是不分频
下面这几行代码是将PCLK2设置为HCLK的2分频,PCLK1设置为HCLK的4分频
下面这几行代码就包括了设置了 HCLK PCLK1 PCLK2 几个时钟的分频,这些时钟都是给外设用的
接下就是设置PLLCFGR 寄存器,这个寄存器主要是用来设置倍频系数、分频系数。
PLLCFGR在时钟树里面就是用设置 xN /P /M 这三个值 的,这几个值就直接关系到PLLCLK的大小
在设置之前先要进行运算
设置了PLLCFGR位22,选择HSE振荡器时钟作为PLL和PLLI2S时钟输入,
在运算过程中选择 RCC_PLLCFGR_PLLSRC_HSE做或运算,作用是把HSE作为下图选择器的输入
然后就去计算,之后赋值给这个PLLCFGR,下面这些值可以通过宏定义查看
下图就是计算相关参数的宏定义,通过 这些值可以计算我们的系统时钟频率,计算方法在《STM32库函数开发指南》4.3.2小节
设置好上面这些之后,我们就可以使能主PLL也就是右图的PLLCLK
接下来就要把系统时钟的时钟源选择为PLLCLK,
RCC_CFGR的为0和位1就是用于系统时钟切换的
到此,我们配置了HCLK PLLCLK2 PLLCLK1,
选择HSE作为PLLCLK的时钟源,
将系统时钟选择为了PLLCLK
补充:因为系统时钟比flash时钟 要快,所以要等待一下系统时钟,这个在中文参考手册,嵌入式flash接口这里有描述
总结:系统时钟 函数配置过程:
1选择HSE作为时钟源,并使能,
2然后 就将HCLK APB1 APB2这些分频系数设置好
3将HSE作为 主PLL的时钟源
4配置 M N P这些参数,产生PLLCLK,使能PLLCLK,等待它 就绪
5选择PLLCLK作为系统时钟的时钟源。