基于STM32+芯片内部时钟树详解和系统时钟内部流程解析

前言

       本次我们认识一下STM32F103的时钟树架构,以及系统时钟在内部的初始化是怎么处理的,大部分是自己收集和整理,如有侵权请联系我删除。

交流群:717237739

如果觉得有用点赞关注收藏三连,多谢支持

本博客内容原创,创作不易,转载请注明

1.初步认识时钟树(HSI,HSE,LSI,LSE,PLL)

        在 STM32 中,有五个时钟源,为 HSI、HSE、LSI、LSE、PLL。从时钟频率来分可以分为 高速时钟源和低速时钟源,在这 5 个中 HIS,HSE 以及 PLL 是高速时钟,LSI 和 LSE 是低速时 钟。从来源可分为外部时钟源和内部时钟源,外部时钟源就是从外部通过接晶振的方式获取时 钟源,其中 HSE 和 LSE 是外部时钟源,其他的是内部时钟源。

HSI振荡器时钟(高速内部时钟)--- 频率为 8MHz

产生的频率精度不是很高,一般使用内部晶振
当HSI被用于作为PLL时钟的输入时,系统时钟能得到的最大频率是64MHz。
HSI时钟信号由内部8MHz的RC振荡器产生,可直接作为系统时钟或在2分频后作为PLL输入
时钟控制寄存器中的HSIRDY位用来指示HSI RC振荡器是否稳定。
在时钟启动过程中,直到这一位被硬件置’1’,HSI RC输出时钟才被释放。HSI RC可由时钟控制寄存器中的HSION位来启动和关闭。

HSE振荡器时钟(高速外部时钟)

在这个模式里,必须提供外部时钟。它的频率最高可达25MHz。(F1为8M,F4为25M)
可接石英/陶瓷谐振器,或者接外部时钟源,频率范围为4MHz~16MHz。
在时钟控制寄存器RCC_CR中的HSERDY位用来指示高速外部振荡器是否稳定。

LSE低速外部时钟 --- 频率为 32.768kHz 的石英晶体

40kHz低速内部RC,可以用于驱动独立看门狗和通过程序选择驱动RTC。
LSE晶体是一个32.768kHz的低速外部晶体或陶瓷谐振器。它为实时时钟或者其他定时功能提供一个低功耗且精确的时钟源。
LSE晶体通过在备份域控制寄存器(RCC_BDCR)里的LSEON位启动和关闭。

 LSI低速内部时钟

LSI RC担当一个低功耗时钟源的角色,它可以在停机和待机模式下保持运行,为独立看门狗和自动唤醒单元提供时钟。
LSI时钟频率大约40kHz(在30kHz和60kHz之间)。
LSI RC可以通过控制/状态寄存器(RCC_CSR)里的LSION位来启动或关闭。

LSI校准 --- 只有大容量和互联型产品可以进行LSI校准

    可以通过校准内部低速振荡器LSI来补偿其频率偏移,从而获得精度可接受的RTC时间基数,以 及独立看门狗(IWDG)的超时时间(当这些外设以LSI为时钟源)。 校准可以通过使用TIM5的输入时钟(TIM5_CLK)测量LSI时钟频率实现。测量以HSE的精度为保 证,软件可以通过调整RTC的20位预分频器来获得精确的RTC时钟基数,以及通过计算得到精 确的独立看门狗(IWDG)的超时时间。

小结:通过对上面的五个时钟源的介绍和说明,相信大家对于ST芯片内部的时钟有了大概的了解,但是对于这些了解,我们并不知道了解的作用在哪里。

下面我们继续说明,讲一下这些时钟在内部是怎么实现的

很多人都以为函数的执行是从main函数实现的,其实这种说法也是可以的,但是在一定程度上来说,程序的执行都需要先运行启动文件,就相当于你电脑开机的等待一样,我们单片机的运行也是从启动文件开始的,确定好相应的时钟配置后,我们才会执行到main函数。 

