HAL库STM32常用外设教程(四)—— 定时器 基本定时

news2024/11/15 19:49:03

HAL库STM32常用外设教程(四)—— 定时器 基本定时


文章目录

  • HAL库STM32常用外设教程(四)—— 定时器 基本定时
  • 前言
  • 一、定时器特性概述
  • 二、基础定时器的结构和功能
    • 1、基本特征
    • 2、基础定时器相关寄存器
    • 3、基础定时器工作流程
    • 4、基础定时器时序图
  • 三、基础定时器HAL驱动程序
    • 1、基础定时器两种定时模式
    • 2、基础定时器主要函数
      • (1)定时器通用HAL库驱动函数
      • (2)启动和停止定时器的三种方式
    • 3、定时器其他通用操作函数
    • 4、定时器有关的中断处理
  • 四、 应用实例
    • 1、CuebMx配置
    • 2、程序功能实现
  • 五、总结


前言

1、STM32F407ZGT6
2、STM32CubeMx软件
3、keil5
内容简述:
通篇文章将涉及以下内容,如有错误,欢迎指出
1、基础定时器特性
2、基础定时器的结构和功能
3、基础定时器HAL库驱动程序
(1)CubeMx配置
(2)TIM驱动程序


一、定时器特性概述

  STM32F407有2个高级控制定时器(TIM1、TIM8)、8个通用定时器和2个基本定时器。基本定时器功能比较简单,只能用于定时,通用定时器和高级定时器还具有输入捕获、输出比较、PWM输出等功能。
              表1-1 STM32F407所有定时器的特性

定时器类型定时器计数器长度计数类型DMA请求捕获/比较通道数所在总线
基本定时器TIM6、TIM7 16位 递增 0 APB1
通用定时器 TIM2、TIM5 32位 递增、递减、递减/递增 4 APB1
通用定时器TIM3、TIM416位 递增、递减、递减/递增4 APB1
通用定时器TIM9 16位递增 2 APB2
通用定时器 TIM1216位 递增 2 APB1
通用定时器 TIM10、TIM11 16位 递增 1 APB2
通用定时器 TIM13、TIM14 16位 递增 1 APB1
高级定时器 TIM1、TIM8 16位 递增、递减、递减/递增 4 APB2

STM32F407还有一个独立看门狗(IWDG)和1个窗口看门狗(WWDG),看门狗实际上也是一个定时器。

二、基础定时器的结构和功能

1、基本特征

TIM6和TIM7两个基础定时器,都在APB1总线上,它们的功能相同,有以下基本特征。
(1)只能使用内部时钟信号CK_INT,这个时钟信号频率为APB1总线频率的2倍,所以这两个定时器输入时钟频率最高为84Mhz。
(2)只有16位自动重装载寄存器(auto-reload register),用于设计计数周期。
(3)有16位可编程预分频器,设置范围为0-65535,分频系数范围为1-65536.
(4)可以输出触发信号(TRGO),用于触发DAC的同步电路。
(5)只有一种事件引起中断或DMA请求,即计数器上溢时产生的更新中断(Updata Event,UEV)。

2、基础定时器相关寄存器

  基础定时器有3个十六位寄存器,计数器寄存器(TIMx_CNT)、预分频器寄存器(TIMx_PSC)、自动重载寄存器(TIMx_ARR) ,这3个寄存器的值都可以读写,组成一个时基单元。基本定时器的这三个寄存器都是 16 位有效数字,即可设置值范围是 0~65535。其中,预分频寄存器和自动重装载寄存器有影子寄存器用于底层工作。
  (1)预分频寄存器(TIMx_PSC),它存储的一个值用于对输入时钟信号CK_PSC进行分频,得到输出时钟信号CK_CNT。实际分频系数是预分频寄存器的值加1。
  (2)计数寄存器(TIMx_CNT),计数器使用时钟信号CK_CNT进行计数,当计数器的值等于自动重装载寄存器的值时产生计数溢出(counter overflow),同时可以产生更新事件(UEV)中断或DMA请求。
  (3)自动重载寄存器(TIMx_ARR),存储的值用于与计数器的值进行比较。

