当前位置: 首页 > news >正文

定时器的小应用

第一个项目

第一步,RCC开启时钟,这个基本上每个代码都是第一步,不用多想,在这里打开时钟后,定时器的基准时钟和整个外设的工作时钟就都会同时打开了

RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);

第二步,选择时基单元的时钟源,对于定时中断,我们就选择内部时钟源

TIM_InternalClockConfig(TIM2);//很多人不写这个函数,因为定时器上电后默认就是内部时钟

第三步,配置时基单元,包括预分频器、自动重装器、计数模式等等,这些参数用一个struct就可以配置好

TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInitStructure.TIM_Period = 10000 - 1; //ARR自动重装器的值【0-65535】
TIM_TimeBaseInitStructure.TIM_Prescaler = 7200 - 1; //PSC预分频器的值【0-65535】,两者取值都不是唯一的
TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0; //重复计数器的值(高级定时器c)
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStructure);
上面并没有CNT计数器的参数,如果我们需要的话,可以用之前说的SetCounter和GetCounter这两个函数来操作计数器

如果我们想定时1秒(也就是定时频率为1Hz),用下面这个公式来算

计数器溢出频率: C K _ C N T _ O V = C K _ C N T / ( A R R + 1 ) = C K _ P S C / ( P S C + 1 ) / ( A R R + 1 ) CK\_CNT\_OV = CK\_CNT / (ARR + 1) = CK\_PSC / (PSC + 1) / (ARR + 1) CK_CNT_OV=CK_CNT/(ARR+1)=CK_PSC/(PSC+1)/(ARR+1)

TIM_TimeBaseInitStructure

typedef struct
{uint16_t TIM_Prescaler;         /*!< Specifies the prescaler value used to divide the TIM clock.This parameter can be a number between 0x0000 and 0xFFFF */uint16_t TIM_CounterMode;       /*!< Specifies the counter mode.This parameter can be a value of @ref TIM_Counter_Mode */uint16_t TIM_Period;            /*!< Specifies the period value to be loaded into the activeAuto-Reload Register at the next update event.This parameter must be a number between 0x0000 and 0xFFFF.  */ uint16_t TIM_ClockDivision;     /*!< Specifies the clock division.//指定时钟分频This parameter can be a value of @ref TIM_Clock_Division_CKD */ //TIM_Clock_Division_CKD是用来干啥的呢?滤波器可以滤掉信号的抖动干扰,怎么工作的呢?就是在一个固定时钟频率f下进行采样,如果连续N个采样点都为相同的电平,那就代表输入信号稳定了,就把采样值输出出去,如果这N个采样值不全都相同,那就说明信号有抖动,这时就保持上一次的输出,或者直接输出低电平也行,这样就可以保证输出信号在一定程度上的滤波了,这里的采样频率f(可以内部时钟直接而来,也可以由内部时钟加一个时钟分频而来,分频多少就是由TIM_Clock_Division_CKD决定,这个参数和时基单元关系并不大,我们随便配一个就行)和采样点N都是滤波器的参数,频率越低,采样点数越多,那滤波效果就越好,不过相应的信号延迟就大uint8_t TIM_RepetitionCounter;  /*!< Specifies the repetition counter value. Each time the RCR downcounterreaches zero, an update event is generated and counting restartsfrom the RCR value (N).This means in PWM mode that (N+1) corresponds to:- the number of PWM periods in edge-aligned mode- the number of half PWM period in center-aligned modeThis parameter must be a number between 0x00 and 0xFF. @note This parameter is valid only for TIM1 and TIM8. */
} TIM_TimeBaseInitTypeDef;      

TIM_Clock_Division_CKD

/** @defgroup TIM_Clock_Division_CKD * @{*/#define TIM_CKD_DIV1                       ((uint16_t)0x0000) //不分频
#define TIM_CKD_DIV2                       ((uint16_t)0x0100) //二分频
#define TIM_CKD_DIV4                       ((uint16_t)0x0200) //四分频
#define IS_TIM_CKD_DIV(DIV) (((DIV) == TIM_CKD_DIV1) || \((DIV) == TIM_CKD_DIV2) || \((DIV) == TIM_CKD_DIV4))
/*** @}*/

TIM_Counter_Mode

/** @defgroup TIM_Counter_Mode * @{*/#define TIM_CounterMode_Up                 ((uint16_t)0x0000) //向上计数
#define TIM_CounterMode_Down               ((uint16_t)0x0010) //向下计数
#define TIM_CounterMode_CenterAligned1     ((uint16_t)0x0020) //三种中央对齐模式
#define TIM_CounterMode_CenterAligned2     ((uint16_t)0x0040)
#define TIM_CounterMode_CenterAligned3     ((uint16_t)0x0060)
#define IS_TIM_COUNTER_MODE(MODE) (((MODE) == TIM_CounterMode_Up) ||  \((MODE) == TIM_CounterMode_Down) || \((MODE) == TIM_CounterMode_CenterAligned1) || \((MODE) == TIM_CounterMode_CenterAligned2) || \((MODE) == TIM_CounterMode_CenterAligned3))
/*** @}*/ 