2. 系统初始化函数

建议大家在看这个流程的时候,最好打开自己的工程一步一步看下去,我这的图片放的有限。

从启动文件开始,调用了系统初始化函数(SystemInit)和main函数

 1)复位RCC时钟

2)开启内部高速时钟--HSE

很多小伙伴可能还没有学过寄存器说明,后面我会在C专栏写一个博客,目前我们首先打开HSE时钟,时钟开启的时候都需要复位(图片绿色部分英文说明),而在前面的时候我们已经看到RCC已经复位了。

这个函数意思是在RCC的CR寄存器里面,在第0位置1,下面我们看看寄存器第0位为1代表什么:

代表了开启HSI的时钟;

 3)关闭了 HSEON, CSSON and PLLON - - - 0xFEF6FFFF

这里我们可以通过位运算来看,因为芯片是32位的,所以0xFEF6FFFF的二进制位为:

1111 1110 1111 0110 1111 1111 1111 1111  可以看到是第16,19,24位清0

4)复位了Reset HSEBYP - - - 0xFFFBFFFF(第18位清0--1011)

 5)复位了Reset PLLSRC, PLLXTPRE, PLLMUL and USBPRE/OTGFSPRE - - - 0xFF80FFFF

        这个时候也有人有疑问了,既然我们要使用,为什么要打开,又要关闭,到底应该配置哪些时钟芯片才能驱动? 

其他时钟介绍:

1)PLL时钟源

        PLL时钟来源可以有两个:一个是HSE,另一个是HSI/2。由时钟配置寄存器CFGR的位16,即PLLSRC设置具体用哪个。HSI是内部高速的时钟信号,频率为8MHz,这里我们选择HSE作为PLL的时钟来源。

2)PLL时钟PLLCLK


        通过设置PLL的倍频因子,可以对PLL的时钟来源进行倍频,倍频因子可以是2至16,由时钟配置寄存器CFGR的位21~18,即PLLMUL[3:0]设置,这里设置为9倍频,因为上一步设置PLL的时钟来源为HSE=8MHz,所以PLLCLK=8M*9=72M。72M是ST官方推荐的稳定运行时钟,可以增大倍频因子实现超频,最大为128MHz。

3)系统时钟SYSCLK


        由图可知系统时钟的来源可以是HSI,PLLCLK,HSE,具体由时钟配置寄存器CFGR的为1~0,即SW[1:0]设置。这里设置系统时钟:SYSCLK=PLLCLK=72MHz。

①、AHB 总线、内核、内存和 DMA 使用的 HCLK 时钟。

②、通过 8 分频后送给 Cortex 的系统定时器时钟,也就是 systick 了。

③、直接送给 Cortex 的空闲运行时钟 FCLK。

④、送给 APB1 分频器。APB1 分频器输出一路供 APB1 外设使用(PCLK1,最大 频率 36MHz),另一路送给定时器(Timer)2、3、4 倍频器使用。

⑤、送给 APB2 分频器。APB2 分频器分频输出一路供 APB2 外设使用(PCLK2, 最大频率 72MHz),另一路送给定时器(Timer)1 倍频器使用。

4)AHB总线时钟HCLK


        系统时钟SYSCLK经过AHB预分频器分频之后得到的时钟叫APB总线时钟,即HCLK,分频因子可以是[1,2,4,8,16,64,128,256,512],具体由时钟配置寄存器CFGR的位7~4,即HPRE[3:0]设置。这里设置为1分频,即HCLK=SYSCLK=72MHz。

5)APB1总线时钟HCLK1


        APB1总线时钟PCLK1由HCLK经过低速APB2预分频器得到,分频因子可以是[1,2,4,8,16],具体由时钟配置寄存器CFGR的位10~8,即PRRE1[2:0]设置。HCLK1属于低速的总线时钟,最高为36MHz。片上低速外设就挂载到这条总线上,比如USART2/3/4/5,SPI2/3,IIC1/IIC2等。这里设置2分频,即PCLK1=HCLK/2=36MHz。

