嵌入式学习笔记——STM32的时钟树

时钟树

  • 前言
  • 时钟树
    • 时钟分类
    • 时钟树框图
      • LSI与LSE
      • HSI、HSE与PLL
        • 系统时钟的产生
        • 举例
      • AHB、APBx的时钟配置
    • 时钟树相关寄存器介绍
      • 1.时钟控制寄存器(RCC_CR)
      • 2.RCC PLL 配置寄存器 (RCC_PLLCFGR)
      • 3.RCC 时钟配置寄存器 (RCC_CFGR)
      • 4.RCC 时钟中断寄存器 (RCC_CIR)
    • 修改系统时钟配置为内部时钟
      • 代码流程
      • 编程代码
    • 验证
          • **使用NDK的Debug仿真查看STM32的系统频率的操作方式:**
  • 总结

前言

在之前的所有代码编程的过程中,似乎每次都绕不开一个叫做时钟使能的东西,当时我们是在数据手册上直接看其挂接在那条时钟线上的,那么STM32内部的时钟到底是怎么一个构型呢,本文来对此做一个介绍。

时钟树

老规矩,一个新的名词出现,首先需要搞清楚它是个啥,下图中对时钟树给出了定义,STM32的时钟树是由多个时钟源和时钟分频组成的,为STM32芯片提供各种时钟信号。也就是说,在使用STM32的时候,所有的频率和时钟都是通过时钟树产生的。
在这里插入图片描述

时钟分类

在之前的嵌入式学习笔记——STM32硬件基础知识中的晶振电路部分提到过一嘴,STM32的基础时钟源有4个HSI振荡器时钟 、HSE振荡器时钟 、LSI振荡器时钟 、LSE振荡器时钟。这是最底层的时钟来源。
然后是上图中提到的PLL锁相环SYSCLK系统时钟,前面提到过,此系列使用的STM32F407VE的主频是168Mhz,这个主频对应的就是SYSCLK系统时钟,而PLL锁相环就是这个系统时钟的直接来源
在硬件篇介绍的时候,我们知道,外部晶振(也就是外部高速时钟HSE)的频率是25MHZ内部振荡电路(对应内部高速时钟HSI)的频率是16Mhz,显然这两者都不能直接提供168MHZ的主频,那么系统时钟的168Mhz是怎么来的呢?
其实就是将HSI或者HSE接入PLL,通过PLL倍频产生的,具体的产生过程在后面的结构框图和寄存器介绍中描述。
在这里插入图片描述系统时钟的来源:HSI振荡器时钟 HSE振荡器时钟 PLL锁相环
两个次级时钟源:LSI振荡器时钟 LSE振荡器时钟
H/L:高速/低速 SI/SE:内部/外部

时钟树框图

大致了解了时钟树的构成后,就可以来研究它的框图了,这是一张很复杂的图,还是按照之前的思路,对其进行一个拆分,把暂时不用的先排除,此图的下方红框里面的是一个I2S的音频处理专用的时钟,独立于其他的所有时钟,所以暂时不看它,绿框里面的是一个以太网的时钟,也是独立于其他所有模块,所以暂时也先不看,最下面的橙色框里的USB2.0时钟也是,这三个暂时都不需要看。
在这里插入图片描述在这里插入图片描述
简化下半部分后,如下图所示,橙色框内的MCO1和MCO2使用来做测试脚的,使用示波器进行测量,测量频率是否正常的,所以这部分暂时也可以不看,进一步简化。
在这里插入图片描述

LSI与LSE

我们先来看上半部分的内部低速时钟LSI和外部低速时钟LSE;根据框图,可以发现紫色框的内部低速时钟频率为32KHZ,有两个分支,一个是为独立看门狗提供时钟,另一个是为RTC提供时钟。
而绿色的框是外部低速时钟,外接引脚OSC32_IN和OSC32_OUT就是接外部晶振的引脚,进来的频率是32.768KHZ进来后只有一个走向就是为RTC提供时钟。
然后需要注意的是蓝色框的四选一数据选择器,一共有三个输入,前两个是上面的LSI和LSE,还有一个来自下方的HSE,中间经过了一个/2到31的分频器,也就是说看门狗智能由内部低速时钟提供时钟,RTC可以由LSI、LSE、或者是HSE经过分频后来提供时钟,具体使用哪一个需要我们在代码里面配置。
在这里插入图片描述