在这里插入图片描述
图2-1 基础定时器功能结构图

3、基础定时器工作流程

  基础定时器只有定时功能,使用基础定时器进行定时的工作流程如下(可对照图2-1进行分析):
  (1)控制器除了控制定时器复位、使能、计数等功能之外,还可以用于触发 DAC 转换。
内部时钟信号CK_INT经过控制器后成为CK_PSC进入预分频器,CK_INT和CK_PSC在频率上相等,假设CK_INT频率为50MHz。
  (2)预分频器对CK_PSC时钟信号进行分频,输出 CK_CNT是分频后的时钟,它是计数器实际的计数时钟,通过设置预分频器寄存器(TIMx_PSC)的值可以得到不同频率 CK_CNT,假设预分频寄存器设置的值为49999,则实际分频系数为50000,那么分频器的输出时钟信号CK_CNT的频率就是

      50MHz /(49999 + 1) = 50 000 000 / 50 000 = 1000Hz
      定时器时钟频率  /(预分频寄存器的值+1)= 计数器频率

  另外:预分频器寄存器(TIMx_PSC)可以在运行过程中修改它的数值,新的预分频数值将在下一个更新事件时起作用。因为更新事件发生时,会把 TIMx_PSC 寄存器值更新到其影子寄存器中,这才会起作用。
什么是影子寄存器
  ①从框图上看,可以看到图2-1中的预分频器PSC后面有一个影子,自动重载寄存器也有个影子,这就表示这些寄存器有影子寄存器。 影子寄存器是一个实际起作用的寄存器, 不可直接访问。举个例子:我们可以把预分频系数写入预分频器寄存器(TIMx_PSC),但是预分频器寄存器只是起到缓存数据的作用,只有等到更新事件发生时,预分频器寄存器的值才会被自动写入其影子寄存器中,这时才真正起作用。
  ②自动重载寄存器及其影子寄存器的作用和上述同理。不同点在于自动重载寄存器是否具有缓冲作用还受到 ARPE 位的控制,当该位置 0 时, ARR 寄存器不进行缓冲,我们写入新的 ARR值时,该值会马上被写入 ARR 影子寄存器中,从而直接生效;当该位置 1 时, ARR 寄存器进行缓冲,我们写入新的 ARR 值时,该值不会马上被写入 ARR 影子寄存器中,而是要等到更新事件发生才会被写入 ARR 影子寄存器,这时才生效。预分频器寄存器则没有这样相关的控制位,这就是它们不同点。值得注意的是,ARPE位对应下图2-2中CubeMx里面的auto-reload preload相对应,当ARPE位被设置为1时,auto-reload preload功能使能;当ARPE位被置零时,该功能禁用。
在这里插入图片描述                        图2-2 自动重装载值

  (3)计数器对时钟信号CK_CNT从0开始计数,自动重装载寄存器存储一个值,如999。当计数器的值达到999时(此时计时时间为1000ms)就产生UEV事件,然后计数器归零又重新开始计数。
  (4)开启定时器全局中断和UEV事件中断后,在发生计数溢出时产生UEV事件中断,利用中断进行定时处理。
  (5)定时器的控制器产生一些控制信号,例如,控制定时器的复位、使能等。

4、基础定时器时序图

  图2-3 是基础定时工作的时序图,其在TIMx_PSC红写入的预分频系数是2,所以后面基础器的时钟CK_CNT的频率是输入时钟CK_PSC的1/2,计数周期如果设置成FC,每来一个CK_CNT的脉冲,计数值加1,当计数值达到FC时,产生计数器上溢信号和UEV时间,如果开启了定时器UEV事件中断,在发生UEV事件时就会置位相应的中断挂起标志位。