第四步,配置输出中断控制,允许更新中断输出到NVIC

TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);//开启了更新中断到NVIC的通路

/*** @brief  Enables or disables the specified TIM interrupts.* @param  TIMx: where x can be 1 to 17 to select the TIMx peripheral.* @param  TIM_IT: specifies the TIM interrupts sources to be enabled or disabled.*   This parameter can be any combination of the following values:*     @arg TIM_IT_Update: TIM update Interrupt source \\ 更新中断*     @arg TIM_IT_CC1: TIM Capture Compare 1 Interrupt source*     @arg TIM_IT_CC2: TIM Capture Compare 2 Interrupt source*     @arg TIM_IT_CC3: TIM Capture Compare 3 Interrupt source*     @arg TIM_IT_CC4: TIM Capture Compare 4 Interrupt source*     @arg TIM_IT_COM: TIM Commutation Interrupt source*     @arg TIM_IT_Trigger: TIM Trigger Interrupt source*     @arg TIM_IT_Break: TIM Break Interrupt source* @note *   - TIM6 and TIM7 can only generate an update interrupt.*   - TIM9, TIM12 and TIM15 can have only TIM_IT_Update, TIM_IT_CC1,*      TIM_IT_CC2 or TIM_IT_Trigger. *   - TIM10, TIM11, TIM13, TIM14, TIM16 and TIM17 can have TIM_IT_Update or TIM_IT_CC1.   *   - TIM_IT_Break is used only with TIM1, TIM8 and TIM15. *   - TIM_IT_COM is used only with TIM1, TIM8, TIM15, TIM16 and TIM17.    * @param  NewState: new state of the TIM interrupts.*   This parameter can be: ENABLE or DISABLE.* @retval None*/
void TIM_ITConfig(TIM_TypeDef* TIMx, uint16_t TIM_IT, FunctionalState NewState)
{  /* Check the parameters */assert_param(IS_TIM_ALL_PERIPH(TIMx));assert_param(IS_TIM_IT(TIM_IT));assert_param(IS_FUNCTIONAL_STATE(NewState));if (NewState != DISABLE){/* Enable the Interrupt sources */TIMx->DIER |= TIM_IT;}else{/* Disable the Interrupt sources */TIMx->DIER &= (uint16_t)~TIM_IT;}
}

第五步,配置NVIC,在NVIC中打开定时器中断的通道,并分配一个优先级(和中断那一节流程一样)

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_Init(&NVIC_InitStructure);

第六步,运行控制

TIM_Cmd(TIM2, ENABLE);

整个模块配置完成后,我们还需要使能一下计数器(要不然计数器不会运行),当定时器使能后,计数器就会开始计数了,当数器更新时,触发中断

最后我们再写一个定时器的中断函数

void TIM2_IRQHandler(void)
{if (TIM_GetITStatus(TIM2, TIM_IT_Update) == SET){TIM_ClearITPendingBit(TIM2, TIM_IT_Update);}
}

这样这个中断函数每隔一段时间就能自动执行一次了

定时器的库函数