HSI、HSE与PLL

丢掉了下面,看完了上面,删除了测试接口,接下来就到了本文的重头戏了,百分之90的片上外设的时钟都与这部分有关系。
首先,看图中的系统时钟(红色椭圆框),可以放发现,系统时钟也是通过一个选择器来选择的,输入源有三个,分别是来自橙色框的HSI(内部高速时钟),绿色框的HSE(外部高速时钟)以及蓝色框的PLL锁相环,也就是说,系统时钟可以有三个选择。
这里有一个问题,上面也提到过,系统时钟的直接来演应该选择哪一个输入?
由于内部高速时钟和外部高速时钟都无法提供168Mhz的频率,所以系统时钟的直接来源应该是PLLCLK,也就是说在配置的时候需要将系统时钟选择到锁相环上。
在这里插入图片描述

系统时钟的产生

那么问题来了,PLLCLK又是怎么产生168Mhz的频率的呢,我们放大这部分电路来做个解析,
如下图所示:
首先内部时钟HSI和外部时钟 HSE会来到绿色框的选择器,由我们编程控制具体选择HSI还是HSE;经过选择器选择后,会有一个分频器 “/M”一般这个M就是对应的多少M,
举个栗子:我们选择外部高速时钟作为锁相环的输入,此时的外部时钟频率是8MHZ,那么此处的分配就会采用8分频,将频率分频为1Mhz输入,方便后面的计算。
同样的,如果板子上没有外接晶振,只能选择内部高速时钟作为PLL的输入,此时内部高速时钟的频率是16Mhz,那么此处的分频系数就要配置为16,总之就是将对应输入的频率在此处转化为1Mhz,当然也可以是其他的值,只是1Mhz方便计算而已。
在这里插入图片描述
再经过选择器和分频器后,就正式进入了PLL锁相环了,这里我们结合寄存器的描述来解析:
首先1的位置就是VCO也就是经过分频后的1Mh频率,在其正下方有一个xN,这个xN是倍频的意思,此处的xN是需要我们编程时进行控制的,它的具体位置就是RCC PLL 配置寄存器 (RCC_PLLCFGR)的第6到14位,但是其写入值不是随意的,注意看下方的描述,我们写入的数据必须是192-432之间的值;
在这里插入图片描述
经过倍频后,会来到3的位置,这里有一个/P,根据上面的经验,这个肯定也是一个分频器,那么它的配置有没有要求呢,还是来看看寄存器的相关描述:它是由RCC PLL 配置寄存器 (RCC_PLLCFGR)的第16和17位控制的,注意最低分频也是2分频。
在这里插入图片描述
经过/P后就输出到SYSCLK的选择器了,至于下面的4和5暂时我们没有用上,所以这里不做介绍,想要了解的自己去中文编程手册查看。

举例

好了,到这里已经知道了系统频率是怎么产生的了,举两个例子吧,
第一种,选择外部时钟作为PLL的输入,外部时钟是8MHZ,主频是168MHZ,那么有关PLL的配置流程应该是怎样的?

//此处伪代码主要是走一下计算流程实际流程会比这个多几个步骤
{
	1.绿框选择器选择HSE作为输入;
	2.橙框的分频系数设置为8分频,输出1Mhz的信号到VCO3.配置2号位置的倍频系数,系数要求是(192-433),由于后面还有个最低的2分频,所以此处要配置为336168*2);
	4.配置3号位置分频器为00,二分频,这样就实现了一个168MHZ的系统频率
}

第二种,没有外部接晶振电路,或者说板子的外接晶振电路挂逼了,此时应该如何配置系统的时钟为200MHZ(对于F407来说,200MHZ的频率算超频,如非特殊需求必要,不建议这么操作,会拉高功耗而且造成不稳定)

//此处伪代码主要是走一下计算流程实际流程会比这个多几个步骤
{
	1.绿框选择器选择HSI作为输入;
	2.橙框的分频系数设置为16分频,输出1Mhz的信号到VCO;(内部高速时做的频率为16MHZ)
	3.配置2号位置的倍频系数,系数要求是(192-433),由于后面还有个最低的2分频,所以此处要配置为400200*2);
	4.配置3号位置分频器为00,二分频,这样就实现了一个200MHZ的系统频率
}

