初学STM32,感觉最蛋疼的是它的时钟系统,每次看到它的那个时钟树就有点晕,虽然看了很多这方面的资料,甚至也已经写过很多STM32的模块代码,做过一些小项目,但一直还是对这一块模模糊糊,似懂非懂,所以想把自己对它的一点点认识写出来,一步一步,直到完全搞通的那一天,(这些内容并非自己原创,只是想帮助自己理解)

在STM32中,有五个时钟源,为HSI、HSE、LSI、LSE、PLL。

HSI是高速内部时钟,RC振荡器,频率为8MHz。

HSE是高速外部时钟,可接石英/陶瓷谐振器,或者接外部时钟源,频率范围为4MHz~16MHz。

LSI是低速内部时钟,RC振荡器,频率为40kHz。

LSE是低速外部时钟,接频率为32.768kHz的石英晶体。

PLL为锁相环倍频输出,其时钟输入源可选择为HSI/2、HSE或者HSE/2。倍频可选择为2~16倍,但是其输出频率最大不得超过72MHz(F103最大72M,F20x最大为120M,F407最大为168M)。

时钟树见中文参考手册;

用户可通过多个预分频器配置AHB总线、高速APB2总线和低速APB1总线的频率。AHB和APB2域的最大频率是72MHZ。APB1域的最大允许频率是36MHZ。SDIO接口的时钟频率固定为HCLK/2。

40kHz的LSI供独立看门狗IWDG使用,另外它还可以被选择为实时时钟RTC的时钟源。另外,实时时钟RTC的时钟源还可以选择LSE,或者是HSE的128分频。RTC的时钟源通过RTCSEL[1:0]来选择。

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

另外,STM32还可以选择一个PLL输出的2分频、HSI、HSE、或者系统时钟SYSCLK输出到MCO脚(PA8)上。系统时钟SYSCLK,是供STM32中绝大部分部件工作的时钟源,它可选择为PLL输出、HSI或者HSE,(一般程序中采用PLL倍频到72Mhz)在选择时钟源前注意要判断目标时钟源是否已经稳定振荡。Max=72MHz,它分为2路,1路送给I2S2、I2S3使用的I2S2CLK,I2S3CLK;另外1路通过AHB分频器分频(1/2/4/8/16/64/128/256/512)分频后送给以下8大模块使用:

①送给SDIO使用的SDIOCLK时钟。

②送给FSMC使用的FSMCCLK时钟。

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

④通过8分频后送给Cortex的系统定时器时钟(SysTick)。

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

⑥送给APB1分频器。APB1分频器可选择1、2、4、8、16分频,其输出一路供APB1外设使用(PCLK1,最大频率36MHz),另一路送给定时器(Timer2-7)2、3、4倍频器使用。该倍频器可选择1或者2倍频,时钟输出供定时器2、3、4、5、6、7使用。

⑦送给APB2分频器。APB2分频器可选择1、2、4、8、16分频,其输出一路供APB2外设使用(PCLK2,最大频率72MHz),另一路送给定时器(Timer1、Timer8)1、2倍频器使用。该倍频器可选择1或者2倍频,时钟输出供定时器1和定时器8使用。另外,APB2分频器还有一路输出供ADC分频器使用,分频后得到ADCCLK时钟送给ADC模块使用。ADC分频器可选择为2、4、6、8分频。

⑧2分频后送给SDIO AHB接口使用(HCLK/2)。

时钟输出的使能控制

在以上的时钟输出中有很多是带使能控制的,如AHB总线时钟、内核时钟、各种APB1外设、APB2外设等。当需要使用某模块时,必需先使能对应的时钟。需要注意的是定时器的倍频器,当APB的分频为1时,它的倍频值为1,否则它的倍频值就为2。

连接在APB1(低速外设)上的设备有:电源接口、备份接口、CAN、USB、I2C1、I2C2、UART2、UART3、SPI2、窗口看门狗、 Timer2、Timer3、Timer4。注意USB模块虽然需要一个单独的48MHz时钟信号,但它应该不是供USB模块工作的时钟,而只是提供给串行接口引擎(SIE)使用的时钟。USB模块工作的时钟应该是由APB1提供的。

连接在APB2(高速外设)上的设备有:GPIO_A-E、USART1、ADC1、ADC2、ADC3、TIM1、TIM8、SPI1、AFIO;

使用HSE时钟,程序设置时钟参数流程:

1、将RCC寄存器重新设置为默认值 RCC_DeInit;

2、打开外部高速时钟晶振HSE      RCC_HSEConfig(RCC_HSE_ON);

3、等待外部高速时钟晶振工作 HSEStartUpStatus = RCC_WaitForHSEStartUp();

4、设置AHB时钟      RCC_HCLKConfig;

5、设置高速AHB时钟     RCC_PCLK2Config;

6、设置低速速AHB时钟   RCC_PCLK1Config;

7、设置PLL              RCC_PLLConfig;

8、打开PLL              RCC_PLLCmd(ENABLE);

9、等待PLL工作while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET)

10、          设置系统时钟        RCC_SYSCLKConfig;

11、          判断是否PLL是系统时钟     while(RCC_GetSYSCLKSource() != 0x08)

12、          打开要使用的外设时钟RCC_APB2PeriphClockCmd()/RCC_APB1PeriphClockCmd()

关于SystemInit函数

初学时容易让人疑惑的是,在我们源代码的工程项目中,我们并没有去手动设置系统时钟,很多时候根本没去管它,但是我们写的跑马灯、GPIO控制、串口通信等小程序依然能够正常运行,这是为什么呢?