void TIM_DeInit(TIM_TypeDef* TIMx);void TIM_TimeBaseInit(TIM_TypeDef* TIMx, TIM_TimeBaseInitTypeDef* TIM_TimeBaseInitStruct); //时基单元初始化,它就是用来配置这个图里这里的时基单元的
//第一个TIMx选择某个定时器,第二个是结构体,里面包含了配置时基单元的一些参数void TIM_TimeBaseStructInit(TIM_TimeBaseInitTypeDef* TIM_TimeBaseInitStruct);//结构体变量赋一个默认值,void TIM_Cmd(TIM_TypeDef* TIMx, FunctionalState NewState);//这个是用来使能计数器的,对应的就是图里面的运行控制,第二个NewState新的状态,也就是使能还是失能void TIM_ITConfig(TIM_TypeDef* TIMx, uint16_t TIM_IT, FunctionalState NewState);//这个是用来使能外设的中断输出信号的,对应的就是图里面的中断输出控制,第二个TIM_IT,选择要配置哪个中断输出,第三个,使能与否下面6个函数对应的就是时基单元的时钟选择部分,可以选择RCC内部时钟、ETR外部时钟、ITRx其他定时器、TIx捕获通道这些void TIM_InternalClockConfig(TIM_TypeDef* TIMx);//选择内部时钟void TIM_ITRxExternalClockConfig(TIM_TypeDef* TIMx, uint16_t TIM_InputTriggerSource);//选择ITRx其他定时器的时钟,InputTriggerSource:选择要接入哪个其他的定时器void TIM_TIxExternalClockConfig(TIM_TypeDef* TIMx, uint16_t TIM_TIxExternalCLKSource,uint16_t TIM_ICPolarity, uint16_t ICFilter);//选择TIx捕获通道的时钟,TIxExternalCLKSource,选择TIx具体的某个引脚,接着还有两个参数ICPolarity和CFilter,输入的极性和滤波器,对于外部引脚的波形,一般都会有极性选择和滤波器,这样更灵活一些void TIM_ETRClockMode1Config(TIM_TypeDef* TIMx, uint16_t TIM_ExtTRGPrescaler, uint16_t TIM_ExtTRGPolarity, uint16_t ExtTRGFilter);//选择ETR通过外部时钟模式1输入的时钟,ExtTRGPrescaler,外部触发预分频器(这里可以对ETR的外部时钟再提前做一个分频),接下来两个和上面那个函数参数一样
void TIM_ETRClockMode2Config(TIM_TypeDef* TIMx, uint16_t TIM_ExtTRGPrescaler, uint16_t TIM_ExtTRGPolarity, uint16_t ExtTRGFilter);//选择ETR通过外部时钟模式2输入的时钟
//对于ETR输入的外部时钟而言,上面这两个函数是等效的,它们的参数是一样的,如果不需要触发输入的功能,那这两个函数可以互换void TIM_ETRConfig(TIM_TypeDef* TIMx, uint16_t TIM_ExtTRGPrescaler, uint16_t TIM_ExtTRGPolarity, uint16_t ExtTRGFilter);//这个不是用来选择时钟的,就是单独用来配置ETR引脚的预分频器、极性、滤波器这些参数的

TIM_ITRxExternalClockConfig

Snipaste_2024-11-17_13-14-46

Snipaste_2024-11-17_13-18-17

Snipaste_2024-11-17_13-19-34

Snipaste_2024-11-17_13-23-05

因为在初始化结构体里有很多关键的参数,比如自动重装值和预分频值等等,这些参数可能会在初始化之后还需要更改,如果为了改某个参数,再调用一次初始化函数,这样太麻烦了,所以这里有一些单独的函数,可以方便地更改这些关键参数

void TIM_PrescalerConfig(TIM_TypeDef* TIMx, uint16_t Prescaler, uint16_t TIM_PSCReloadMode); //单独用来写预分频值的,Prescaler,要写入的预分频值,TIM_PSCReloadMode,写入的模式(预分频器有一个缓冲器,这个参数决定这个影子寄存器是否生效,或者是在写入后,手动产生一个更新事件,让这个值立刻生效)void TIM_CounterModeConfig(TIM_TypeDef* TIMx, uint16_t TIM_CounterMode); //改变计数器的计数模式的,TIM_CounterMode:选择新的计数器模式void TIM_ARRPreloadConfig(TIM_TypeDef* TIMx, FunctionalState NewState);//自动重装器预装功能配置,有无预装是可以自己选择的,使能与否就可以使这个是否有无预装void TIM_SetCounter(TIM_TypeDef* TIMx, uint16_t Counter);//给计数器写入一个值,如果你想手动给一个计数值,就可以用这个函数void TIM_SetAutoreload(TIM_TypeDef* TIMx, uint16_t Autoreload);//给自动重装器写入一个值uint16_t TIM_GetCounter(TIM_TypeDef* TIMx);//获取当前计数器的值uint16_t TIM_GetPrescaler(TIM_TypeDef* TIMx);//获取当前预分频器的值下面四个就是之前中断里面学习的那四个函数,获取标志位和清除标志位的
FlagStatus TIM_GetFlagStatus(TIM_TypeDef* TIMx, uint16_t TIM_FLAG);
void TIM_ClearFlag(TIM_TypeDef* TIMx, uint16_t TIM_FLAG);
ITStatus TIM_GetITStatus(TIM_TypeDef* TIMx, uint16_t TIM_IT);
void TIM_ClearITPendingBit(TIM_TypeDef* TIMx, uint16_t TIM_IT);

主函数内容

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "OLED.h"
#include "Timer.h"uint16_t Num;int main(void)
{OLED_Init();Timer_Init();OLED_ShowString(1, 1, "Num:");while (1){OLED_ShowNum(1, 5, Num, 5);}
}
//为了不让Num跨文件,所以把中断函数放到了这个
void TIM2_IRQHandler(void)
{if (TIM_GetITStatus(TIM2, TIM_IT_Update) == SET){Num ++;TIM_ClearITPendingBit(TIM2, TIM_IT_Update);}
}

我们调试运行发现,每次复位Num都是从1开始计数的,按理说Num的初始值是0,应该是从0开始计数的,这说明中断函数在初始化之后就立刻进入了一次,这是怎么回事呢?