AHB、APBx的时钟配置

上面一段主要是介绍了系统时钟的具体生成过程,这个时钟框图还剩下最后一块,就是我们前面配置时经常使用到的AHB、APB1、APB2这些。
在这里插入图片描述
如上图所示,经左侧的选择器选择后,最终的SYSCLK的频率是168MHZ,紧接着往右就分成了两条路线一条向上直接是给到了以太网时钟,这个暂时用不上,可以暂时性忽略;另一路则是来到了AHB,下面有一个分频器,意思是可以配置AHB分频为1,2,4,8,16分频,这个具体的我们也看一眼,对应的寄存器描述:其具体的控制是由RCC 时钟配置寄存器 (RCC_CFGR)的第4到第7位来实现的。
在这里插入图片描述
然后再往后走,又分成了两路,这次先看下面的这一路,可以看见首先来到了2位置的APBx的分频控制,关于它的具体配置也是有对应的寄存器位的,如下图:其中APB1占RCC 时钟配置寄存器 (RCC_CFGR)的10-12位
APB2占RCC 时钟配置寄存器 (RCC_CFGR)的13-15位
然后还有对应的要求,APB1不能超过42MHZ,AOB2不能超过84Mhz。
在这里插入图片描述
通过这个就可以为大多是外设提供所需的时钟了,但是下面还有个框4,里面是一个判断语句,如果APBx是1分频,则×1给到定时器,如果APBx不是1分频,则需要×2后再给到定时器。
最后,还有一个遗留的就是经过AHB后向上去的,那个最后是给内核提供时钟了,还有个是经过8分频后位系统时钟提供时钟,也就是下一篇会介绍的系统滴答(SYS_Tick),这个到下一篇再说。

时钟树相关寄存器介绍

整个时钟相关的寄存器都在中文编程手册的第6.3章,主要包括三大类:1.时钟配置寄存器部分 ;2.外设复位寄存器部分 3.外设使能寄存器部分;
在这里插入图片描述
这里重点是如何配置时钟,所以需要使用到的是第一大类,时钟配置相关的寄存器。

1.时钟控制寄存器(RCC_CR)

在这里插入图片描述

写法:RCC->CR
功能: 1.打开对应的时钟源 HIS HSE PLL;2.用以判断对应的时钟是否准备好。
配置过程中需要使用到的具体位:
位 0 HSION:内部高速时钟使能 (Internal high-speed clock enable)
置1:打开HSI时钟
置0:关闭HSI时钟
写操作,时钟并不是立刻打开的
位 1 HSIRDY:内部高速时钟就绪标志 (Internal high-speed clock ready flag)
为1:表示HSI时钟开启成功
为0:表示HSI时钟还没有开启成功
读操作

位 16 HSEON:HSE 时钟使能 (HSE clock enable)
置1:打开HSE时钟
置0: 关闭HSE时钟
位 17 HSERDY:HSE 时钟就绪标志 (HSE clock ready flag)
为1:表示HSE时钟开启成功
为0:表示HSE时钟还没有开启成功

位 24 PLLON:主 PLL (PLL) 使能 (Main PLL (PLL) enable)
置1:打开锁相环
置0:关闭锁相环
位 25 PLLRDY:主 PLL (PLL) 时钟就绪标志 (Main PLL (PLL) clock ready flag)
为1:表示PLL开启成功
为0:表示PLL还没有开启成功
PLL的锁相环具备写保护,在PLL锁相环运行状态的时候,不能进行相关配置
其他位的相关介绍请参考手册。

2.RCC PLL 配置寄存器 (RCC_PLLCFGR)

这个寄存器在上面介绍PLL的流程的时候已经大致看过了,其作用就是配置PLL的各项参数,产生系统所需的168MHZ的频率。
写法:RCC->PLLCFGR
功能:配置PLL锁相环,注意:配置过程中需要先操作上一个寄存器关闭锁相环

位 5:0 PLLM:主 PLL (PLL) 和音频 PLL (PLLI2S) 输入时钟的分频系数 (Division factor for the main PL(PLL) and audio PLL (PLLI2S) input clock)
可以配置相应的分频
写入值:2~63 可写入的值有限制