再次强调,基础定时器TIM6和TIM7各有一个中断号,且只有一个中断事件源,就是定时器计数溢出的UEV事件。

在这里插入图片描述
                       图2-3 基础定时器工作时序图

三、基础定时器HAL驱动程序

1、基础定时器两种定时模式

  基础定时器只有定时这一个功能,根据控制寄存器TIMx_CR1中的OPM(One-pulse mode)位设置值不同,基础定时器有两种模式:连续定时模式和单次定时模式
  (1)当 OPM位是0时,定时器是连续定时模式,也就是计数器在发生UEV事件时不停止计数。所以在连续定时模式下,可以产生连续的UEV事件,也就是产生连续、周期性的定时中断,这就是定时器默认的工作模式
  (2)当OPM位是1时,定时器是单次定时模式,也就是计数器在发生下一次UEV事件时会停止计数。所以在单词定时模式下,如果启用了UEV时间中断,在产生一次定时中断后,定时器就停止计数了。
  图3-1 CubeMX中的One Pulse Mode(单次触发模式)对应于定时器控制寄存器(TIMx_CR1)中的OPM位。
在这里插入图片描述                           图3-1 单次触发模式

2、基础定时器主要函数

(1)定时器通用HAL库驱动函数

  表3-1 是基础定时器的一些主要的HAL驱动函数,所有定时器具有定时功能,所以这些函数对于通用定时器、高级定时器也是适用的。
                 表3-1 基础定时器的一些主要的HAL库驱动函数

分组函数名功能描述
初始化HAL_TIM_Base_Init()定时器初始化,设置各种参数和连续定时模式
初始化HAL_TIM_OnePulse_Init()将定时器配置为单次定时模式,需要先执行HAL_TIM_Base_Init()
初始化HAL_TIM_Base_MspInit()MSP弱函数,在HAL_TIM_Base_Init() 里面被调用,重新实现的这个函数一般用于时钟器时钟使能和中断设置
启动HAL_TIM_Base_Start()以轮训方式启动定时器,不会产生中断
停止HAL_TIM_Base_Stop()停止轮询工作方式的定时器
启动HAL_TIM_Base_Start_IT()以中断工作方式启动定时器,发生UEV事件时产生中断
停止HAL_TIM_Base_Stop_IT()停止中断工作方式的定时器
启动HAL_TIM_Base_Start_DMA()以DMA工作方式启动定时器
停止HAL_TIM_Base_Stop_DMA()停止DMA工作方式的定时器
获取状态HAL_TIM_Base_GetState()获取基础定时器的当前状态

(2)启动和停止定时器的三种方式

  • 轮询方式。以函数HAL_TIM_Base_Start()启动定时器后,定时器会开始计数,计数溢出会产生UEV事件标志,但是不会触发中断。用户程序需要不断的查询计数值或者UEV事件标志来判断是否发生了计数溢出。
  • 中断方式。以函数HAL_TIM_Base_Start_IT()启动定时器后,定时器会开始计数,计数溢出时会产生UEV事件,并触发中断。用户在中断服务例程(Interruput Service Routine,ISR,在stm32f4xx_it.c里面)里进行处理即可,这是定时器最常用的处理方式。
  • DMA方式。以函数HAL_TIM_Base_Start_DMA()启动定时器后,定时器会进行计数,计数溢出时会产生UEV事件,并产生DMA请求。DMA一般用于需要进行高速数据传输的场合,定时器一般用不着DMA功能。

3、定时器其他通用操作函数

文件stm32f4xx_hal_tim.h还定义了定时器操作的一些通用函数,这些函数都是宏定义,直接操作寄存器,所以主要用于在定时器运行时直接读取或者修改某些寄存器的值,如修改定时周期,重新设置预分频系数等,如表3-2所示。表中寄存器名称用了前缀“TIMx_”,其中“x”可以用具体的定时器编号替换,例如,TIMx_CR1表TIM6_CR1、TIM7_CR1或TIM9_CR1等。