打开一下TIM_TimeBaseInit函数的定义

Snipaste_2024-11-17_20-45-58

英文意思是:生成一个更新事件,来重新装载预分频器和重复计数器的值,立刻

我们知道这个预分频器是有个缓冲寄存器的,我们写的值只有在更新事件时,才会真正起作用,这里为了让值立刻起作用,所以在这最后,手动生成了一个更新事件,这样预分频器的值就有效了,但同时,它的副作用就是,更新事件和更新中断是同时发生的,更新中断会置更新中断标志位,当我们之后一但初始化完了,更新中断就会立刻进入,这就是我们刚一上电,就立该进中断的原因

解决方案:在TIM_TimeBaseInit后面,开启中断的前面,再手动调用一下TIM_ClearFlag(TIM2, TIM_FLAG_Update);

第二个项目

接线图:

6-2 定时器外部时钟

这个PA0引脚就是TIM2的ETR引脚,我们在这个引脚输入一个外部时钟

TIM_ETRClockMode2Config(TIM2, TIM_ExtTRGPSC_OFF, TIM_ExtTRGPolarity_NonInverted, 0x0F);//通过ETR引脚的外部时钟模式2配置
/*** @brief  Configures the External clock Mode2* @param  TIMx: where x can be  1, 2, 3, 4, 5 or 8 to select the TIM peripheral.* @param  TIM_ExtTRGPrescaler: The external Trigger Prescaler. 外部触发预分频器,可以是下面这些值*   This parameter can be one of the following values:*     @arg TIM_ExtTRGPSC_OFF: ETRP Prescaler OFF. //不需要分频就选择第一个*     @arg TIM_ExtTRGPSC_DIV2: ETRP frequency divided by 2.*     @arg TIM_ExtTRGPSC_DIV4: ETRP frequency divided by 4.*     @arg TIM_ExtTRGPSC_DIV8: ETRP frequency divided by 8.* @param  TIM_ExtTRGPolarity: The external Trigger Polarity. //外部触发的极性*   This parameter can be one of the following values:*     @arg TIM_ExtTRGPolarity_Inverted: active low or falling edge active. //反向,就是低电平或下降沿有效*     @arg TIM_ExtTRGPolarity_NonInverted: active high or rising edge active.//不反向,高电平或上升沿有效(目前选这个)* @param  ExtTRGFilter: External Trigger Filter.外部触发滤波器,这个值必须是0x00到0x0F之间的一个值,这个值就是来决定上面讲的滤波器的f和N的*   This parameter must be a value between 0x00 and 0x0F* @retval None*/
void TIM_ETRClockMode2Config(TIM_TypeDef* TIMx, uint16_t TIM_ExtTRGPrescaler, uint16_t TIM_ExtTRGPolarity, uint16_t ExtTRGFilter)
{/* Check the parameters */assert_param(IS_TIM_LIST3_PERIPH(TIMx));assert_param(IS_TIM_EXT_PRESCALER(TIM_ExtTRGPrescaler));assert_param(IS_TIM_EXT_POLARITY(TIM_ExtTRGPolarity));assert_param(IS_TIM_EXT_FILTER(ExtTRGFilter));/* Configure the ETR Clock source */TIM_ETRConfig(TIMx, TIM_ExtTRGPrescaler, TIM_ExtTRGPolarity, ExtTRGFilter);/* Enable the External clock mode2 */TIMx->SMCR |= TIM_SMCR_ECE;
}

ExtTRGFilter的取值

Snipaste_2024-11-17_22-38-16

我们暂时不用滤波器,所以写0x00就行了

因为引脚用到了GPIO所以我们也要初始化GPIO

GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);

Snipaste_2024-11-17_22-41-58

但是浮空输入(如果你外部的输入信号功率很小,内部的这个上拉电阻可能会影响到这个输入信号,这时采用浮空输入,防止外部输入的电平)会导致电平跳个没完,所以还是给了上拉输入

TIM_TimeBaseInitStructure.TIM_Period = 10 - 1; //从0计到9就行了
TIM_TimeBaseInitStructure.TIM_Prescaler = 1 - 1;//手动模拟的输入没有那么快,所以不需要分频

相关文章:

定时器的小应用

第一个项目 第一步&#xff0c;RCC开启时钟&#xff0c;这个基本上每个代码都是第一步&#xff0c;不用多想&#xff0c;在这里打开时钟后&#xff0c;定时器的基准时钟和整个外设的工作时钟就都会同时打开了 RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);第二步&…...

【计算机网络】UDP协议

一、UDP协议格式 1.报头的含义 ① 16位源端口号&#xff1a;自己的端口号 ② 16位目的端口号&#xff1a;对方的端口号 ③ 16位UDP长度&#xff1a;整个数据报(UDP报头UDP有效载荷)的长度&#xff0c;最大64KB 一个UDP最多传64KB的数据&#xff0c;如果要传的数据 > 64K…...

