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中断挂起位被清除。
STM32F4时钟树外设挂靠总线学习小结
STM32F4时钟树学习小结时钟是单片机的心脏,重要性不言而喻,STM32F4的时钟树是比较复杂的。
时钟树图一时钟树图二1:STMF4xx系统共计有三个主要时钟源(HSI、HSE和PLL)和两个次要时钟源(LSE、LSI)。
2:SYSCLK可以来自HSI、HSE和PLL,多数采用PLL频率最高能达到168MHz。
3:RTC时钟可以来自LSE、LSI和HSE,但只有用LSE时,才能保证系统电源掉电时RTC仍能正常工作。
4:可通过多个预分频器配置AHB 频率、高速APB (APB2) 和低速APB (APB1)。
AHB 域的最大频率为168 MHz。
高速APB2 域的最大允许频率为84 MHz。
低速APB1 域的最大允许频率为42 MHz。
5:STM32F405xx/07xx 和STM32F415xx/17xx 的定时器时钟频率由硬件自动设置。
如果APB 预分频器为1,定时器时钟频率等于APB 域的频率。
否则,等于APB 域的频率的两倍(×2)。
6:除以下时钟外,所有外设时钟均由系统时钟(SYSCLK) 提供:●来自于特定PLL 输出(PLL48CLK) 的USB OTG FS 时钟(48 MHz)、基于模拟技术的随机数发生器(RNG) 时钟(<=48 MHz) 和SDIO 时钟(<= 48 MHz)。
●I2S 时钟●由外部PHY 提供的USB OTG HS (60 MHz) 时钟●由外部PHY 提供的以太网MAC 时钟(TX、RX 和RMII)。
下面介绍挂在不同总线上的设备情况1、挂在AHB1总线的外设有:最高时钟频率:168MHZ1)GPIOA~K2)RCC_AHB1Periph_CRC3)FLITF4)SRAM15)SRAM26)BKPSRAM7)SRAM38)CCMDATARAMEN9)DMA110)DMA211)DMA2D12)ETH_MAC、ETH_MAC_Tx、ETH_MAC_Rx、ETH_MAC_PTP13)OTG_HS、OTG_HS_ULPI2、挂在AHB2总线的外设有:最高时钟频率:168MHZ1)DCMI2)CRYP3)HASH4)RNG5)OTG_FS3、挂在APB1_Peripherals 有:最高时钟频率:42MHZ1)TIM2~142)WWDG3)SPI2~34)USART2~35)UART4~5,7~86)I2C1~37)CAN1~28)PWR9)DAC4、挂在APB2_Peripherals 有:最高时钟频率:84MHZ1)TIM1,8~112)USART1,63)ADC4)ADC1~35)SDIO,1,4,5,66)SYSCFG7)SAI18)LTDC。
STM32F427xx系列芯片系统时钟讲解
STM32F427xx系列芯片系统时钟讲解——写代码的Tobem 为了进行通用定时器的设置,有必要先了解STM32F427xx系列芯片的时钟系统。
为了实现低功耗(对于每个时钟源来说,在未使用时都可单独打开或者关闭,以降低功耗),STM32F427xx设计了功能完善但却有点复杂的时钟系统,见下图:图2 STM32F427xx系统时钟树从图中可以看出,STM32F427xx具有4个时钟源,分别为2个内部时钟源和2个外部时钟源,也可以分为2个高速时钟源和2个低速时钟源,具体为:1、HSE(高速外部时钟):以外部晶振作时钟源,晶振频率可取范围为4~26MHz,实际电路图中我们采用12MHz的晶振。
2、HSI(高速内部时钟):由内部RC振荡器产生,频率为16MHz。
其特点是起振快,在芯片刚上电的时候,就是使用高速内部时钟,但其精度不高,因此,上电之后我们再通过软件配置(SystemInit()函数),转而采用高速外部时钟信号。
3、LSE(低速外部时钟):以外部晶振作时钟源,主要提供给实时时钟模块(RTC),一般采用32.768KHz。
4、LSI(低速内部时钟):由内部RC振荡器产生,频率为32KHz,主要用于驱动独立看门狗,也可选择提供给RTC 用于停机/待机模式下的自动唤醒。
程序在执行主函数main()之前,要先进行堆栈指针SP、程序计数器PC的初始化、设置异常中断向量地址等工作,最后才进入到主函数main()中去执行,这其中包括系统时钟的配置(在startup_stm32f4xx.s启动文件中)。
系统时钟的配置由system_stm32f4xx.c文件中的SystemInit()函数完成,配置结果如下:图3 系统时钟配置情况从时钟树中可以看到,系统时钟SYSCLK是大部分器件的时钟来源,因此SYSCLK的配置就显得十分重要。
SYSCLK可以从三个时钟源中进行选择,分别为HSI、HSE和PLLCLK。
HSI 不稳定,而HSE速率太低(4~26MHz),为了使系统获得较快的运行速率和稳定性,我们选择PLLCLK来作为SYSCLK(见备注1),而PLLCLK又可以选择HSI或者HSE作为时钟源,我们选择HSE作为时钟源(见备注2)根据时钟树的走向,SYSCLK(即PLLCLK)计算过程为:PLL_VCO = (HSE_VALUE / PLL_M) * PLL_NSYSCLK = PLL_VCO / PLL_P而宏定义有#if !defined (HSE_VALUE)#define HSE_VALUE ((uint32_t)12000000) /*!< Value of the External oscillator in Hz */#endif /* HSE_VALUE */#define PLL_M 12#define PLL_Q 7#if defined (STM32F427_437xx) || defined (STM32F429_439xx)#define PLL_N 360#define PLL_P 2故SYSCLK最终为180MHz。
STM32F072从零配置工程-自定义时钟配置详解
STM32F072从零配置⼯程-⾃定义时钟配置详解从⾃⼰的板⼦STM32F407⼊⼿,参考官⽅的SystemInit()函数:核⼼在SetSysClock()这个函数,官⽅默认是采⽤HSE(设定为8MHz)作为PLL锁相环的输⼊输出168MHz的SYSCLK;/*** @brief Setup the microcontroller system* Initialize the Embedded Flash Interface, the PLL and update the* SystemFrequency variable.* @param None* @retval None*/void SystemInit(void){/* Reset the RCC clock configuration to the default reset state ------------*//* Set HSION bit */RCC->CR |= (uint32_t)0x00000001;/* Reset CFGR register */RCC->CFGR = 0x00000000;/* Reset HSEON, CSSON and PLLON bits */RCC->CR &= (uint32_t)0xFEF6FFFF;/* Reset PLLCFGR register */RCC->PLLCFGR = 0x24003010;/* Reset HSEBYP bit */RCC->CR &= (uint32_t)0xFFFBFFFF;/* Disable all interrupts */RCC->CIR = 0x00000000;/* Configure the System clock source, PLL Multiplier and Divider factors,AHB/APBx prescalers and Flash settings ----------------------------------*/SetSysClock();}这⾥⼤致分析⼀下官⽅默认的SetSysClock()配置:由于我个⼈采⽤的是STM32F407型号的芯⽚,因此精简⼀下函数;总体思路的话:使能HSE;等待HSE初始化完毕,进⾏下⼀步设置;设置HCLK、PCLK1、PCLK2的分频系数;配置PLL,使能PLL,等待PLL初始化完毕;选择PLL作为SYSCLK,等待SYSCLK时钟设置完毕;/*** @brief Configures the System clock source, PLL Multiplier and Divider factors,* AHB/APBx prescalers and Flash settings* @Note This function should be called only once the RCC clock configuration* is reset to the default reset state (done in SystemInit() function).* @param None* @retval None*/static void SetSysClock(void){/******************************************************************************//* PLL (clocked by HSE) used as System clock source *//******************************************************************************/__IO uint32_t StartUpCounter = 0, HSEStatus = 0;/* Enable HSE */RCC->CR |= ((uint32_t)RCC_CR_HSEON);/* Wait till HSE is ready and if Time out is reached exit */do{HSEStatus = RCC->CR & RCC_CR_HSERDY;StartUpCounter++;} while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));if ((RCC->CR & RCC_CR_HSERDY) != RESET){else{HSEStatus = (uint32_t)0x00;}if (HSEStatus == (uint32_t)0x01){/* Select regulator voltage output Scale 1 mode */RCC->APB1ENR |= RCC_APB1ENR_PWREN;PWR->CR |= PWR_CR_VOS;/* HCLK = SYSCLK / 1*/RCC->CFGR |= RCC_CFGR_HPRE_DIV1;/* PCLK2 = HCLK / 2*/RCC->CFGR |= RCC_CFGR_PPRE2_DIV2;/* PCLK1 = HCLK / 4*/RCC->CFGR |= RCC_CFGR_PPRE1_DIV4;/* PCLK2 = HCLK / 1*/RCC->CFGR |= RCC_CFGR_PPRE2_DIV1;/* PCLK1 = HCLK / 2*/RCC->CFGR |= RCC_CFGR_PPRE1_DIV2;/* Configure the main PLL */RCC->PLLCFGR = PLL_M | (PLL_N << 6) | (((PLL_P >> 1) -1) << 16) |(RCC_PLLCFGR_PLLSRC_HSE) | (PLL_Q << 24);/* Enable the main PLL */RCC->CR |= RCC_CR_PLLON;/* Wait till the main PLL is ready */while((RCC->CR & RCC_CR_PLLRDY) == 0){}/* Configure Flash prefetch, Instruction cache, Data cache and wait state */FLASH->ACR = FLASH_ACR_PRFTEN | FLASH_ACR_ICEN |FLASH_ACR_DCEN |FLASH_ACR_LATENCY_5WS; /* Configure Flash prefetch, Instruction cache, Data cache and wait state */FLASH->ACR = FLASH_ACR_PRFTEN | FLASH_ACR_ICEN |FLASH_ACR_DCEN |FLASH_ACR_LATENCY_2WS; /* Select the main PLL as system clock source */RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));RCC->CFGR |= RCC_CFGR_SW_PLL;/* Wait till the main PLL is used as system clock source */while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS ) != RCC_CFGR_SWS_PLL);{}}else{ /* If HSE fails to start-up, the application will have wrong clockconfiguration. User can add here some code to deal with this error */}}在官⽅的基础上,直接设定HSE作为SYSCLK时钟:初始化HSE;等待HSE初始化成功后再继续;设置调压器电压输出级别为1以便使器件在最⼤频率⼯作;设置HCLK、PCLK1、PCLK2分频系数;设置HSE作为系统时钟;void HSE_SetSysClock(void){__IO uint32_t HSEStartUpStatus = 0; /* 开启HSE时钟 */ /* 此函数从stm32f0xx_rcc.c获取,⽤于配置外部时钟HSE: * 有三个配置:RCC_HSE_OFF关闭外部HSE时钟 * RCC_HSE_ON开始外部HSE晶振 * RCC_HSE_Bypass开始HSE旁路设置 */ RCC_HSEConfig(RCC_HSE_ON); /* 若时钟配置成功 */if(HSEStartUpStatus == SUCCESS){RCC->APB1ENR |= RCC_APB1ENR_PWREN;PWR->CR |= PWR_CR_VOS;RCC_HCLKConfig(RCC_SYSCLK_Div1);RCC_PCLK2Config(RCC_HCLK_Div1);RCC_PCLK1Config(RCC_HCLK_Div1); /* 将SYSCLK系统时钟设置为HSE */RCC_SYSCLKConfig(RCC_SYSCLKSource_HSE); /* 等待SYSCLK系统时钟设置成功 */while(RCC_GetSYSCLKSource() != 0x04){}}else{while(1);}}使⽤HSI经过PLL配置系统时钟:使能HSI时钟;获取HSI状态并等待HSI稳定;设置调节器电压输出级别配置为1;设置HCLK、PCLK1/2分频系数;设置PLL时钟分频系数;使能PLL并等待PLL稳定后配置PLL状态;设置PLL作为SYSCLK时钟并等待设置完成;void HSI_SetSysClock(uint32_t m, uint32_t n, uint32_t p, uint32_t q) {__IO uint32_t HSIStartUpStatus = 0;/* 去初始化RCC */RCC_DeInit();/* 使能HSI时钟 */RCC_HSICmd(ENABLE);/* 从RCC的CR寄存器中获取HSI配置状态 */HSIStartUpStatus = RCC->CR & RCC_CR_HSIRDY;/* 若HSI配置成功 */if(HSIStartUpStatus == RCC_CR_HSIRDY){/* 配置调节器电压输出级别为1 */RCC->APB1ENR |= RCC_APB1ENR_PWREN;PWR->CR |= PWR_CR_VOS;/* 配置SYSCLK到HCLK的分频系数为1 */RCC_HCLKConfig(RCC_SYSCLK_Div1);/* 配置HCLK到PCLK1/2的分频系数为2/4 */RCC_PCLK2Config(RCC_HCLK_Div2);RCC_PCLK1Config(RCC_HCLK_Div4);/* 配置PLL参数,选⽤HSI作为PLL参数,同时使能PLL */RCC_PLLConfig(RCC_PLLSource_HSI, m, n, p, q);RCC_PLLCmd(ENABLE);/* 等待PLL设置完成 */while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET); FLASH->ACR = FLASH_ACR_PRFTEN| FLASH_ACR_ICEN| FLASH_ACR_DCEN| FLASH_ACR_LATENCY_5WS;RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);while(RCC_GetSYSCLKSource() != 0x08);}else{while(1);}}HAL时钟配置分析:与STM32标准外设库不同,HAL库来实现时钟配置需要重新适应配置⽅式,但是本质的寄存器调动是类似不变的,且配置的过程也和STM32标准外设库相似;参考使⽤STMCube⽣成的代码,时钟树如图所⽰:在STM32Cube中设置:HSE设置为Crystal/Ceramic Resonator,Input Frequency设置为16MHz;在⼯程中要配置的参数:第⼀个HSE_VALUE参数位于stm32f0xx_hal_conf.h中,此参数与在STMCube时钟树上定义的⼀致,需要⼿动设置为实际的参数值;第⼆个HSE_VALUE参数位于system_stm32f0xx.c中,此参数默认为8MHz,可以通过⽤户程序来提供和调整;第三个SystemCoreClock参数位于system_stm32f0xx.c中,其默认值也是8MHz,可以根据以下三种⽅式来更新: 调⽤CMSIS函数SystemCoreClockUpdate()、 调⽤HAL API函数HAL_RCC_GetHCLKFreq()、 调⽤HAL_RCC_ClockConfig();/*** @brief Adjust the value of External High Speed oscillator (HSE) used in your application.* This value is used by the RCC HAL module to compute the system frequency* (when HSE is used as system clock source, directly or through the PLL).*/#if !defined (HSE_VALUE)#define HSE_VALUE ((uint32_t)16000000) /*!< Value of the External oscillator in Hz */#endif /* HSE_VALUE */#if !defined (HSE_VALUE)#define HSE_VALUE ((uint32_t)8000000)/*!< Default value of the External oscillator in Hz.This value can be provided and adapted by the user application. */#endif /* HSE_VALUE *//** @addtogroup STM32F0xx_System_Private_Variables* @{*//* This variable is updated in three ways:1) by calling CMSIS function SystemCoreClockUpdate()2) by calling HAL API function HAL_RCC_GetHCLKFreq()3) each time HAL_RCC_ClockConfig() is called to configure the system clock frequencyNote: If you use this function to configure the system clock there is no need to call the 2 first functions listed above, since SystemCoreClock variable is updated automatically.uint32_t SystemCoreClock = 8000000;实际的时钟配置函数如下图:使⽤了三个参数来配置:RCC_OscInitStruct⽤来配置外部时钟参数,这⾥设置晶振类型为HSE、设置HSE的状态为开启状态、不使⽤PLL;RCC_ClkInitStruct⽤来配置系统时钟内的参数(如Sys CLK、HCLK、PCLK1),这⾥设置要配置的时钟类型为HCLK、SYSCLK、PCLK1,选择HSE时钟作为SYSCLK的时钟源,并设置系统时钟SYSCLK分频系数为0、HCLK的分频系数为4;PeriphClkInit⽤来配置外设时钟的时钟源,这⾥设置USART1/2的时钟源为PCLK1;/*** @brief System Clock Configuration* @retval None*/void SystemClock_Config(void){RCC_OscInitTypeDef RCC_OscInitStruct = {0};RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};/** Initializes the CPU, AHB and APB busses clocks*/RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;RCC_OscInitStruct.HSEState = RCC_HSE_ON;RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK){Error_Handler();}/** Initializes the CPU, AHB and APB busses clocks*/RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK|RCC_CLOCKTYPE_PCLK1;RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSE;RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK){Error_Handler();}PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USART1|RCC_PERIPHCLK_USART2;art1ClockSelection = RCC_USART1CLKSOURCE_PCLK1;art2ClockSelection = RCC_USART2CLKSOURCE_PCLK1;if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK){Error_Handler();}HAL_SYSTICK_Config(SystemCoreClock / 1000);HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);}这⾥加⼊了对SysTick的时钟配置,参考HAL库本⾝的设置:HAL_SYSTICK_Config()⽤来配置使能和配置SysTick寄存器;HAL_SYSTICK_CLKSourceConfig()选择AHB时钟(或AHB时钟除以8)作为SysTick时钟源;HAL_NVIC_SetPriority()配置SysTick_IRQn的中断优先级为0,默认为最⾼;。
STM32F103ZET6时钟
STM32F103ZET6时钟1、STM32F103ZET6时钟说明 STM32F103ZET6的时钟树图如下所⽰: STM32F103ZET6有很多个时钟源,分别有: HSE:⾼速外部时钟信号。
HSI:⾼速内部部时钟信号。
LSI:低速内部时钟信号。
LSE:低速外部时钟信号。
HSI和LSI是芯⽚内置的时钟源,它们的频率⼤⼩是固定的,HSI是8MHZ,LSI是⼤约40KHZ。
时钟树中的序号1是⾼速外部时钟信号HSE: HSE是由有源晶振或⽆源晶振通过OSC_OUT和OSC_IN脚提供的,从图⽚中可以看到,HSE频率从4MHZ到16MHZ不等。
当使⽤有源晶振时,时钟从OSC_IN引脚进⼊,OSC_OUT引脚悬空;当使⽤⽆源晶振时,时钟从OSC_IN和OSC_OUT进⼊,并且要配谐振电容。
HSE最常使⽤的就是8MHZ的⽆源晶振。
时钟树中的序号D是外部低速时钟LSE: LSE是由有源晶振或⽆源晶振通过OSC32_OUT和OSC32_IN脚提供的。
LSE⼀般使⽤的是32.768KHZ的⽆源晶振。
时钟树中的序号2是选择PLL(倍频后的时钟)的时钟源: 从图中可以看出,PLL时钟的来源可以是HSE或HSI/2,通过PLLSRC(CFGR寄存器的bit16)来选择使⽤哪⼀个时钟源。
HSI是8MHZ的内部⾼速时钟信号,HSI会根据温度和环境的情况频率会有漂移,⼀般不作为PLL的时钟来源。
⼀般使⽤HSE作为PLL的时钟源。
时钟树中的序号3是设置PLL的倍频因⼦: 可以对PLL的时钟来源进⾏倍频,然后得到PLLCLK时钟源。
倍频因⼦可以通过时钟配置寄存器CFGR的bit21~bit18:PLLMUL[3:0]来配置,分别可配置成2、3、4、5、6、7、8、9、10、11、12、13、14、15、16倍频。
举个例⼦来说,如果选择HSE作为PLL的时钟源,⽽且HSE=8MHZ,且将PLL的倍频因⼦设置为9倍频,那么PLLCLK=9*8MHZ = 72MZH。
stm32几种时钟控制介绍,含原理图
stm32几种时钟控制介绍,含原理图本文提到的有以下内容:• 时钟系统与总线矩阵• SysTick系统定时器• RTC实时时钟• 看门狗定时器• 通用定时器一、时钟系统与总线矩阵stm32F4的时钟树如下图所示:在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。
我们在学习51单片机的时候,其内部是没有晶振的,而stm32是有的。
stm32可以通过RCC(时钟控制寄存器)对时钟进行参数配置以及使能。
我们还可以通过修改system_stm32f4xx.c文件,来配置上述时钟树上的一些分频、倍频参数,得到理想的频率。
在单片机系统中,CPU和总线以及外设的时钟设置是非常重要的,因为没有时钟就没有时序,组合电路需要好好理解清楚。
我们先来看一下总线矩阵。
片上总线标准种类繁多,而由ARM公司推出的AMBA片上总线受到了广大IP开发商和SoC系统集成者的青睐,已成为一种流行的工业标准片上结构。
AMBA规范主要包括了AHB(Advanced High performance Bus)系统总线和APB(Advanced Peripheral Bus)外围总线。
二者分别适用于高速与相对低速设备的连接。
一般性的时钟设置需要先考虑系统时钟的来源,是内部RC还是外部晶振还是外部的振荡器,是否需要PLL。
然后考虑内部总线和外部总线,最后考虑外设的时钟信号。
遵从先倍频作为CPU时钟,然后在由内向外分频,下级迁就上级的原则。
专题三stm32时钟树及相关库函数
#ifndef STM32F10X_CL
RCC->CFGR &= (uint32_t)0xF8FF0000;
#else
RCC->CFGR &= (uint32_t)0xF0FF0000;
#endif /* STM32F10X_CL */
APB2ENR|=1<<2;//或运算,1有效。
第二种方法就是调用库函数。
四、介绍两种库函数
4.1外设时钟使能函数
与rcc有关寄存器设置的库函数都在stm32f10x_rcc.c以及stm32f10x_rcc.h文档中。上面说要使能GPIO时钟,因为GPIO是APB2的外设,因此就是使能APB2相应外设时钟。库函数是:
三
从前面的图1可以看到,要设置STM32芯片的时钟,有以下几个方面要考虑:
1.芯片的时钟源选择HSE,HIS还是其他?
2.SYSCLK系统时钟应该选择哪个?
3.各总线的分频系数?
4.PLL锁相环的倍频系数?
5.各个外设对应的时钟是开启呢,还是禁止?
上面5个问题,STM32统一用RCC来解决。我们首先来看下与RCC相关的寄存器有哪些。
输入参数2:NewState,外设时钟的新状态,可以是DISABLE,ENABLE两种。
返回值:无
调用示范:RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);//使能GPIOB时钟
函数的具体定义引用如下:
void RCC_APB2PeriphClockCmd(uint32_t RCC_APB2Periph, FunctionalState NewState)
STM32时钟配置方法详解
STM32时钟配置方法详解时钟树是STM32微控制器中一系列时钟源和时钟分频器的组成部分。
时钟树包括系统时钟、外设时钟和内核时钟。
系统时钟用于驱动整个微控制器系统的核心,外设时钟用于驱动各种外设,内核时钟用于驱动CPU的运算。
在进行时钟配置之前,首先需要了解系统所需的时钟频率。
在STM32中,系统时钟可以通过多种方式进行配置,例如使用外部晶体、外部时钟、内部RC振荡器或者PLL(锁相环)等方式。
外部晶体是一种常用的时钟源,可以提供高精度的时钟频率。
在使用外部晶体时,首先需要设置PLL的时钟源为外部晶体,并设置PLL输入除频器的分频系数。
然后,再根据系统所需的时钟频率,设置PLL的倍频系数,以得到最终的系统时钟频率。
外部时钟是从外部提供的时钟信号,一般用于测试和调试。
使用外部时钟时,需要设置PLL的时钟源为外部时钟,并设置PLL的倍频系数,以得到所需的系统时钟频率。
内部RC振荡器是一种低成本的时钟源,但是其频率不如外部晶体稳定和精确。
在使用内部RC振荡器时,需要设置PLL的时钟源为内部RC振荡器,并设置PLL的倍频系数,以得到所需的系统时钟频率。
PLL是一种用于产生稳定高频时钟的电路,可以从一个低频时钟源产生一个高频时钟源。
使用PLL时,需要设置其输入时钟源和倍频系数。
系统时钟的分频系数可以通过RCC_CFGR寄存器进行设置。
RCC_CFGR寄存器的各个位域用于配置系统时钟的分频系数,包括分频因子、APB1的分频系数、APB2的分频系数等。
外设时钟是用于驱动外设的时钟,可以由系统时钟分频得到。
外设时钟的分频系数可以通过RCC_CFGR寄存器及各个外设的控制寄存器进行设置。
内核时钟是用于驱动CPU的运算的时钟。
在STM32微控制器中,CPU 时钟可以由系统时钟分频得到,分频系数可以通过RCC_CFGR寄存器和FLASH_ACR寄存器进行设置。
除了上述方法之外,STM32还可以使用时钟配置工具进行时钟配置。
- 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函数,可以更加轻松的配置系统的时钟树了。