位 14:6 PLLN:适用于 VCO 的主 PLL (PLL) 倍频系数 (Main PLL (PLL) multiplication factor for VCO)
可以配置相应的倍频
写入值:192~432 可写入的值有限制

位 17:16 PLLP:适用于主系统时钟的主 PLL (PLL) 分频系数 (Main PLL (PLL) division factor for main system clock)
可以配置相应的分频,对应的分频有自己的参数
00:PLLP = 2
01:PLLP = 4
10:PLLP = 6
11:PLLP = 8

位 22 PLLSRC: 主 PLL(PLL) 和音频 PLL (PLLI2S) 输入时钟源 (Main PLL(PLL) and audio PLL
(PLLI2S) entry clock source)
由软件置 1 和清零,用于选择 PLL 和 PLLI2S 时钟源。此位只有在 PLL 和 PLLI2S 已禁止时
才可写入。
0:选择 HSI 时钟作为 PLL 和 PLLI2S 时钟输入
1:选择 HSE 振荡器时钟作为 PLL 和 PLLI2S 时钟输
此位就是上面框图中的绿色选择框,选择HSI或者是HSE作为PLL的输入。

3.RCC 时钟配置寄存器 (RCC_CFGR)

此寄存器的主要作用就是对AHB、APB1、APB2等进行时钟配置,也就是上面框图讲解的最后一部分的控制内容。
在这里插入图片描述
写法:RCC->CFGR
功能:配置相应时钟总线时钟,选择系统时钟的来源
位 1:0 SW:系统时钟切换 (System clock switch)
00:选择HSI作为系统时钟时钟源
01:选择HSE作为系统时钟时钟源
10:选择PLL作为系统时钟时钟源

位 3:2 SWS:系统时钟切换状态 (System clock switch status)
为00:表示HIS选择成功
为01:表示HSE选择成功
为10:表示PLL选择成功

具体写法:
while(!(PLL->CFGR & (1<<3)));
//等待系统时钟切换成HIS
while ( RLL->CFGR & (3<<2) );

位 7:4 HPRE:AHB 预分频器 (AHB prescaler)
可以修改AHB总线的频率
0xxx:系统时钟不分频
1000:系统时钟 2 分频
1001:系统时钟 4 分频
1010:系统时钟 8 分频
1011:系统时钟 16 分频
1100:系统时钟 64 分频
1101:系统时钟 128 分频
1110:系统时钟 256 分频
1111:系统时钟 512 分频

位 15:10 PPRE1:APBx分频器
0xx:AHB 时钟不分频
100:AHB 时钟 2 分频
101:AHB 时钟 4 分频
110:AHB 时钟 8 分频
111:AHB 时钟 16 分频

4.RCC 时钟中断寄存器 (RCC_CIR)

功能:在上面各个配置过程中,各类时钟准备就绪就会进入中断执行操作,默认不操作,在这里一般不需要执行中断。所以这个寄存器基本上不操作的。

修改系统时钟配置为内部时钟

在搞清楚了框图以及对应的寄存器后,就可以尝试配置一个时钟了,这里实现这样一个需求,使用HSI作为基础时钟源配置系统时钟200Mhz,APB2为50MHZ;APB1为25MHZ。
这类需求一般不常用,但是一旦拿到的板子没有外接晶振或者说自己画的板子外接晶振挂了,不工作,就可以采用类似的操作,将PLL时钟源选择为HSI,进而为整个系统提供时钟源。

代码流程

还是老规矩,先写一个伪代码来理清思路:

ST的默认时钟文件------HSE
HSI系统时钟配置的初始化函数
{
   打开HSI的时钟振荡器
   等待HSI准备就绪

   先切换系统时钟到HSI//由于系统运行过程中不能没有时钟,而配置PLL又需要先将PLL关闭,所以需要执行此操作,现将系统时钟暂时切换到HSI。
   等待系统时钟切换成功

   关闭锁相环
   选择锁相环需要的时钟源
   配置M分频
   配置N倍频
   配置P分频

   打开PLL锁相环
   等待PLL锁相环锁定
   
   系统时钟切换回PLL锁相环
   等待系统时钟准备就绪
}

编程代码

还是一样的需要新建文件然后导入工程,这里就不再一步一步的演示了

//配置代码:
#include "Hsi.h"