vulhub之log4j

Apache Log4j Server 反序列化命令执行漏洞(CVE-2017-5645) 漏洞简介 Apache Log4j是一个用于Java的日志记录库,其支持启动远程日志服务器。Apache Log4j 2.8.2之前的2.x版本中存在安全漏洞。攻击者可利用该漏洞执行任意代码。 Apache Log4j 在应用程序中添加日志记录最…...

[Unity] 关于引入Google SDK以及使用的方法

在Unity中接入谷歌SDK&#xff08;如Google Play Games SDK或Firebase SDK等&#xff09;通常涉及几个关键步骤&#xff0c;包括下载SDK、导入Unity项目、配置项目设置、编写必要的代码以及测试集成。以下是一个基于Firebase SDK接入Unity的示例&#xff0c;同时涵盖了Google P…...

集群聊天服务器(13)redis环境安装和发布订阅命令

目录 环境安装订阅redis发布-订阅的客户端编程环境配置客户端编程 功能测试 环境安装 sudo apt-get install redis-server 先启动redis服务 /etc/init.d/redis-server start默认在6379端口上 redis是存键值对的&#xff0c;还可以存链表、数组等等复杂数据结构 而且数据是在…...

第R4周:LSTM-火灾温度预测(pytorch版)

>- **&#x1f368; 本文为[&#x1f517;365天深度学习训练营]中的学习记录博客** >- **&#x1f356; 原作者&#xff1a;[K同学啊]** 往期文章可查阅&#xff1a; 深度学习总结 任务说明&#xff1a;数据集中提供了火灾温度&#xff08;Tem1&#xff09;、一氧化碳浓度…...

基于SpringBoot和uniapp开发的医护上门系统上门护理小程序

项目分析 一、市场需求分析 人口老龄化趋势&#xff1a;随着全球及中国人口老龄化的加剧&#xff0c;老年人口数量显著增加&#xff0c;对医疗护理服务的需求也随之增长。老年人由于身体机能下降&#xff0c;更需要便捷、高效的医护服务&#xff0c;而医护上门服务恰好满足了这…...

js批量输入地址获取经纬度

使用js调用高德地图的接口批量输入地址获取经纬度。 以下的请求接口的key请换成你的key。 创建key&#xff1a;我的应用 | 高德控制台 &#xff0c;服务平台选择《Web服务》。 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-…...

Python自动化测试实践中pytest用到的功能dependency和parametrize

Python自动化测试中pytest用到的功能 1、pytest之@pytest.mark.dependency装饰器设置测试用例之间的依赖关系 1.1说明: 1、这是一个pytest第三方插件,主要解决用例之间的依赖关系。如果依赖的上下文测试用例失败后续的用例会被标识为跳过执行,相当于执行了 pytest.mark.s…...

json-bigint处理前端精度丢失问题

问题描述&#xff1a;前后端调试过程中&#xff0c;有时候会遇到精度丢失的问题&#xff0c;比如后端给过来的id超过16位&#xff0c;就会出现精度丢失的情况&#xff0c;前端拿到的id与后端给过来的不一致。 解决方案&#xff1a; 1、安装 npm i json-bigint 2、在axios中配置…...

神经网络10-Temporal Fusion Transformer (TFT)

Temporal Fusion Transformer (TFT) 是一种专为时序数据建模而设计的深度学习模型&#xff0c;它结合了Transformer架构和其他技术&#xff0c;旨在有效地处理和预测时序数据中的复杂模式。TFT 于 2020 年由 Google Research 提出&#xff0c;旨在解决传统模型在时序预测中的一…...

django基于django的民族服饰数据分析系统的设计与实现

摘 要 随着网络科技的发展&#xff0c;利用大数据分析对民族服饰进行管理已势在必行&#xff1b;该平台将帮助企业更好地理解服饰市场的趋势&#xff0c;优化服装款式&#xff0c;提高服装的质量。 本文讲述了基于python语言开发&#xff0c;后台数据库选择MySQL进行数据的存储…...

html数据类型

数据类型是字面含义&#xff0c;表示各种数据的类型。在任何语言中都存在数据类型&#xff0c;因为数据是各式各样。 1.数值类型 number let a 1; let num 1.1; // 整数小数都是数字值 ​ // 数字肯定有个范围 正无穷大和负无穷大 // Infinity 正无穷大 // -Infinity 负…...

Springboot启动异常 错误: 找不到或无法加载主类 xxx.Application异常

Springboot启动异常 错误: 找不到或无法加载主类 xxx.Application异常 报错提示 Connected to the target VM, address: 127.0.0.1:57210, transport: socket 错误:找不到或无法加载主类 global.hh.manage.HHMicroCloudProviderApplication Disconnected from the target VM, …...