函数名功能描述
HAL_TIM_ENABLE()启动某个定时器,就是将定时器控制寄存器TIMx_CR1的CEN位 置1
HAL_TIM_DISABLE()禁用某个定时器
HAL_TIM_GET_COUNTER()在运行时读取定时器的当前计数值,就是读取TIMx_CNT寄存器的值
HAL_TIM_SET_COUNTER()在运行时设置定时器的计数值,就是设置TIMx_CNT寄存器的值
HAL_TIM_GET_AUTORELOAD()在运行时读取自重载寄存器TIMx_ARR的值
HAL_TIM_SET_AUTORELOAD()在运行时设置自重载寄存器TIMx_ARR的值,并改变定时的周期
HAL_TIM_SET_PRESCALER()在运行时设置预分频系数,就是设置预分频寄存器TIMx_PSC的值

                    表3-2 定时器操作部分通用函数

注: HAL_TIM_GET_COUNTER()其返回值就是寄存器TIMx_CNT的值,有的定时器是32位的,有的定时器是16位的,实际使用时用uint32_t类型的变量来存储函数返回值即可。

4、定时器有关的中断处理

函数名功能描述
HAL_TIM_ENABLE_IT()启用某个定时器的中断,就是将中断使能寄存器TIMx_DIER中相应事件位置1
HAL_TIM_DISABLE_IT()禁用某个定时器的中断,就是将中断使能寄存器TIMx_DIER中相应事件位置0
HAL_TIM_GET_FLAG()判断某个中断事件源的中断挂起标志位是否被置位,就是读取状态寄存器TIMx_SR中相应的中断标志位是否置1,返回值为TURE或FALSE
HAL_TIM_CLEAR_FLAG()清除某个中断事件源的中断挂起标志位,就是将状态寄存器TIMx_SR中相应的中断事件位清零
HAL_TIM_CLEAR_IT()与HAL_TIM_CLEAR_FLAG()的代码和功能完全相同
HAL_TIM_GET_IT_SOURCE()查询是否允许某个中断事件源产生中断,就是检查中断使能寄存器TIMx_DIER中相应位置位是否置1,返回值为SET或RESET
HAL_TIM_IRQHandler()定时器中断的ISR里面调用的定时器中断通用处理函数
HAL_TIM_PeriodElapsedCallback()弱函数,UEV事件中断的回调函数。当定时器的计数器达到自动重装载值并重新开始计数时,会触发一个定时周期结束的事件。在HAL库中,可以通过编写HAL_TIM_PeriodElapsedCallback()函数来处理这个事件。

                    表3-3 定时器中断处理相关函数

每个定时器都只有一个中断号,也就是只有一个ISR。基础定时器只有一个中断事件源,即UEV事件,但是通用定时器和高级定时器有多个中断事件源。在定时器的HAL库驱动中,每一个中断事件对应一个回调函数,HAL驱动程序会自动判断中断事件源,清楚中断事件挂起标志,然后调用相应的回调函数。

四、 应用实例

  • TIM6设置为连续定时模式,定时周期为500ms,以中断方式启动TIM6,在UEV事件中断回调函数里面使LED1输出翻转。
  • TIM7设置为单次定时模式,定时周期为2000ms,按下KEY1(PE3引脚)键后使LED2点亮,并以中断方式启动TIM7,在UEV事件中断回调函数里使LED2输出翻转。
  • 按键需要进行消抖,此处用定时器2定时10ms去完成消抖工作。

1、CuebMx配置

在这里插入图片描述                  图4-1 定时器TIM6的模式和参数配置