/*******************************************
*函数名    :HSI_Init
*函数功能  :初始化HSI函为系统时钟
*函数参数  :无
*函数返回值:无
*函数描述  :
将系统时钟调整为200MHZ
APB2为50MHZ
APB1为25MHZ
*********************************************/
void HSI_Init(void)
{
		RCC->CR |=(1<<0);//打开HSI的适中振荡器
		while(!(RCC->CR & (1<<1)));//等待HSI就位
		RCC->CFGR &= ~(3<<0);//将系统时钟暂时切换至HSI
		while(RCC->CFGR & (3<<2));//等待时钟切换完成
	
		RCC->CR &=~(1<<24);//关闭锁相环
		RCC->PLLCFGR &=~(1<<22);//PLL选择HSI为输入时钟源
	
		RCC->PLLCFGR &=~(0X3F<<0);//清零
		RCC->PLLCFGR |=(16<<0);  //M16分频
	
		RCC->PLLCFGR &=~(0X1FF<<6);//清零
		RCC->PLLCFGR |=(400<<6);  //N倍频 400
	
		RCC->PLLCFGR &=~(3<<16);//P分频 2
	
		RCC->CR |=(1<<24);//打开锁相环
		while(!(RCC->PLLCFGR & (1<<25)));//等待锁相环锁定
		//切换回PLL作为系统时钟
		RCC->CFGR |= (1<<1);//将系统时钟暂时切换回PLL
		while(!(RCC->CFGR & (1<<3)));//等待时钟切换完成
		
		RCC->CFGR &=~(0xf<<4);//清零,将AHB时钟设置为不分频200MHZ
		
		RCC->CFGR &=~(0x7<<10);//清零
		RCC->CFGR |=(0x6<<10);//将APB1的时钟设置为25MHZ8分频
		
		RCC->CFGR &=~(0x7<<13);//清零
		RCC->CFGR |=(0x5<<13);//将APB2的时钟设置为50MHZ//4分频
		
}

//.H:
#ifndef _HSI_H
#define _HSI_H
#include "stm32f4xx.h"

void HSI_Init(void);
#endif

验证

效果:由于APB2的时钟变成了50MHZ所以一种检验方式如下图,修改BRR内对应的频率为50MHZ然后编译下载,串口助手可以正常打印就说明正常。
在这里插入图片描述

另外一种检验方式就是添加库函数,调用对应库函数即可查看。
未修改之前的主频是168Mhz,如下图右下的框图所示。
在这里插入图片描述

修改后的主频是200MHZ,APB1的频率是25MHZ,APB2的频率是50MHZ。
在这里插入图片描述

使用NDK的Debug仿真查看STM32的系统频率的操作方式:

1.需要使用到库函数,要找一个库函数的代码,复制对应的
“stm32f4xx_rcc.h” 和对应的"stm32f4xx_rcc.c"到自己工程目录下并添加进工程;使用库函数的同学可以直接在自己的库里面找,将其添加进工程即可。
2.使用寄存器的小伙伴记得打开stm32f4xx_rcc.h,
添加一个宏定义“ #define assert_param(expr) ((void)0)”,使用库函数的同学直接跳转至第3步。
在这里插入图片描述
3.在main.h包含头文件“stm32f4xx_rcc.h”,然后再main.c声明一个结构体变量

RCC_ClocksTypeDef Get_Rcc_Clock;    //声明一个结构体变量,获取系统时钟状态

4.在单次运行代码的位置,添加:

RCC_GetClocksFreq(&Get_Rcc_Clock);  //仿真的时候就可以在结构体get_rcc_clock中看见各个外设的时钟了

在这里插入图片描述

5.编译通过后,点击Debug按钮,来到如下界面,在右下角底部找到“Call Stack + Locals”,选中;然后点击2位置的全速运行,等待3秒,然后点击叛变的停止运行,4对应的框会出现对应的频率。
在这里插入图片描述
此时频率还是16进制的数,为了方便查看,随便选择一个变量选中,然后右键弹出2位置的16进制显示,把这个复选框取消即可。
为了
在这里插入图片描述
STM32F4获取并查看当前系统时钟频率——http://t.csdn.cn/E9ATa
STM32获取当前系统时钟——http://t.csdn.cn/uPwvO
此法是仿真的频率并不是实际采集的频率,只是理论值,实际最好还是采用上一种串口修改频率不乱码的方案来解决。