哋它亢SEO技术分析:如何提升网站在搜索引擎中的可见性

文章目录 哋它亢SEO技术分析&#xff1a;如何提升网站在搜索引擎中的可见性网站的基本情况SEO优化分析与建议1. 元数据优化2. 关键词优化3. URL结构4. 图像优化5. 移动端优化6. 网站速度7. 结构化数据&#xff08;Schema Markup&#xff09;8. 内链与外链9. 社交分享 哋它亢SEO…...

web——upload-labs——第十一关——黑名单验证,双写绕过

还是查看源码&#xff0c; $file_name str_ireplace($deny_ext,"", $file_name); 该语句的作用是&#xff1a;从 $file_name 中去除所有出现在 $deny_ext 数组中的元素&#xff0c;替换为空字符串&#xff08;即删除这些元素&#xff09;。str_ireplace() 在处理时…...

ElasticSearch7.x入门教程之中文分词器 IK(二)

文章目录 前言一、内置分词器二、中文IK分词器&#xff08;第三方&#xff09;三、本地自定义四、远程词库总结 前言 ElasticSearch 核心功能就是数据检索&#xff0c;首先通过索引将文档写入 es。 查询分析则主要分为两个步骤&#xff1a; 1、词条化&#xff1a;分词器将输入…...

体积全息及平面全息图的衍射效率

一、体积全息 当记录材料的厚度是条纹间距的若干倍时&#xff0c;则在记录材料体积内将记录下干涉全息图的三维空间分布&#xff0c;就形成了体积全息。 按物光和参考光入射方向和再现方式的不同体积全息可以分为两种。 一种是物光和参考光在记录介质的同一侧入射&#xff0c;得…...

【常用组件整理】

xgplayer 字节开发的前端视频播放器 xgplayer是一个由字节跳动开发的强大的前端视频播放器&#xff0c;具有稳定性高、文档清晰、支持弹幕和移动端优化 等特点。相较于VideoJs&#xff0c;xgplayer的文档更简洁&#xff0c;自定义插件更为便捷。xgplayer还提供了丰富的插件来扩…...

用指针函数寻找数组中的最大值与次大值

#include <stdio.h>// 函数用于找出数组中的最大值和次大值 void LargestTow(int a[], int n, int *pfirst, int *psecond) {*pfirst a[0];*psecond a[1];if (*psecond > *pfirst) {// 如果初始的次大值大于最大值&#xff0c;交换它们int temp *pfirst;*pfirst *…...

原生微信小程序在顶部胶囊左侧水平设置自定义导航兼容各种手机模型

无论是在什么手机机型下&#xff0c;自定义的导航都和右侧的胶囊水平一条线上。如图下 以上图iphone12&#xff0c;13PRo 以上图是没有带黑色扇帘的机型 以下是调试器看的wxml的代码展示 注意&#xff1a;红色阔里的是自定义导航&#xff08;或者其他的logo啊&#xff0c;返回之…...

Android Gradle自定义任务在打包任务执行完成后执行cmd命令

背景 在每次打包之后需要做某事&#xff0c;例如每次打包后我都会安装某个目录下的一个apk。这个apk是通过一堆shell命令过滤得到一个apk的地址&#xff0c;然后把执行的几个shell命令何必成一个alias指令&#xff0c;在打包后只需要执行alias指令实现功能。当然也可以直接写在…...

http自动发送请求工具(自动化测试http请求)

点击下载《http自动发送请求工具(自动化测试http请求)》 前言 在现代软件开发过程中&#xff0c;HTTP 请求的自动化测试是确保应用程序稳定性和可靠性的关键环节。为了满足这一需求&#xff0c;我开发了一款功能强大且易于使用的自动化 HTTP 请求发送工具。该工具基于 C# 开发…...

解决Docker环境变量的配置的通用方法

我们部署的很多服务都是以Docker容器的形式存在的。 在运行Docker容器前&#xff0c;除了设置网络、数据卷之外&#xff0c;还需要设置各种各样的环境变量。 有时候&#xff0c;由于容器版本的问题&#xff0c;一些文档没有及时更新&#xff0c;可能同时存在多个新旧版本的环…...

SpringBoot3整合Hutool-captcha实现图形验证码

文章目录 验证码需求分析:项目创建import方式的使用说明exclude方式定义接口:接口定义定义 CaptchaController前端代码在整合技术框架的时候,想找一个图形验证码相关的框架,看到很多验证码不在更新了或者是在中央仓库下载不下来,还需要多引入依赖。后面看到了Hutool **图形…...

Spring Boot核心概念:日志管理

日志记录是软件开发的重要组成部分&#xff0c;它帮助开发人员了解应用程序运行时的状态&#xff0c;以及在故障排查和性能监控时提供关键信息。Spring Boot通过提供默认的日志配置&#xff0c;简化了日志管理。 Spring Boot默认日志框架 Spring Boot默认使用Logback作为日志…...

