stm32时钟树分析
STM32F407ZGT的时钟深入剖析(32M_40M_72M灵活切换)

时钟频率的配置
{开始
ቤተ መጻሕፍቲ ባይዱ
{ /**** 程序总共 2 部分之第 1 部分 时钟频率的配置 ********************/
/***** 以下是关于 RCC 时钟 详细请见《STM32F20XXX 参考手册》5.3 节 RCC 寄存 器描述 *******/
unsigned char sws = 0; RCC->CR |= 0X00010000; //使能外部高速时钟 HSEON while(!(RCC->CR>>17)); //将 RCC_CR 寄存器的值右移 17 位,等待 HSERDY 就绪, 即外部时钟就绪
对于 5, 通过 PLL 选择位预先选择后续 PLL 分支的输入时钟(假设选择外部晶振);
对于 7,设置外部晶振的分频数(假设 1 分频);
对于 21,选择 PLL 倍频的时钟源(假设选择经过分频后的外部晶振时钟);
对于 8,设置 PLL 倍频数(假设 9 倍频);
对于 9,选择系统时钟源(假设选择经过 PLL 倍频所输出的时钟);
众所周知,微控制器(处理器)的运行必须要依赖周期性的时钟脉冲来驱动——往往由 一个外部晶体振荡器提供时钟输入为始,最终转换为多个外部设备的周期性运作为末,这种 时钟“能量”扩散流动的路径,犹如大树的养分通过主干流向各个分支,因此常称之为“时 钟树”。在一些传统的低端 8 位单片机诸如 51,AVR,PIC 等单片机,其也具备自身的一个 时钟树系统,但其中的绝大部分是不受用户控制的,亦即在单片机上电后,时钟树就固定在 某种不可更改的状态(假设单片机处于正常工作的状态)。比如 51 单片机使用典型的 12MHz 晶振作为时钟源,则外设如 IO 口、定时器、串口等设备的驱动时钟速率便已经是固定的, 用户无法将此时钟速率更改,除非更换晶振。
stm32单片机时钟

stm32单⽚机时钟stm32 单⽚机时钟学习以及分析1 引⾔:单⽚机(Microcontrollers),采⽤超⼤规模集成电路技术把具有数据处理能⼒的中央处理器CPU、随机存储器RAM、只读存储器ROM、多种I/O⼝和中断系统、定时器/计数器等功能(可能还包括显⽰驱动电路、脉宽调制电路、模拟多路转换器、A/D转换器等电路)集成到⼀块硅⽚上构成的⼀个⼩⽽完善的微型计算机系统,在⼯业控制领域⼴泛应⽤。
单⽚机时钟可以说如同⼈的⼼脏那样重要,我们在⼼脏的搏动下进⾏⾃⼰的⽣命活动,同样的单⽚机在时钟下进⾏⾃⼰的控制活动。
2 时钟的分类:单⽚机的时钟分为内部时钟与外部时钟:⼀般⽽⾔,内部时钟集成在芯⽚内部(RC振荡电路),其精度⽐较低;外部时钟,顾名思义,存在于芯⽚外部(晶体或陶瓷谐振器),可以为系统提供精确的时钟。
晶振是给单⽚机提供⼯作信号脉冲的,如图所⽰的为外部晶振,频率为4MHz,我们常⽤的晶振频率为12MHz,单⽚机⼯作时,是⼀条⼀条地从RoM中取指令,然后⼀步⼀步地执⾏。
单⽚机访问⼀次存储器的时间,称之为⼀个机器周期,这是⼀个时间基准。
—个机器周期包括12个时钟周期。
如果⼀个单⽚机选择了12MHz晶振,它的时钟周期是1/12us,它的⼀个机器周期是12×(1/12)us,也就是1us。
有些晶振的频率并数是整数,如:11.0592MHz的晶振。
单⽚机在进⾏串⾏通信时,常⽤的波特率为1200,2400,4800,9600,115200等,为了适应单⽚机的串⼝通讯波特率的计算⽽来的。
⽤11.0592MHz晶振经过相应的分频或者倍频后刚好能够得出⼀个整数的波特率,这样在上位机和下位机的同步⽅⾯⽐较⽅便。
3 stm32的时钟来源这⾥以stm32f1系列的芯⽚为例。
由上⾯可知,系统的时钟来源有内部时钟与外部时钟,详细的来说stm32f1有五个时钟源:HSI(⾼速内部时钟)HSE(⾼速外部时钟)LSI(低速内部时钟)LSE(低速外部时钟)PLL(锁相环倍频输出)每⼀个时钟都可以独⽴的开启与关闭。
STM32F4时钟树概述

STM32F4时钟树概述STM32F4 相对于 STM32F1 来说,时钟部分复杂了很多, STM32F4 的时钟配置,我们提供两个函数: Sys_Clock_Set 和Stm32_Clock_Init。
其中 Sys_Clock_Set 是核⼼的系统时钟配置函数,由 Stm32_Clock_Init 调⽤,实现对系统时钟的配置。
外部程序,⼀般调⽤ Stm32_Clock_Init函数来配置时钟。
sys⽂件夹中在 STM32F4 中,有 5 个最重要的时钟源,为 HSI、 HSE、 LSI、 LSE、 PLL。
其中 PLL 实际是分为两个时钟源,分别为主 PLL 和专⽤PLL。
从时钟频率来分可以分为⾼速时钟源和低速时钟源,在这 5 个中 HSI, HSE 以及 PLL 是⾼速时钟, LSI 和 LSE 是低速时钟。
从来源可分为外部时钟源和内部时钟源,外部时钟源就是从外部通过接晶振的⽅式获取时钟源,其中 HSE 和LSE 是外部时钟源,其他的是内部时钟源。
①、 LSI 是低速内部时钟, RC 振荡器,频率为 32kHz 左右。
供独⽴看门狗和⾃动唤醒单元使⽤。
②、 LSE 是低速外部时钟,接频率为 32.768kHz 的⽯英晶体。
这个主要是 RTC 的时钟源。
③、 HSE 是⾼速外部时钟,可接⽯英/陶瓷谐振器,或者接外部时钟源,频率范围为 4MHz~26MHz。
我们的开发板接的是 8M 的晶振。
HSE 也可以直接做为系统时钟或者 PLL 输⼊。
④、 HSI 是⾼速内部时钟, RC 振荡器,频率为 16MHz。
可以直接作为系统时钟或者⽤作 PLL输⼊。
⑤、 PLL 为锁相环倍频输出。
STM32F4 有两个 PLL:1)主 PLL(PLL)由 HSE 或者 HSI 提供时钟信号,并具有两个不同的输出时钟。
第⼀个输出 PLLP ⽤于⽣成⾼速的系统时钟(最⾼ 168MHz)第⼆个输出 PLLQ ⽤于⽣成 USB OTG FS 的时钟(48MHz),随机数发⽣器的时钟和 SDIO时钟。
STM32时钟树

STM32F10xx 时钟树STM32有五个时钟源,HSI RC,HSE OSC,LSI RC,LSE OSC,PLL。
实际是四个,PLL 是由锁相环电路倍频得到的。
HSI 高速内部时钟,8MHzHSE高速外部时钟,频率为4MHz~16MHzLSI 低速内部时钟,40kHzLSE低速外部时钟,32.768kHzPLL的时钟源为两个高速时钟,可选HSI/2,HSE,HSE/2,最大为72MHzOSC 为晶振,振荡器(Oscillator)引脚ˈɒsɪleɪtə(r),STM32F10xx系列处理器有两个外部时钟源,分别接OSC和OSC32引脚,前者为高速,后者为低速。
内置RC振荡器可以被关闭。
STM32有一个时钟监视系统CSS,一旦HSE失效则会自动切换至SYSTICK = HSI。
介绍完时钟源,下面介绍一下STM32每个模块分别对应哪个时钟源。
低速的:1.独立看门狗的时钟源为低速内部时钟LSI ,40kHz2.RTC时钟的时钟源可以有三个,分别为LSI,LSE或者HSE的128分频,通过RTCSEL[1:0]来选择,其中RTCSEL为RCC_CSR寄存器其中的两位。
高速的:1.全速功能的USB模块,其串行接口引擎需要一个频率为48MHz,该时钟源只能从PLL 输出端获得,可以选择1分频或者1.5分频,也就是说,当使用了USB模块,PLL必须使能,而且时钟频率需配置为48MHz或者72MHz.2.系统时钟SYSCLK,是供STM32中绝大部分部件工作的时钟源,系统时钟可选择,PLL 输出,HSI或者HSE输出,全是高速的,系统时钟最大频率为72MHz。
系统时钟并不是直接提供给各模块使用,它需要通过AHB分频器分频给各个模块使用。
AHB的分频因子有9种,1,2,4,8,16,64,128,256,512。
AHB是Advanced High performance Bus,即高级高性能总线,这是一种系统总线,主要用于高性能模块如CPU,DMA,DSP等之间的连接,AHB系统由主模块,从模块和基础结构三部分组成,整个AHB总线上的传输都是由主模块发出,从模块负责回应。
STM32时钟树

STM32时钟树STM32的时钟系统相较于51单⽚机,stm32的时钟系统可以说是⾮常复杂了,我们现在看下⾯的⼀张图:上图说明了时钟的⾛向,是从左⾄右的从时钟源⼀步步的分配给外设时钟。
需要注意的是,上图左侧⼀共有四个时钟源,从上到下依次是:⾼速内部时钟(HSI):以内部RC振荡器产⽣,频率为8Mhz,但相较于外部时钟不稳定。
⾼速内部时钟(HSE):以外部晶振作为时钟源,晶振频率可取范围为4~16Mhz,⼀般采⽤8Mhz的晶振。
低速外部时钟(LSE): 以外部晶振作为时钟源,主要是提供给实时时钟模块,所以⼀般选⽤32.768khz,该频率下定时器⽅便取整。
低速内部时钟(LSI): 从内部RC振荡器产⽣,频率为40khz,也是主要提供给实时时钟模块。
根据上图,以我们最常⽤的⾼速外部时钟为例,沿着路线⼀步步的分析:1. 从最左端的OSC_OUT和OSC_IN开始,这两个引脚分别连接到外部晶振的两端。
2. 我们假设连接的晶振为8Mhz,它遇到了第⼀个分频器PLLXTPRE。
在这个分频器中,可以选择设置⼆分频,或者不分频。
这⾥我们选择不分频。
3. 然后箭头指向了开关PLLSRC,这个开关可以选择HSE或者HSI作为其时钟输出。
这⾥我们选择HSE,紧接着⼜遇到锁相环PLL,也叫倍频器。
我们可以设定2到16的倍频因⼦(PLLMUL),经过PLL的时钟称为PLLCLK。
在这⾥设置倍频因⼦为9,也就是说乘以9,PLLCLK为72Mhz。
4. 然后⼜遇到⼀个开关SW,经过这个开关之后就是STM32的系统时钟(SYSCLK)了。
通过这个开关,可以切换SYSCLK的时钟源,有HSI,PLLCLK,HSE三个选择。
我们选择PLLCLK时钟,所以SYSCLK就为72Mhz了。
5. PLLCLK在输⼊到SW前,还流向了USB预分频器,所以这个PLLCLK也作为USB的时钟。
6. 再继续看SYSCLK,SYSCLK经过AHB预分频器,分频后再输⼊到其他外设。
图文详解stm32时钟树

对于广大初次接触STM32的读者朋友(甚至是初次接触ARM器件的读者朋友)来说,在熟悉了开发环境的使用之后,往往“栽倒”在同一个问题上。
这问题有个关键字叫:时钟树。
众所周知,微控制器(处理器)的运行必须要依赖周期性的时钟脉冲来驱动——往往由一个外部晶体振荡器提供时钟输入为始,最终转换为多个外部设备的周期性运作为末,这种时钟“能量”扩散流动的路径,犹如大树的养分通过主干流向各个分支,因此常称之为“时钟树”。
在一些传统的低端8位单片机诸如51,AVR,PIC等单片机,其也具备自身的一个时钟树系统,但其中的绝大部分是不受用户控制的,亦即在单片机上电后,时钟树就固定在某种不可更改的状态(假设单片机处于正常工作的状态)。
比如51单片机使用典型的12MHz晶振作为时钟源,则外设如IO口、定时器、串口等设备的驱动时钟速率便已经是固定的,用户无法将此时钟速率更改,除非更换晶振。
而STM32微控制器的时钟树则是可配置的,其时钟输入源与最终达到外设处的时钟速率不再有固定的关系,本文将来详细解析STM32微控制器的时钟树。
图1是STM32微控制器的时钟树,表1是图中各个标号所表示的部件。
标号图1标号释义1内部低速振荡器(LSI,40Khz)2外部低速振荡器(LSE,32.768Khz)3外部高速振荡器(HSE,3-25MHz)4内部高速振荡器(HIS,8MHz)5PLL输入选择位6RTC时钟选择位7PLL1分频数寄存器8PLL1倍频寄存器9系统时钟选择位10USB分频寄存器11AHB分频寄存器12APB1分频寄存器13AHB总线14APB1外设总线15APB2分频寄存器16APB2外设总线17ADC预分频寄存器18ADC外设19PLL2分频数寄存器20PLL2倍频寄存器21PLL时钟源选择寄存器22独立看门狗设备23RTC设备图1STM32的时钟树在认识这颗时钟树之前,首先要明确“主干”和最终的“分支”。
假设使用外部8MHz 晶振作为STM32的时钟输入源(这也是最常见的一种做法),则这个8MHz便是“主干”,而“分支”很显然是最终的外部设备比如通用输入输出设备(GPIO)。
stm32 25m晶振时钟树计算公式

为stm32 25m晶体振荡器设计时钟树就像为完美的系统时钟频率创造了一种神奇的食谱。
这就像混合和匹配不同的成分,以达到最迷人的结果。
想象一下用分时器,乘数器和源头来为您的系统时钟创造最终的药剂!首先以25MHz晶体振荡器作为主要成分。
将一些 PLLM 作为密制时钟分割器,添加一个 PLLN 的破折叠乘法因子,并在一些 PLLP 和PLLQ 中分别作为主除法因子和 USB OTG FS, SDIO 和随机数生成时钟分割因子。
在使用魔法公式: SystemClock = (InputFreency 、 PLLM)× PLLN 、 PLLP 、 PLLQ 进行混合和计算时,你会感觉自己是一个巫师,为你的系统时钟频率酝酿出最强大的咒语。
一旦你完成了,呜!你会为钟表树设计配制完美的配方以最迷人的方式让你的stm32复活当我们找出PLLM,PLLN,PLLP,PLLP,和PLLQ因素时,我们需要思考一下我们的系统时钟需要什么,以及我们的STM32微控制器能够处理什么。
我们选择PLLM系数,以确保我们的输入频率适合PLL。
我们选择PLLN系数来获得我们想要的乘法,我们主系统时钟的PLLP 系数,以及USB OTG FS,SDIO和RNG时钟的PLLQ系数。
一旦我们掌握了所有这些因素,我们就可以把它们插进一个公式中,来研究系统时钟频率。
在计算PLLM,PLLN,PLLP,以及PLLQ因子后,通过配置STM32微控制器的RCC(重置和时钟控制)登记器来实施时钟树设计。
这一过程需要精确设定RCC—PLLCFGR登记册中的PLLM、PLLN、PLLLP和PLLQ值,然后启用和配置RCC—CR登记册中的PLL。
通过坚持这一系统化程序,stm32 25m晶体振荡器可以被高效地利用,为微控制器产生必要的系统时钟频率。
这一方法符合现行意识形态框架和战略指令规定的硬件资源利用既定办法和政策。
STM32时钟总结剖析

STM32时钟总结一、时钟基本概念 (2)二、时钟树 (7)三、STM32上电后时钟的过程. (7)3.1 执行SystemInit ()函数 (7)3.2 执行SetSysClock()函数. (8)3.3 执行SetSysClockTo72()函数 (8)3.3.2 判断外部高速时钟源是否稳定 (8)3.3.4 FLASH 配置. (9)3.3.5 系统时钟配置是HCLK,PCLK2为HCLK,PCLK1为HCLK的一半93.3.6 配置PLL 在这里修改倍频值。
RCC_CFGR_PLLMUL9L 93.3.7 失能PLL;判断PLL是否Readay;选择PLL 为系统时钟,一直等到时钟稳定 (9)四、时钟源的选择 (10)4.1 系统默认配置时钟8*9=72M (10)4.2 配置HSI(高速内部时钟)为系统主时钟(永远不变8M)104.3 配置HSE为系统主时钟。
8M(和外部晶振有关)114.4 配置PLLCLK为系统主时钟. (11)4.5 程序 (11)五、配置HCLK,PCLK,1 PCLK2. (11)、时钟基本概念钟。
当时钟源被直接或通过PLL间接作为系统时钟时,它将不能被停止。
稳定阶段的延迟或PLL 稳定),从一个时钟源到另一个时钟源的切换才会发生。
在被选择时钟源没有就绪时,系统时钟的切换不会发生。
直至目标时钟源就绪,才发生切换。
时钟安全系统(CSS)时钟安全系统可以通过软件被激活。
一旦其被激活,时钟监测器将在HSE振荡器启动延迟后被使能,并在HSE时钟关闭后关闭。
如果HSE时钟发生故障,HSE 振荡器被自动关闭,时钟失效事件将被送到高级定时器TIM1的刹车输入端,并产生时钟安全中断CSSI,允许软件完成营救操作。
此CSSI中断连接到Cortex ?M3的NMI中断。
一旦CSS被激活,并且HSE时钟出现故障,CSS中断就产生,并且NMI 也自动产生。
NMI 将被不断执行,直到CSS中断挂起位被清除。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
void RCC_Configuration(void)
{
/* RCC system reset(for debug purpose) */ RCC_DeInit();
/* Enable HSE */
RCC_HSEConfig(RCC_HSE_ON);
/* Wait till HSE is ready */
HSEStartUpStatus = RCC_WaitForHSEStartUp();
if(HSEStartUpStatus == SUCCESS)
{
/* Enable Prefetch Buffer */
FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);
/* Flash 2 wait state */
FLASH_SetLatency(FLASH_Latency_2);
/* HCLK = SYSCLK */
RCC_HCLKConfig(RCC_SYSCLK_Div1);
/* PCLK2 = HCLK */
RCC_PCLK2Config(RCC_HCLK_Div1);
/* PCLK1 = HCLK/2 */
RCC_PCLK1Config(RCC_HCLK_Div2);
/* PLLCLK = 8MHz * 9 = 72 MHz */
RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);
/* Enable PLL */
RCC_PLLCmd(ENABLE);
/* Wait till PLL is ready */
while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET)
{
}
/* Select PLL as system clock source */
RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
/* Wait till PLL is used as system clock source */
while(RCC_GetSYSCLKSource() != 0x08)
{
}
}
}
systemclock共有三个来源,上面代码最后
RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);应该是选择PLLCLK为时钟源void RCC_Configuration(void)
{
/* RCC system reset(for debug purpose) */
RCC_DeInit();
/* Enable HSE */
RCC_HSEConfig(RCC_HSE_ON); ------------SHE外部晶振起震(8M)
/* Wait till HSE is ready */
HSEStartUpStatus = RCC_WaitForHSEStartUp();
if(HSEStartUpStatus == SUCCESS) --------------起震成功配置,flash取指令设置{
/* Enable Prefetch Buffer */
FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);
/* Flash 2 wait state */
FLASH_SetLatency(FLASH_Latency_2);
/* HCLK = SYSCLK */
RCC_HCLKConfig(RCC_SYSCLK_Div1); --------------AHB总线不分频
/* PCLK2 = HCLK */
RCC_PCLK2Config(RCC_HCLK_Div1); --------------APB2总线不分频
/* PCLK1 = HCLK/2 */
RCC_PCLK1Config(RCC_HCLK_Div2); --------------APB1总线二分频
/* PLLCLK = 8MHz * 9 = 72 MHz */
RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9); -----PLLCLK =
8MHz * 9 = 72 MHz
/* Enable PLL */
RCC_PLLCmd(ENABLE); --------------- PLL 使能
/* Wait till PLL is ready */
while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET)
{
}
/* Select PLL as system clock source */
RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK); -------选择PLLCLK为系统时钟systemclk
/* Wait till PLL is used as system clock source */
while(RCC_GetSYSCLKSource() != 0x08)
{
}
}
}
从这里可以看到最后AHB时钟为72M(最大也是72M);APB2时钟72M(最大也是72M);APB1时钟36M(最大也是36M);
所以可以得到APB2预分频系数为1;APB1预分频系数为2。
接着往下走,可以看到定时器的时钟怎么来的了,好兴奋!
从上图可以看到通用定时器tim2~tim7使用的是低速的APB1提供的时钟,因为APB1的预分频系数为2,所以提供给通用定时器的时钟要乘以2,所以通用定时器的时钟源频率为
36M * 2=72M。
高级定时器tim1和tim8使用高速APB2总线提供时钟,因为APB2的预分频为1,所以提供给高级定时器的时钟不变,所以高级定时器的时钟源频率为72M。
同理也可以分析出ADC的时钟。
这个是2.0固件库里面的RCC_Configuration函数调用后系统的时钟情况,要是想使用低速的时钟树,可以修改这个函数中的相关参数,但是在3.0固件库调用的是SystemInit函数,可以更加轻松的配置系统的时钟树了。