其实根本原因就是系统自己已经替我们设置过了,有一个默认的设置函数(SystemInit()),很奇怪我们在主函数中看不到它的踪影,因为系统把它写在启动文件(startup_xxx.s)中了,并且在主函数之前执行,所以我们看不到,如下图:

  

关于STM32时钟系统的更多相关文章

  1. STM32入门系列-STM32时钟系统,STM32时钟树

    时钟对于单片机来说是非常重要的,它为单片机工作提供一个稳定的机器周期从而使系统能够正常运行.时钟系统犹如人的心脏,一旦有问题整个系统就崩溃.我们知道STM32属于高级单片机,其内部有很多的外设,但不是 ...

  2. STM32时钟系统的配置寄存器和源码分析

    一.时钟系统 概述 时钟是单片机运行的基础,时钟信号推动单片机内各个部分执行相应的指令,时钟系统就是CPU的脉搏,决定cpu速率. STM32有多个时钟来源的选择,为什么 STM32 要有多个时钟源呢 ...

  3. STM32时钟系统

    一.在STM32中,有五个时钟源,为HSI.HSE.LSI.LSE.PLL. ①HSI是高速内部时钟,RC振荡器,频率为8MHz. ②HSE是高速外部时钟,可接石英/陶瓷谐振器,或者接外部时钟源,频率 ...

  4. STM32时钟系统之利用 systick 定时器来实现准确的延时。

    本篇文章带着大家来认识一下 STM32 的时钟系统,以及利用 systick 定时器来实现一个比较准确的延时. 我们首先从时钟说起,时钟在MCU中的作用,就好比于人类的心脏一样不可或缺.STM32 的 ...

  5. STM32入门系列-STM32时钟系统,时钟使能配置函数

    之前的推文中说到,当使用一个外设时,必须先使能它的时钟.怎么通过库函数使能时钟呢?如需了解寄存器配置时钟,可以参考<STM32F10x中文参考手册>"复位和时钟控制(RCC)&q ...

  6. STM32入门系列-STM32时钟系统,自定义系统时钟

    在时钟树的讲解中我们知道,通过修改PLLMUL中的倍系数值(2-16)可以改变系统的时钟频率.在库函数中也有对时钟倍频因子配置的函数,如下: void RCC_PLLConfig(uint32_t R ...

  7. STM32入门系列-STM32时钟系统,时钟初始化配置函数

    在前面推文的介绍中,我们知道STM32系统复位后首先进入SystemInit函数进行时钟的设置,然后进入主函数main.那么我们就来看下SystemInit()函数到底做了哪些操作,首先打开我们前面使 ...

  8. STM32入门-STM32时钟系统,时钟初始化配置函数

    在前面推文的介绍中,我们知道STM32系统复位后首先进入SystemInit函数进行时钟的设置,然后进入主函数main.那么我们就来看下SystemInit()函数到底做了哪些操作,首先打开我们前面使 ...

  9. STM32 时钟系统

    1.在 STM32F4 中,有 5 个最重要的时钟源,为 HSI.HSE.LSI.LSE.PLL.其中 PLL 实际是分为两个时钟源,分别为主 PLL 和专用 PLL. 2.   ①.LSI 是低速内 ...

随机推荐

  1. LRU原理和Redis实现——一个今日头条的面试题(转载)

    很久前参加过今日头条的面试,遇到一个题,目前半部分是如何实现 LRU,后半部分是 Redis 中如何实现 LRU. 我的第一反应是操作系统课程里学过,应该是内存不够的场景下,淘汰旧内容的策略.LRU ...

  2. git ssh 22 端口不可用时通过https 443 端口配置git ssh

    Using SSH over the HTTPS port Sometimes, firewalls refuse to allow SSH connections entirely. If usin ...

  3. MySQL字符集不一致的解决办法总结

    用SHOW CREATE TABLE table_name;可以看出具体的字符集设置. 错误代码: Illegal mix of collations (utf8mb4_unicode_ci,IMPL ...

  4. mybatis 中一对多、多对一、多对多、父子继承关系

    mybatis 中处理一对多.多对一.多对多.父子继承关系的有关键词:association .collection .discriminator id – 一个 ID 结果:标记出作为 ID 的结果 ...

  5. james2.3 配置收件 之 MariaDB数据库配置

    james我们公司一直都是使用的2.3这个稳定版本,现在已经有3.0了,不过无所谓,能用就行 基于2.3,来进行一些配置,主要是接受邮件,之前的博文如何安装的,这里不多做介绍了,链接参考:https: ...

  6. [k8s]debug模式启动集群&k8s常见报错集合(on the fly)

    debug模式启动-支持sa 集群内(pod访问api)使用443加密 no1 no2 安装flanneld kubelet/kube-proxy m1 安装etcd/ api/contruller/ ...

  7. Analyzing the Go runtime scheduler from source code perspective

    http://www.cs.columbia.edu/~aho/cs6998/reports/12-12-11_DeshpandeSponslerWeiss_GO.pdf http://www.cs. ...

  8. Python之string

    1.string模块支持哪些字符形式?分别是什么. string支持的字符形式有: ('_re', '====>', <module 're' from 'C:\Python25\lib\ ...

  9. CentOS7下解决ifconfig command not found的办法

    先 https://www.cnblogs.com/PatrickLiu/p/8433273.html 再 https://blog.csdn.net/ryu2003/article/details/ ...

  10. 为什么要使用NoSQL

    转载自:http://www.infoq.com/cn/news/2011/01/nosql-why [编者按]NoSQL在2010年风生水起,大大小小的Web站点在追求高性能高可靠性方面,不由自主都 ...