selenium grid 远程webdriver添加上网代理

################## selenium grid config start ####################### # UI自动化测试策略 Grid/Local UIAutomation_TestStrategy Grid selenium_grid_url http://172.16.99.131:4444/wd/hub # Windows XP / linux grid_platformName linux # windows capabilities win…...

Flutter踩坑记录(一)debug运行生成的项目,不能手动点击运行

问题 IOS14设备&#xff0c;切后台划掉&#xff0c;二次启动崩溃。 原因 IOS14以上 flutter 不支持debugger模式下的二次启动 。 要二次启动需要以release方式编译工程安装至手机。 操作步骤 清理项目&#xff1a;在命令行中运行flutter clean来清理之前的构建文件。重新构…...

Spring Boot 项目 myblog 整理

myblog 项目是一个典型的 Spring Boot 项目&#xff0c;主要包括用户注册、登录、文章管理&#xff08;创建、查询、更新、删除&#xff09;等功能。 1. 项目结构与依赖设置 项目初始化与依赖 使用 Spring Initializr 创建项目。引入必要的依赖包&#xff1a; Spring Boot W…...

【前端知识】nodejs项目配置package.json深入解读

package.json详细解读 文件解读一、文件结构二、字段详解三、使用场景四、注意事项 组件版本匹配规则 文件解读 package.json 文件是 Node.js 项目中的一个核心配置文件&#xff0c;它位于项目的根目录下&#xff0c;并包含项目的基本信息、依赖关系、脚本、版本等内容。以下是…...

51c嵌入式~IO合集2

我自己的原文哦~ https://blog.51cto.com/whaosoft/11697814 一、STM32串口通信基本原理 通信接口背景知识 设备之间通信的方式 一般情况下&#xff0c;设备之间的通信方式可以分成并行通信和串行通信两种。并行与串行通信的区别如下表所示。 串行通信的分类 1、按照数据传…...

在应用启动时,使用 UniApp 提供的 API 检查和请求权限。

在使用 UniApp 开发 App 时&#xff0c;如果你需要在应用启动时提示用户获取本地媒体权限&#xff0c;可以按照以下步骤操作&#xff1a; 1. 明确需要的权限 要访问本地媒体&#xff08;如相机、麦克风或文件存储&#xff09;&#xff0c;需要申请以下权限&#xff1a; Andr…...

前端知识点---伪数组是什么 , 伪数组如何转换为真数组(Javascript)

伪数组是什么 , 伪数组如何转换为真数组(Javascript) 在 JavaScript 中&#xff0c;伪数组对象是具有类似数组特性的对象&#xff0c;但并不是数组&#xff08;即不继承 Array.prototype&#xff09;。这些对象通常有一个 length 属性以及以数字索引为键的属性&#xff0c;但不…...

嵌入式 UI 开发的开源项目推荐

嵌入式开发 UI 难吗&#xff1f;你的痛点我懂&#xff01;作为嵌入式开发者&#xff0c;你是否也有以下困扰&#xff1f;设备资源太少&#xff0c;功能和美观只能二选一&#xff1f;调试效率低&#xff0c;每次调整都要反复烧录和测试&#xff1f;开发周期太长&#xff0c;让你…...

《智能指针频繁创建销毁:程序性能的“隐形杀手”》

在 C编程的世界里&#xff0c;智能指针无疑是管理内存资源的得力助手。它们为我们自动处理内存的分配与释放&#xff0c;极大地减少了因手动管理内存而可能引发的诸如内存泄漏、悬空指针等棘手问题。然而&#xff0c;就像任何工具都有其两面性一样&#xff0c;智能指针在带来便…...

28.<Spring博客系统⑤(部署的整个过程(CentOS))>

引入依赖 Spring-boot-maven-plugin 用maven进行打包的时候必须用到这个插件。看看自己pom.xml中有没有这个插件 并且看看配置正确不正常。 注&#xff1a;我们这个项目打的jar包在30MB左右。 <plugin><groupId>org.springframework.boot</groupId><artif…...

mongodb多表查询,五个表查询

需求是这样的&#xff0c;而数据是从mysql导入进来的&#xff0c;由于mysql不支持数组类型的数据&#xff0c;所以有很多关联表。药剂里找药物&#xff0c;需要药剂与药物的关联表&#xff0c;然后再找药物表。从药物表里再找药物与成分关联表&#xff0c;最后再找成分表。 这里…...

服务器端渲染 (SSR) 与客户端渲染 (CSR)

嘿程序员&#xff01;我们都知道&#xff0c;新时代的 Javascript 已经彻底改变了现代网站的结构和用户体验。如今&#xff0c;网站的构建更像是一个应用程序&#xff0c;伪装成一个能够发送电子邮件、通知、聊天、购物、支付等的网站。今天的网站是如此先进、互动&#xff0c;…...