总结

本文主要是介绍了STM32的是时钟树,捋了一下时钟的配置流程,文中如有不足还请指出。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/1326.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Java中的二叉树

文章目录前言一、树形结构&#xff08;了解&#xff09;1.1 概念1.2 概念&#xff08;重要&#xff09;1.3 树的表示形式&#xff08;了解&#xff09;1.4 树的应用二、二叉树&#xff08;重点&#xff09;2.1 概念2.2 两种特殊的二叉树2.3 二叉树的性质2.5 二叉树的存储2.5 二…

数据挖掘(2.2)--数据预处理

目录 二、数据描述 1.描述数据中心趋势 1.1平均值和截断均值 1.2加权平均值 1.3中位数&#xff08;Median&#xff09;和众数(Mode) 2.描述数据的分散程度 2.1箱线图 2.2方差和标准差 2.3正态分布 3.数据清洗 3.1数据缺失的处理 3.2数据清洗 二、数据描述 描述数…

【IDEA插件开发】环境搭建

基础信息 GRADLE 7.5.1 IDEA IntelliJ IDEA 2020.1.1 (Ultimate Edition) Build #IU-201.7223.91, built on April 30, 2020 Licensed to https://zhile.io You have a perpetual fallback license for this version Subscription is active until July 8, 2089 Runtime ve…

蓝桥杯嵌入式第一课--创建工程

概述学习本节之前&#xff0c;必须要先安装好 keil5 以及 CubeMX 等软硬件环境&#xff0c;如果你已经安装完成&#xff0c;请告诉自己&#xff1a;考试现在开始&#xff01;从CubeMX开始CubeMX是创建工程模板的软件&#xff0c;也是我们比赛时第一个要进行操作的软件。一、选择…

【十二天学java】day01-Java基础语法

day01 - Java基础语法 1. 人机交互 1.1 什么是cmd&#xff1f; 就是在windows操作系统中&#xff0c;利用命令行的方式去操作计算机。 我们可以利用cmd命令去操作计算机&#xff0c;比如&#xff1a;打开文件&#xff0c;打开文件夹&#xff0c;创建文件夹等。 1.2 如何打…

介绍两款红队常用的信息收集组合工具

介绍两款红队常用的信息收集组合工具1.Ehole本地识别FOFA识别结果输出2.AlliN1.Ehole EHole(棱洞)3.0 红队重点攻击系统指纹探测工具 EHole是一款对资产中重点系统指纹识别的工具&#xff0c;在红队作战中&#xff0c;信息收集是必不可少的环节&#xff0c;如何才能从大量的资…

【洛谷刷题】蓝桥杯专题突破-深度优先搜索-dfs(3)

写在前面&#xff1a; 怎么样才能学好一个算法&#xff1f; 我个人认为&#xff0c;系统性的刷题尤为重要&#xff0c; 所以&#xff0c;为了学好深度优先搜索&#xff0c;为了用好暴搜应对蓝桥杯&#xff0c; 事不宜迟&#xff0c;我们即刻开始刷题&#xff01; 题目&…

Spring Cloud Alibaba全家桶(五)——微服务组件Nacos配置中心

前言 本文小新为大家带来 微服务组件Nacos配置中心 相关知识&#xff0c;具体内容包括Nacos Config快速开始指引&#xff0c;搭建nacos-config服务&#xff0c;Config相关配置&#xff0c;配置的优先级&#xff0c;RefreshScope注解等进行详尽介绍~ 不积跬步&#xff0c;无以至…

关于Linux多线程

文章目录Linux线程的概念什么是线程二级页表线程的优点线程的缺点线程异常线程用途Linux进程VS线程进程和线程进程的多个线程共享进程和线程的关系Linux线程控制POSIX线程库线程创建线程等待线程终止分离线程Linux线程的概念 什么是线程 在一个程序里的一个执行路线就叫做线程…

【Android WMS】从应用图像获取来认识WindowState

为了能够更动感的去学习WMS窗口概念&#xff0c;这里我们从应用的图像画面获取来认识WindowState&#xff0c;作为WMS学习的一个突破口&#xff0c;现在暂时记住下面这句话&#xff0c;WindowState是WMS中的一个对象&#xff0c;保存了APP窗口相关信息。保存了窗口相关信息&…