(1)定时器TIM6的模式和参数设置结果如图4-1所示,在模式设置部分,勾选Activated复选框,已启动TIM6。启用后,会出现One Pulse Mode复选框,这是用于设置单脉冲模式的,对于基础定时器就是单次定时模式。TIM6工作于连续定时模式,不勾选此项。参数里面设置如下几个参数。

  • Prescalar,预分频器值,设置范围为0 ~ 65535,对应的分频系数为1 ~ 65536。这里设置为4200-1,所以实际分频系数是4200。
  • Counter Mode,计数模式,基础定时器只有递增模式(Up)。
  • Counter Period,计数周期,也就是自重载寄存器(AutoReload Register,ARR)的值,这里设置为10000-1,那么产生UEV事件时,共计时10000个时钟周期。
  • auto-reload preload,是否启用自动重装寄存器TIM6_ARR的预装载功能,实际上就是设置控制寄存器TIM6_CR1的ARPE位(上文有解释)。如果不是动态修改寄存器TIM6_ARR的值,这个设置对寄存器工作没什么影响。
  • Trigger Event Selection,主模式下触发输出信号(TRGO)信号源选择,就是设置寄存器TIM6_CR2的MMS[2:0]位。有3个选项:Reset,使用定时器的复位信号作为TRGO输出;Enable,使用计数器的是能信号作为TRGO输出;Updata Event,使用定时器的UEV事件作为TRGO输出。

(2)定时器7采用单次定时模式,定时周期为2000ms,其他参数与TIM6一样。TIM7的模式和参数设置结果如图4-2 所示,在模式设置部分勾选现One Pulse Mode复选框,使TIM7工作于单次定时模式。
在这里插入图片描述
                    图4-2 定时器TIM7的模式和参数配置

(3)定时器TIM2的模式和参数设置结果如图4-3所示,定时周期设置为10ms。
时钟源时钟频率 = 84MHZ
PSC 预分频器值 = 840-1
ARR自动自动重装载值 = 1000-1
定时器时钟频率 = 时钟源时钟频率 / [ (PSC+1)(ARR+1) ]
注:之所以要加1是因为计数从0开始的,不是从1开始计数的。
即 84000000 / [ (840-1 +1) x (1000-1 +1) ] = 84000000/[840*1000] = 100
计时周期 = 频率的倒数 = 0.01s =10 ms,即每10ms进入一次TIM2中断在这里插入图片描述
                    图4-3 定时器TIM2的模式和参数配置

(4)还需要开启TIM6、TIM7、TIM2的中断,在定时器配置界面的NVIC Setting页面里,可以开启定时器中断,但是不能设置中断优先级。TIM6、TIM7和TIM2的中断优先级需要在NVIC组件的配置界面设置,如图。两个定时器的抢占优先级都设置成1,其实设置成0也没有影响,因为本示例在定时器的ISR里不会直接或间接调用延时函数HAL_Delay()。
注:HAL_Delay()延时函数会用到Systick定时器中断,而这个中断的抢占优先级是0.如果某个外部中断的抢占优先级为0,执行外部中断的ISR时调用HAL_Delay(),则Systick中断无法抢占,函数HAL_Delay()的执行就会陷入死循环。如果将所有中断外部回调的抢占优先级设置为1或2,在外部中断的ISR里调用HAL_Delay()时,Systick中断就可以抢占外部中断,正常执行。

在这里插入图片描述                  图4-4 设置TIM6、TIM7、TIM2的中断优先级
(5)按键外部触发模式设置
  ①如图4-5,按键KEY1时外端接地,按键按下时,输入低电平,所以需要设置成下降沿外部触发中断(External lnterrupt Mode with Falling edge trigger detection),使用输入上拉(Pull-up)。
  ②按照图4-6的步骤 设置CubeMx里面的按键触发模式。
在这里插入图片描述
                         图4-5 按键原理图
在这里插入图片描述                     图4-6 按键 外部触发模式CubeMx设置

2、程序功能实现