包括电源接口、 备份接口、CAN、USB、I2C1、I2C2、UART2、UART3 等等

6)APB2总线时钟HCLK2


        APB2总线时钟PCLK2由HCLK经过高速APB2预分频器得到,分频因子可以是[1,2,4,8,16],具体由时钟配置寄存器CFGR的位13~11,即PPRE2[2:0]设置。HCLK2属于高速的总线时钟,片上高速外设就挂载到这条总线上,比如全部GPIO,USART1,SPI1等。这里设置1分频,即PCLK2=HCLK=72MHz。

高速外设包 括 UART1、SPI1、Timer1、ADC1、ADC2、所有普通 IO 口(PA~PE)、第二功能 IO 口等。

3.调用了设置系统时钟函数

        对于系统时钟,默认情况 下是在 SystemInit 函数的 SetSysClock()函数中间判断的,而设置是通过宏定义设置的。

        STM32 时钟系统的配置除了初始化的时候在 system_stm32f10x.c 中的 SystemInit()函数中 外,其他的配置主要在 stm32f10x_rcc.c 文件中,里面有很多时钟设置函数,大家可以打开这个 文件浏览一下,基本上看看函数的名称就知道这个函数的作用。

        经过上面的时钟配置后,现在才开始进入我们需要的时钟配置选择,我们点击这个函数,F12跳转过去看看说明:

        当我们设置好系统时钟后,可以通过变量 SystemCoreClock 获取系统时钟 值,如果系统是 72M 时钟,那么 SystemCoreClock=72000000。这是在 system_stm32f10x.c 文件中设置的,

         因为我们的芯片系统时钟频率默认为72M,所以我们直接跳转到这个72M的函数里面看看别人是怎么帮我们配置好时钟的。

1)等待HSE启动,晶振启动需要一定的时间,如果超时则进入中断

        系统时钟 SYSCLK,它是供 STM32 中绝大部分部件工作的时 钟源。系统时钟可选择为 PLL 输出、HSI 或者 HSE。系统时钟最大频率为 72MHz, 当然你也可以超频,不过一般情况为了系统稳定性是没有必要冒风险去超频的。

        因为HSE是外部高速时钟,所以一般来时我们首先应该先驱动外部晶振,如果启动不成功,则表明外部晶振虚焊或者没有,这个时候我们系统则会选择用内部时钟驱动,但是内部晶振不稳定,所以一般出现芯片无法使用,也可以检查一下外部晶振。

里面的寄存器说明和定义我就不一一举例了,因为定义实在太多了,经过上面的说明大家应该对寄存器怎么赋值应该了解了,我们在例程里面直接跳转过去看定义了解。

 2)设置AHB时钟等于系统时钟,设置APB2的时钟不分频

3)设置APB1的时钟为2分频 - - APB1的时钟为36M

4)配置主PLL时钟为系统时钟72M 

        因为 USB 的时钟是来自 PLL 时钟源。STM32 中有一个全速功能 的 USB 模块,其串行接口引擎需要一个频率为 48MHz 的时钟源。该时钟源只能 从 PLL 输出端获取,可以选择为 1.5 分频或者 1 分频,也就是,当需要使用 USB 模块时,PLL 必须使能,并且时钟频率配置为 48MHz 或 72MHz。

5)打开PLL时钟

总结: 

        经过上面的步骤,我们初步认识了时钟树和时钟的配置流程,不过一般来说这些并不需要我们配置,但是我们也要了解为什么要这样配置才能使用,毕竟有的时候我们移植或者用其他芯片的时候,可能也会需要改动时钟树的内容。

交流群:717237739

如果觉得有用点赞关注收藏三连,多谢支持

本博客内容原创,创作不易,转载请注明

                点赞关注双击博主,不定期分享单片机知识,互相学习交流。

  • 15
    点赞
  • 54
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值