【已解决】“EndNote could not connect to the online sync service”问题的解决

本人不止一次在使用EndNote软件时遇到过“EndNote could not connect to the online sync service”这个问题。 过去遇到这个问题都是用这个方法来解决&#xff1a; 这个方法虽然能解决&#xff0c;但工程量太大&#xff0c;每次做完得歇半天身体才能缓过来。 后来再遇到该问…...

HTML5拖拽API学习 托拽排序和可托拽课程表

文章目录 前言拖拽API核心概念拖拽式使用流程例子注意事项综合例子&#x1f330; 可拖拽课程表拖拽排序 前言 前端拖拽功能让网页元素可以通过鼠标或触摸操作移动。HTML5 提供了标准的拖拽API&#xff0c;简化了拖放操作的实现。以下是拖拽API的基本使用指南&#xff1a; 拖拽…...

sed使用扩展正则表达式时, -i 要写在 -r 或 -E 的后面

sed使用扩展正则表达式时, -i 要写在 -r 或 -E 的后面 前言 -r 等效 -E , 启用扩展正则表达式 -E是新叫法,更统一,能增强可移植性 , 但老系统,比如 CentOS-7 的 sed 只能用 -r ### Ubuntu24.04-E, -r, --regexp-extendeduse extended regular expressions in the script(fo…...

CSS中Flex布局应用实践总结

① 两端对齐 比如 要求ul下的li每行四个&#xff0c;中间间隔但是需要两段对齐&#xff0c;如下图所示&#xff1a; 这是除了基本的flex布局外&#xff0c;还需要用到:nth-of-type伪类来控制每行第一个与第四个的padding。 .hl_list{width: 100%;display: flex;align-items…...

【前端】CSS修改div滚动条样式

示例 分别是滚动条默认样式和修改后的样式 代码 <div class"video-list"><div class"list-item" onclick"videoinfo(100)"><img src"/index/images/coverimg/方和谦.png"><div class"txt">国医大…...

鸿蒙多线程开发——线程间数据通信对象02

1、前 言 本文的讨论是接续鸿蒙多线程开发——线程间数据通信对象01的讨论。在上一篇文章中&#xff0c;我们讨论了常规的JS对象(普通JSON对象、Object、Map、Array等)、ArrayBuffer。其中讨论了ArrayBuffer的复制传输和转移传输方式。 下面&#xff0c;我们将讨论SharedArra…...

Kotlin的data class

在 Kotlin 中&#xff0c;data class 是一种专门用来存储数据的类。与普通类相比&#xff0c;data class 提供了简化数据存储的语法&#xff0c;并且自动生成了一些常用的方法&#xff0c;例如 toString()、equals()、hashCode() 和 copy()。 1. 定义 data class data class …...

Proxy 在 JavaScript的用法

Proxy 是 JavaScript 提供的一个构造函数,用于创建一个“代理对象”。这个代理对象可以拦截目标对象的基本操作,例如读取属性、赋值、删除、调用函数等。通过它,我们可以修改或扩展对象的默认行为。 Proxy 的基本语法 const proxy = new Proxy(target, handler);target:被…...

vue3的attr透传属性详解和使用法方式。以及在css样式的伪元素中实现

在 Vue 3 和 TypeScript 中&#xff0c;属性透传&#xff08;attr pass-through&#xff09;是指将组件的属性传递到其根元素或某个子元素中。这个概念在开发可复用的组件时非常有用&#xff0c;尤其是当你希望将父组件的属性动态地传递给子组件的某个 DOM 元素时。 在 Vue 3 …...

《人工智能深度学习的基本路线图》

《人工智能深度学习的基本路线图》 基础准备阶段 数学基础&#xff1a; 线性代数&#xff1a;深度学习中大量涉及矩阵运算、向量空间等概念&#xff0c;线性代数是理解和处理这些的基础。例如&#xff0c;神经网络中的权重矩阵、输入向量的运算等都依赖于线性代数知识。学习内容…...

Matlab 答题卡方案

在现代教育事业的飞速发展中&#xff0c;考试已经成为现代教育事业中最公平的方式方法&#xff0c;而且也是衡量教与学的唯一方法。通过考试成绩的好与坏&#xff0c;老师和家长可以分析出学生掌握的知识多少和学习情况。从而老师可以了解到自己教学中的不足来改进教学的方式方…...

[Unity]TileMap开发,TileMap地图缝隙问题

环境&#xff1a; windows11 unity 2021.3.14f1c1 tilemap使用的图是美术已经拼接到一起的整图&#xff0c;块与块之间没有留缝隙 问题&#xff1a; TileMap地图直接在Unity中使用时&#xff0c;格子边缘会出现缝隙&#xff0c;移动或缩放地图时较明显。 解决方案&#x…...