(1)在定时器2的中断服务例程里面进行消抖,消抖成功即表明按键按下后开启定时器7,同时将定时器2关闭,为下一次按键按下做准备。
在这里插入图片描述

	static uint8_t key_ticks = 0;								    						/* 用于按键计数 */
	if(HAL_GPIO_ReadPin(GPIOE, GPIO_PIN_3) == GPIO_PIN_RESET){     						    /* 确认按键是否正常按下 */
			key_ticks++;																	/* 消抖 */
			if (key_ticks == 2){    														/* 20ms */        
				HAL_TIM_Base_Start_IT(&htim7);												/* 开启定时器7 */
				HAL_TIM_Base_Stop_IT(&htim2);												/* 及时关闭定时器2,已完成消抖任务 */
                key_ticks = 0;																/* 按键计数清零,为下一次按键触发做准备 */
		}
	}

(2)开启定时器6中断
在这里插入图片描述

	HAL_TIM_Base_Start_IT(&htim6); /* 开启定时器6定时中断 */

(3)
①重新定义外部触发中断回调函数,当按键按下时,触发中断,在中断里调用对应的回调函数,在回调函数里面开启定时器2。
②在文件stm32f4xx_it.c中,CubeMx自动生成了定时器TIM6和TIM7的应交中断ISR的代码框架,代码如下(该处系统已自动生成,张贴出来只为进行说明)

/**
  * @brief This function handles TIM6 global interrupt, DAC1 and DAC2 underrun error interrupts.
  */
void TIM6_DAC_IRQHandler(void)
{
  /* USER CODE BEGIN TIM6_DAC_IRQn 0 */

  /* USER CODE END TIM6_DAC_IRQn 0 */
  HAL_TIM_IRQHandler(&htim6);
  /* USER CODE BEGIN TIM6_DAC_IRQn 1 */

  /* USER CODE END TIM6_DAC_IRQn 1 */
}
/**
  * @brief This function handles TIM7 global interrupt.
  */
void TIM7_IRQHandler(void)
{
  /* USER CODE BEGIN TIM7_IRQn 0 */

  /* USER CODE END TIM7_IRQn 0 */
  HAL_TIM_IRQHandler(&htim7);
  /* USER CODE BEGIN TIM7_IRQn 1 */

  /* USER CODE END TIM7_IRQn 1 */
}

③这两个ISR都调用用了定时器中断通用处理函数 HAL_TIM_IRQHandler(),在这个通用处理函数里,程序会判断产生定时器硬件中断的事件源然后调用对应的会调函数进行处理。
④基础定时器的中断事件源只有一个,就是计数器溢出时产生的UEV事件,对应的回调函数是HAL_TIM_PerioElapsedCallback(),用户需要重新实现这个函数进行中断处理。为此,我们将定时器回调函数与HAL_GPIO_EXTI_Callback()函数 在mian.c中重新实现,代码如下:
在这里插入图片描述

	/**
 * @brief   外部触发中断(EXTI)的回调函数
 *          
 * @param
 * @return
 */
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)  
{
	HAL_TIM_Base_Start_IT(&htim2);   /* 开启定时器2 */
}

/**
 * @brief   定时器(TIM)中断的回调函数
 *          
 * @param
 * @return
 */
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
	if(htim->Instance == TIM6){                   						/* 判断是否是定时器6 */
			HAL_GPIO_TogglePin(GPIOF,GPIO_PIN_10);    						/* 将灯的引脚电平进行翻转--PF10 */
	}
	if(htim->Instance == TIM7){																/* 判断是否是定时器7 */
			HAL_GPIO_TogglePin(GPIOF,GPIO_PIN_9);									/* 将灯的引脚电平进行翻转--PF9 */
	}
}

中断响应的ISR是可重入的,事件中断响应的回调函数也可是重入的,计时TIM6和TIM7的中断同时发生,它们的中断响应代码也会被执行。

五、总结

本文主要讲解基础定时器的使用,其中还涉及了按键处理和点灯的操作。其中对CubeMx自动生成的代码部分(例如 定时器初始化)没有做过多的解释,但我们不应该忽视了这部分,应该熟悉基础定时器从配置到实现功能的整个流程。