ACM训练赛赛后补题:Happy Necklace(思维+递推+矩阵快速幂)

题目描述&#xff1a; 分析 这道题很容易就可以定性为动态规划&#xff0c;需要能够推出递推公式&#xff1b;然后观察发现n太大了&#xff0c;最多只能接收O(logn)的复杂度&#xff0c;这样的复杂度&#xff0c;实现的方式就是矩阵快速幂。 首先题目所说的是这一串项链里面…

77.qt qml-QianWindow-V1版本界面讲解

上章介绍: 76.qt qml-QianWindow开源炫酷界面框架简介(支持白色暗黑渐变自定义控件均以适配) 界面如下所示: 代码结构如下所示:

大学四年..就混了毕业证的我,出社会深感无力..辞去工作,从头开始

时间如白驹过隙&#xff0c;一恍就到了2023年&#xff0c;今天最于我来说是一个值得纪念的日子&#xff0c;因为我收获了今年的第一个offer背景18年毕业&#xff0c;二本。大学四年&#xff0c;也就将就混了毕业证和学位证。毕业后&#xff0c;并未想过留在湖南&#xff0c;就回…

西安石油大学C语言期末重点知识点总结

大一学生一周十万字爆肝版C语言总结笔记 是我自己在学习完C语言的一次总结&#xff0c;尽管会有许多的瑕疵和不足&#xff0c;但也是自己对C语言的一次思考和探索&#xff0c;也让我开始有了写作博客的习惯和学习思考总结&#xff0c;争取等我将来变得更强的时候再去给它优化出…

计算机组成原理笔记——计算机性能指标(CPI、IPS、MIPS等)

计算机系统的性能评价有两种指标&#xff0c;分别为非时间指标和时间指标。 非时间指标 机器字长总线宽度主存容量、存储带宽CPU内核数 时间指标 主频、周频、外频、倍频CPI、IPCMIPS、MFLOPSCPU执行时间 非时间指标 &#xff08;1&#xff09;机器字长 机器一次能处理的二…

复制带随机指针的复杂链表

目录一、题目题目链接二、题目分析三、解题思路四、解题步骤4.1 复制结点并链接到对应原节点的后面4.2 处理复制的结点的随机指针random4.3 分离复制的链表结点和原链表结点并重新链接成为链表五、参考代码六、总结一、题目题目链接 ​​​​ ​ 题目链接&#xff1a;https://…

IDEA搭建vue-cli | vue-router | 排错思路、Webpack、Axios、周期、路由、异步、重定向

&#x1f497;wei_shuo的个人主页 &#x1f4ab;wei_shuo的学习社区 &#x1f310;Hello World &#xff01; Vue.js概述 Vue 是一套用于构建用户界面的渐进式JavaScript框架。 与其它大型框架不同的是&#xff0c;Vue 被设计为可以自底向上逐层应用。Vue 的核心库只关注视图层…

C语言数据结构初阶(6)----链表常见OJ题

CSDN的uu们&#xff0c;大家好&#xff01;编程能力的提高不仅需要学习新的知识&#xff0c;还需要大量的练习。所以&#xff0c;C语言数据结构初阶的第六讲邀请uu们一起来看看链表的常见oj题目。移除链表元素原题链接&#xff1a;203. 移除链表元素 - 力扣&#xff08;Leetcod…

ENVI_IDL:批量获取影像文件各个波段的中值并输出为csv文件

01 实验数据诸多.float后缀的影像文件(但以ENVI默认格式存储)02 实验思路迭代循环所有影像文件所在的文件夹&#xff0c; 获取每一个float后缀的影像文件&#xff0c;并对每一个影像文件进行循环&#xff0c;获取循环文件的每一个波段影像的中值&#xff0c;最后将其输出为csv文…

设计模式之单例模式~

设计模式包含很多&#xff0c;但与面试相关的设计模式是单例模式&#xff0c;单例模式的写法有好几种&#xff0c;我们主要学习这三种—饿汉式单例&#xff0c;懒汉式单例、登记式单例,这篇文章我们主要学习饿汉式单例 单例模式&#xff1a; 满足要点&#xff1a; 私有构造 …