源码链接 点击百度网盘领取
提取码:n1qj

参考书籍:
《STM32Cube高效开发教程(基础篇)》王维波
《STM32F4xx中文参考手册》
《STM32F407 探索者开发指南》


只要今天比昨天好,这不就是希望吗?

-----------《士兵突击》

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

基于python+django+vue的家居全屋定制系统

作者:计算机学姐 开发技术:SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等,“文末源码”。 专栏推荐:前后端分离项目源码、SpringBoot项目源码、SSM项目源码 系统展示 【2025最新】基于协同过滤pythondjangovue…

文件误删除后的数据救援实战指南

在数字化时代,文件误删除成为了许多用户心头挥之不去的阴影。无论是手误点击了“删除”键,还是系统崩溃导致的数据丢失,文件一旦从我们的视线中消失,往往伴随着重要信息的流失和工作的中断。本文将深入探讨文件误删除的现象&#…

kubernetes技术详解,带你深入了解k8s

目录 一、Kubernetes简介 1.1 容器编排应用 1.2 Kubernetes简介 1.3 k8s的设计架构 1.3.1 k8s各个组件的用途 1.3.2 k8s各组件之间的调用关系 1.3.3 k8s的常用名词概念 1.3.4 k8s的分层结构 二、k8s集群环境搭建 2.1 k8s中容器的管理方式 2.2 k8s环境部署 2.2.1 禁用…

如何在GitHub上克隆仓库:HTTPS、SSH和GitHub CLI的区别

GitHub是开发者的天堂,提供了丰富的工具和功能来管理代码和项目。在克隆GitHub仓库时,你可能会遇到三种常见的方法:HTTPS、SSH和GitHub CLI。每种方法都有其独特的优势和适用场景。本文将深入探讨这三种克隆方式的区别,帮助你选择…

AI助力遥感影像智能分析计算,基于高精度YOLOv5全系列参数【n/s/m/l/x】模型开发构建卫星遥感拍摄场景下地面建筑物智能化分割检测识别系统

随着科技的飞速发展,卫星遥感技术已成为获取地球表面信息的重要手段之一。卫星遥感图像以其覆盖范围广、数据量大、信息丰富等特点,在环境监测、城市规划、灾害评估等多个领域发挥着不可替代的作用。然而,面对海量的卫星图像数据,…

react hooks--useLayoutEffect

概述 ◼ useLayoutEffect看起来和useEffect非常的相似,事实上他们也只有一点区别而已:  useEffect会在渲染的内容更新到DOM上后执行,不会阻塞DOM的更新;  useLayoutEffect会在渲染的内容更新到DOM上之前执行,会…

JUC学习笔记(二)

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 四、共享模型之内存4.1 Java 内存模型4.2 可见性退不出的循环解决方法可见性 vs 原子性模式之 Balking1.定义2.实现 4.3 有序性原理之指令级并行1. 名词2.鱼罐头的故…

STM32巡回研讨会总结(2024)

前言 本次ST公司可以说是推出了7大方面,几乎可以说是覆盖到了目前生活中的方方面面,下面总结下我的感受。无线类 支持多种调制模式(LoRa、(G)FSK、(G)MSK 和 BPSK)满足工业和消费物联网 (IoT) 中各种低功耗广域网 (LPWAN) 无线应…

【Android 13源码分析】WindowContainer窗口层级-4-Layer树

在安卓源码的设计中,将将屏幕分为了37层,不同的窗口将在不同的层级中显示。 对这一块的概念以及相关源码做了详细分析,整理出以下几篇。 【Android 13源码分析】WindowContainer窗口层级-1-初识窗口层级树 【Android 13源码分析】WindowCon…

计算机的错误计算(九十五)

摘要 从计算机的错误计算(八十六)至(九十四),其主题均涉及对数运算。本节用错数解释(九十四)中的错误计算的原因。其余类似。 首先,由计算机的错误计算(二十七&#xf…

QUIC的loss detection学习

PTO backoff backoff 补偿 /ˈbkɒf/PTO backoff 是QUIC(Quick UDP Internet Connections)协议中的一种机制,用于处理探测超时(Probe Timeout, PTO)重传策略 它逐步增加探测超时的等待时间,以避免网络拥塞…

外网(公网)访问VMware workstation 虚拟机内web网站的配置方法---端口转发总是不成功的原因

问题背景:客户提供的服务器操作系统配置web程序时,总是显示莫名其妙的问题,发现是高版本操作系统的.net库已经对低版本.net库进行了大范围修订,导致在安全检测上、软件代码规范上更加苛刻,最终导致部署不成功。于是想到…

使用Qt 搭建简单雷达

目录 1.简易雷达图思维导图 2.结果展示图 3.制作流程 3.1表盘的绘制 3.1.1 绘制底色 ​编辑 3.1.2 绘制大圆 3.3.3绘制小圆 3.3.4 绘制小圆的内容 3.3.5 绘制表盘刻度和数字标注 3.3.6 绘制指针 3.3.7 绘制扇形 3.2 设置定时器让表盘动起来 3.3.1 设置动态指针…

Excel图片批量插入单元格排版处理插件【图片大师】

为了方便大家在图片的插入排版的重复工作中解放出来,最近发布了一款批量插入图片的插件,欢迎大家下载,免费试用。 这是图片的文件夹: 主要功能如下: 1,匹配单元格名称的多张图批量插入到一个单元格 该功能支持设置图…

【1.使用Index和Match函数自动补全内容】

目录 前言如何利用函数自动填充内容效果学会使用的方法(文字图片版本)只管使用,不看原理原理解读MATCH函数INDEX函数组合 学会使用的方法(视频版本) 后言最后想说的话 前言 如何利用函数自动填充内容 先说结论,本文的目的是通过使用Excel的函数&#xf…

深度强化学习Reinforcement Learning|PG|Actor-Critic|A3C|DDPG

目录 一、PG(Policy Gradient)策略梯度算法(on-policy) 1、策略梯度公式推导 2、代码讲解/伪代码 3、改进 3.1Trick Baseline 3.2 Suitable Credit 二、Actor-Critic算法 三、A3C算法 四、DDPG算法 前言 我们都知道强化学习环境env的不确定性是…

TCP协议分析《实验报告》

一、实验目的 1、理解TCP协议; 2、掌握TCP协议三次握手建立连接和四次挥手释放连接的过程; 3、理解TELNET协议及工作过程; 4、掌握TCP协议分析方法。 二、实验设备和环境 1、硬件设备:PC机或笔记本电脑; 2、软件…

Matlab simulink建模与仿真 第十七章(补充离散库和补充数学库)

参考视频:simulink1.1simulink简介_哔哩哔哩_bilibili 一、补充离散库和补充数学库中的模块概览 1、补充离散库 注:每个版本的补充离散库不一定相同,也不是每个版本的库都有如上所有模块。 2、补充数学库 二、离散直接传递函数Ⅱ模块 1、…

OpenCV_图像旋转超详细讲解

图像转置 transpose(src, dst); transpose()可以实现像素下标的x和y轴坐标进行对调:dst(i,j)src(j,i),接口形式 transpose(InputArray src, // 输入图像OutputArray dst, // 输出 ) 图像翻转 flip(src, dst, 1); flip()函数可以实现对图像的水平翻转…

re题(24)BUUFCTF-[WUSTCTF2020]level1

BUUCTF在线评测 (buuoj.cn) 放到ida 这是下载的文本 逻辑比较简单,写个脚本 p[198,232,816,200,1536,300,6144,984,51200,570,92160,1200,565248,756,1474560,800,6291456,1782,65536000] for i in range(1,20):if (i & 1) ! 0 :p[i-1]chr(p[i-1] >> i)…