STM32F4_定时器输入捕获详解

news2024/9/26 1:29:04

目录

1. 输入捕获简介

2. 输入捕获框图

3. 输入捕获模式

4. 相关寄存器

4.1 TIMx_ARR、TIMx_PSC

4.2 捕获/比较寄存器1:TIMx_CCMR1

4.3 捕获/比较使能寄存器 TIMx_CCER

4.4 中断使能寄存器 TIMx_DIER

5. 库函数配置输入捕获高电平脉冲宽度

6. 实验程序

6.1 main.c

6.2 IntputCapture.c

6.3 IntputCapture.h


1. 输入捕获简介

        STM32定时器可以分为相关时钟、时基单元、输入捕获、输出比较。在上一节我们已经学习了STM32的输出PWM比较功能,本节我们将学习STM32的输入捕获功能

        输入捕获模式可以用来测量脉冲宽度或者测量频率。STM32F4系列拥有14个定时器,除了TIM6和TIM7,其他定时器都有输入捕获功能。

        输入捕获功能就是通过检测TIMx_CHx上的边沿信号,在边沿信号发生跳变(比如说上升沿/下降沿)的时候,将当前定时器的值TIMx_CNT存放到对应通道的捕获/比较寄存器TIMx_CCRx里面,完成一次捕获。同时还可以配置捕获时是否触发中断/DMA等。

2. 输入捕获框图

        输入捕获的过程:输入阶段对TIx输入进行采样,通过滤波器生成一个滤波信号TIxF,然后通过一个带有极性选择的边沿检测器(极性选择就是确定高电平有效还是低电平有效)生成一个信号(TIxFPx),信号一方面可以用作模式控制器的触发输入,另一方面可以捕获命令,通过分频器分频以后传给捕获/比较寄存器。

3. 输入捕获模式

        在输入捕获模式下,当相应的ICx信号( ICx称作输入捕获、OCx称作输出比较 )检测到跳变沿(上升沿、下降沿)后,将会使用TIMx_CCRx捕获/比较寄存器来存储这一时候计数器的值。发生捕获事件时,会将状态寄存器TIMx_SR的CCXIF位置1,并且这一时刻在使能的状态下可以发送中断或者DMA请求。如果发生捕获事件时CCxIF标志已经处于高位1,那么会将重复捕获标志状态寄存器的CCxOF位置1。可以通过写程序的方式给CCxIF位写入0来将CCxIF位清0,或者读取存储在TIMx_CCRx寄存器中的已捕获数据。

发生输入捕获时

        发生有效跳变沿时,TIMx_CCR1寄存器会获取计数器的值,保存下来。

        将CC1IF标志位置1。如果至少发生了两次连续捕获,但CC1IF标志未被清0,则CC1OF捕获溢出标志位会被置1。

        根据CC1IE位生成中断。

        根据CC1DE位生成DMA请求。

输入捕获测量脉宽的原理

        假定定时器工作在向上计数模式,图中的t1~t2时间,就是我们要测量的高电平时间;首先设置定时器通道x为上升沿捕获,这样在t1时刻会进行第一次捕获,记为CCRx1,记录当前计数器CNT的值;立即清0 CNT,设置定时器通道x为下降沿捕获,在t2时刻,会进行第二次捕获,记录这时的计数器值,记为CCRx2,这样,根据时钟值得到计数器的计数频率,就能算出t1~t2的时间,从而得到高电平脉宽。

        如图,在t1到t2之间,可能会产生N次定时器溢出,为了防止高电平太长,导致数据不准确,需要计算CNT计数的次数:N*ARR+CCRx2,用计数次数乘以CNT的计数周期,就可以得到t2~t1的时间长度。

4. 相关寄存器

4.1 TIMx_ARR、TIMx_PSC

这两个寄存器在过去学习定时器功能时,常常用到;分别是自动重装载值寄存器和时钟预分频寄存器。

4.2 捕获/比较寄存器1:TIMx_CCMR1

捕获/比较寄存器1:TIMx_CCMR1(capture/compare mode register 1)

在PWM输出中,已经介绍了该寄存器的输出位配置;这次我们着重看输入部分:也就是第二行ICxx;

第二行的输入部分的高8位是2通道IC2x;低8位是1通道IC1x;3 4通道显然是TIMx_CCMR2捕获/比较寄存器2控制的。

位1:0  捕获/比较1选择  00:CC1通道配置为输出    01:CC1通道配置为输入,IC1映射到TI1上 这里我们配置01,因为框图上通道1对应IC1

                                     10:CC1通道配置为输入,IC1映射到TI2上     11:CC1通道配置为输入,IC1映射到TRC上。

IC1PSC输入捕获1预分频器配置为 00:1次边沿就触发一次捕获。

IC1F是用来设置输入采样频率和数字滤波器长度的。

4.3 捕获/比较使能寄存器 TIMx_CCER

捕获/比较使能寄存器 TIMx_CCER(capture/compare enable register)

CC1P位配置为输入时,由输入捕获的框图可得:1通道CH1对应TI1,又对应TI1PF1/TI1PF2;配置极性就是高电平有效,还是低电平有效。

CC1E位配置为输入时,捕获/比较1输出使能。

4.4 中断使能寄存器 TIMx_DIER

中断使能寄存器 TIMx_DIER(DMA/Interrupt enable register)

位1 CC1IE: 捕获/比较1中断使能

                0:禁止CC1中断

                1:使能CC1中断

5. 库函数配置输入捕获高电平脉冲宽度

本程序获取TIM5的1通道上高电平脉冲宽度;

1. 开启TIM5时钟,配置PA0为复用功能(AF2),并开启下拉电阻

RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5,ENABLE);  //TIM5时钟使能 

GPIO_PinAFConfig(GPIOA,GPIO_PinSource0,GPIO_AF_TIM5); //GPIOA0复用位定时器5

…………………………………………………………………………

GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_DOWN;//下拉

GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF;//模式设置为复用模式

GPIO_Init(GPIOA,&GPIO_InitStructure);//GPIOA初始化

2. 初始化TIM5,设置TIM5的ARR和PSC

TIM_TimeBaseStructure.TIM_Prescaler=psc; //定时器分频 
TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up; //向上计数模式 
TIM_TimeBaseStructure.TIM_Period=arr; //自动重装载值 
TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1; 
TIM_TimeBaseInit(TIM5,&TIM_TimeBaseInitStructure);

3. 设置TIM5的输入捕获参数,开启输入捕获

定时器有输出比较函数,对应的就有输入捕获函数;

void TIM_ICInit(TIM_TypeDef* TIMx, TIM_ICInitTypeDef* TIM_ICInitStruct)   //  输入捕获初始化

typedef struct 
{  
uint16_t TIM_Channel; //通道  有1 2 3 4 通道供选择
uint16_t TIM_ICPolarity; //捕获极性  有上升沿捕获和下降沿捕获选择
uint16_t TIM_ICSelection;//映射  //每一个通道都对应一个映射关系,1通道对应映射TI1
uint16_t TIM_ICPrescaler;//分频系数  有0 2 4 8供选择
uint16_t TIM_ICFilter; //滤波器长度 不使用滤波器,默认选择滤波器长度为0
} TIM_ICInitTypeDef; 


对于第二个结构体成员变量:捕获极性  有单独的
TIM_OC1PolarityConfig(TIM5,TIM_ICPolarity_Falling);//通道1捕获极性函数

有TIM_OCxPolarityConfig()。x对应2 3 4 通道选择。

ag. 

TIM5_ICInitStructure.TIM_Channel = TIM_Channel_1; //选择输入端 IC1映射到TI1上  
TIM5_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising; //上升沿捕获  
TIM5_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; //映射到TI1上  
TIM5_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1; //配置输入分频,不分频  
TIM5_ICInitStructure.TIM_ICFilter = 0x00;//IC1F=0000 配置输入滤波器 不滤波  
TIM_ICInit(TIM5, &TIM5_ICInitStructure); 

4. 使能捕获和更新中断(设置TIM5的DIER寄存器)

TIM_ITConfig( TIM5,TIM_IT_Update|TIM_IT_CC1,ENABLE);//允许更新中断和捕获中断 

此时开启中断,我们需要在中断中设置:因为此程序是捕获高电平信号的脉宽,所以第一次捕获的是上升沿,第二次是下降沿,这两个时间间隔内就是一个高电平信号。

同时脉宽比较长,就会导致定时器溢出,需要在中断中对溢出进行处理。

5. 设置中断优先级,编写中断服务函数

NVIC_Init();

中断服务函数:需要完成数据处理和捕获设置等关键操作。    TIM5_IRQHandler

        在中断开始的时候需要进行中断类型的判断,中断结束时要清除中断标志位。

if (TIM_GetITStatus(TIM5, TIM_IT_Update) != RESET){}//判断是否为更新中断 

if (TIM_GetITStatus(TIM5, TIM_IT_CC1) != RESET){}//判断是否发生捕获事件 

TIM_ClearITPendingBit(TIM5, TIM_IT_CC1|TIM_IT_Update);//清除中断和捕获标志位

TIM_SetCounter(TIM5,0); //设置计数器的值  将TIM5的计数值设置为0

6. 使能定时器

TIM_Cmd(TIM5,ENABLE ); //使能定时器5 

最后因为用到了串口输出结果,所以还需要配置一下串口

6. 实验程序

本实验程序通过输入捕获TIM5_CH1(PA0)上面的高电平脉冲宽度,并从串口打印捕获结果。

注意:

        该程序中的TIM5CH1_CAPTURE_STA是一个状态位,前6位表示捕获高电平后定时器溢出的次数;第七位是捕获到高电平的标志;第八位是捕获完成的标志。TIM5CH1_CAPTURE_VAL用来记录捕获到下降沿时CNT计数器的值,因为该程序是捕获高电平脉冲宽度,每当捕获到下降沿的时候,就意味着捕获到了一个高电平脉冲信号。因为一个高电平是由一个上升沿和一个下降沿组成的。

6.1 main.c

#include "stm32f4xx.h"
#include "delay.h"
#include "LED.h"
#include "BEEP.h"
#include "Key.h"
#include "usart.h"
#include "exti.h"
#include "iwdg.h"
#include "wwdg.h"
#include "Timer.h"
#include "pwm.h"
#include "IntputCapture.h"

extern u8 TIM5_CH1_CAPTURE_STA;//外部声明
//该程序中的TIM5CH1_CAPTURE_STA是一个状态位,前6位表示捕获高电平后定时器溢出的次数;第七位是捕获到高电平的标志;第八位是捕获完成的标志。
extern u32 TIM5_CH1_CAPTURE_VAL;
//TIM5CH1_CAPTURE_VAL用来记录捕获到下降沿时CNT计数器的值


int main(void)
{
	long long Temp=0; //Temp表示溢出的次数,对于溢出我们这样理解的,因为计数器的重装载值是固定设置的,如果频率过快,可能在一次高电平期间,会溢出多次,因此我们需要记录溢出的次数
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//中断优先级分组
	delay_init(168);
	uart_init(115200);
	TIM14_Init(500-1,84-1);
	TIM5_CH1_InterCapture_Init(0xFFFFFFFF,84-1); //自动重装载值为最大  84/84M=1M,频率为1Mhz
	while(1)
	{
		delay_ms(10);
		TIM_SetCompare1(TIM14,TIM_GetCapture1(TIM14)+1);//设置占空比,占空比是TIM14输出比较来的
		if(TIM_GetCapture1(TIM14)==300)//占空比达到顶峰
			TIM_SetCompare1(TIM14,0);//清空TIM14定时器
		if(TIM5_CH1_CAPTURE_STA&0x80)//成功捕获一次高电平
		{
			Temp=TIM5_CH1_CAPTURE_STA&0x3F;//低6位的值给到Temp  循环次数
			Temp*=0xFFFFFFFF;  //溢出时间总和  循环次数乘以最大重装载值(最大重装载值就是一个周期的计数器值)就是循环这么多次的时间
			Temp=Temp+TIM5_CH1_CAPTURE_VAL; //总的高电平时间 TIM5_CH1_CAPTURE_VAL表示最后一次检测到低电平时的计数器值
			printf("HIGH:%lld us\r\n",Temp);//打印总的高电平时间
			TIM5_CH1_CAPTURE_STA=0; //开启下一次捕获
		}
	}
	
}


6.2 IntputCapture.c

#include "stm32f4xx.h"                  
#include "IntputCapture.h"

//AutomaticReload:自动重装载值    PrioritySendCount:时钟预分频数

void TIM14_Init(u32 AutomaticReload,u32 PrioritySendCount)
{
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM14,ENABLE);//使能TIM14_CH1 1通道时钟
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF,ENABLE);// 使能GPIOF引脚
	GPIO_PinAFConfig(GPIOF,GPIO_PinSource9,GPIO_AF_TIM14);//引脚复用PF9引脚复用为TIM14的通道1
	//GPIO的初始化函数,设置初始化的模式为复用
	
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF; //设置GPIO模式为复用  对应上述引脚复用PF9引脚复用为TIM14的通道1
	GPIO_InitStructure.GPIO_OType=GPIO_OType_PP;
	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_9; 
	GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_UP;
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_100MHz;
	GPIO_Init(GPIOF,&GPIO_InitStructure);
	
	//初始化TIM14定时器,设置预分频值和自动重装载值
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
	TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1;
	TIM_TimeBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up;//向上计数,也就是递增计数
	TIM_TimeBaseInitStructure.TIM_Period=AutomaticReload;//自动重装载值
	TIM_TimeBaseInitStructure.TIM_Prescaler=PrioritySendCount;//时钟预分频值
	TIM_TimeBaseInit(TIM14,&TIM_TimeBaseInitStructure);
	
	
	//设置TIM14的PWM模式
	TIM_OCInitTypeDef TIM_OCInitStructure;
	TIM_OCInitStructure.TIM_OCPolarity=TIM_OCPolarity_Low;//输出极性低,也就意味着占空比中低电平有效
	TIM_OCInitStructure.TIM_OCMode=TIM_OCMode_PWM1;//PWM调质模式1
	TIM_OCInitStructure.TIM_OutputState=TIM_OutputState_Enable;//输出比较使能
	TIM_OCInitStructure.TIM_Pulse=0;
	TIM_OC1Init(TIM14,&TIM_OCInitStructure);//初始化TIM14通道1
	
	TIM_OC2PreloadConfig(TIM14,TIM_OCPreload_Enable);//使能TIM14在CCR2上的预装载寄存器
	TIM_ARRPreloadConfig(TIM14,ENABLE);//使能自动重装载寄存器
	
	TIM_Cmd(TIM14,ENABLE);//使能TIM14
}
//AutomationReload:自动重装值(TIM2,TIM5的自动重装载值是32位的)   PrioritySendCount:时钟预分频数

void TIM5_CH1_InterCapture_Init(u32 AutomationReload,u16 PrioritySendCount)
{
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5,ENABLE);//TIM5时钟使能
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE);//使能GPIOA
	GPIO_PinAFConfig(GPIOA,GPIO_PinSource0,GPIO_AF_TIM5);//PA0复用为TIM5
	
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF;
	GPIO_InitStructure.GPIO_OType=GPIO_OType_PP;
	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0;
	GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_DOWN; //引脚设置为下拉,因为PA0对应KEY_UP按键,KEY_UP按键左侧接V3.3
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_100MHz;
	GPIO_Init(GPIOA,&GPIO_InitStructure);//GPIOA初始化
	
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
	TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1;
	TIM_TimeBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up;//向上计数模式
	TIM_TimeBaseInitStructure.TIM_Period=AutomationReload;
	TIM_TimeBaseInitStructure.TIM_Prescaler=PrioritySendCount;
	TIM_TimeBaseInit(TIM5,&TIM_TimeBaseInitStructure);
	
	TIM_ICInitTypeDef TIM_ICInitStructure;
	TIM_ICInitStructure.TIM_Channel=TIM_Channel_1;//映射通道1上
	TIM_ICInitStructure.TIM_ICFilter=0x00;//不滤波
	TIM_ICInitStructure.TIM_ICPolarity=TIM_ICPolarity_Rising;//上升沿捕获
	TIM_ICInitStructure.TIM_ICPrescaler=TIM_ICPSC_DIV1;//配置输入不分频
	TIM_ICInitStructure.TIM_ICSelection=TIM_ICSelection_DirectTI;//映射到TI1上,也就是TIM5通道1
	TIM_ICInit(TIM5,&TIM_ICInitStructure);//初始化TIM5输入捕获
	
	TIM_ITConfig(TIM5,TIM_IT_Update|TIM_IT_CC1,ENABLE);//使能捕获和更新中断
	
	NVIC_InitTypeDef NVIC_InitStructure;
	NVIC_InitStructure.NVIC_IRQChannel=TIM5_IRQn;//TIM5通道
	NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;//使能中断优先级
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=2;//抢占优先级2
	NVIC_InitStructure.NVIC_IRQChannelSubPriority=0;//响应优先级0
	NVIC_Init(&NVIC_InitStructure);//初始化NVIC
	
	TIM_Cmd(TIM5,ENABLE);//使能定时器5
}
//捕获状态位
//位7:0 还没成功捕获  1  成功捕获到一次
//位6:0 还没有捕获到低电平  1  成功捕获到一次低电平
//位5:0  捕获低电平后溢出的次数,当达到最高的溢出次数时,标记成功捕获一次
//这里需要注意,之所以设置低电平捕获状态和溢出次数,是因为初始化TIM5的时候设置的是上升沿捕获,那么就意味着初始化时上升沿就会进行一次捕获,想要获得高电平的持续时间,就要在中断中获得捕获低电平时的计数器值

u8 TIM5_CH1_CAPTURE_STA=0;//定义全局变量输入捕获的状态
u32 TIM5_CH1_CAPTURE_VAL;//输入捕获的值(注意TIM2/TIM5的输入捕获值是32位的)

void TIM5_IRQHandler(void)//两种情况 一种是溢出次数也就是循环了多少次,另一种是发生捕获也就是最后一次的时间,两个相加才是总的时间
//这个也比较好理解,因为我们不确定在我们捕获的低电平是第一次低电平,还是第n次低电平;
//如果只是单纯的记录低电平的计数器值,可能要比实际的高电平时间要小很多,因为中间掺杂着多个周期,我们都没有记录在内
{
	if((TIM5_CH1_CAPTURE_STA&0x80)==0)//输入捕获状态位的最高位为0,还未成功捕获
	{
		if(TIM_GetITStatus(TIM5,TIM_IT_Update)!=RESET)//判断是否为更新中断,溢出
		{
			if(TIM5_CH1_CAPTURE_STA&0x40)//已经捕获到高电平了
			{
				if((TIM5_CH1_CAPTURE_STA&0x3F)==0x3F)//低6位为1,表示溢出的次数达到了最高,默认标记成功捕获一次
				{
					TIM5_CH1_CAPTURE_STA=TIM5_CH1_CAPTURE_STA|0X80;//状态位的最高位置1,表示已经成功捕获了一次
					TIM5_CH1_CAPTURE_VAL=0xFFFFFFFF;//捕获值达到最高
				}
				else   //不是因为溢出次数达到顶峰而标记捕获,则捕获状态++;
					TIM5_CH1_CAPTURE_STA++;
			}
		}
		if(TIM_GetITStatus(TIM5,TIM_IT_CC1)!=RESET)//捕获1发生捕获事件
		{
			if(TIM5_CH1_CAPTURE_STA&0x40)//捕获一个下降沿,一次捕获已经结束了,我需要做以下几件事:
				//标记状态位的最高位为1,表明成功捕获一次,将捕获到的值给到全局变量VAL,
			//因为要捕获高电平的频率,所以先设置上升沿捕获,在设置下降沿捕获,这样一来,一个上升沿一个下降沿就会得到一个完整的高电平频率
			{
				TIM5_CH1_CAPTURE_STA|=0x80;//状态最高位置1,表示成功捕获一次
				TIM5_CH1_CAPTURE_VAL=TIM_GetCapture1(TIM5);//获取捕获值给到全局变量
				TIM_OC1PolarityConfig(TIM5,TIM_ICPolarity_Rising);//设置上升沿捕获
			}
			else //否则意味着还没有捕获到下降沿
			{
				TIM5_CH1_CAPTURE_STA=0;//清空
				TIM5_CH1_CAPTURE_VAL=0;
				TIM5_CH1_CAPTURE_STA|=0x40;//标记捕获到了一个上升沿
				TIM_Cmd(TIM5,ENABLE);//使能定时器5
				TIM_SetCounter(TIM5,0);//将定时器5清空
				TIM_OC1PolarityConfig(TIM5,TIM_ICPolarity_Falling);//设置下降沿捕获
				TIM_Cmd(TIM5,ENABLE);//使能定时器5
			}
		}
	}
	TIM_ClearITPendingBit(TIM5,TIM_IT_CC1|TIM_IT_Update);//清除中断标志位
}


6.3 IntputCapture.h

#ifndef _INTPUTCAPTURE__H_
#define _INTPUTCAPTURE__H_

void TIM14_Init(u32 AutomaticReload,u32 PrioritySendCount);
void TIM5_CH1_InterCapture_Init(u32 AutomationReload,u16 PrioritySendCount);
void TIM5_IRQHandler(void);

#endif

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

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

相关文章

【4.14】今天讲两道TCP面试题

文章目录TCP Keepalive 和HTTP Keep-Alive是一个东西吗?TCP协议有什么缺陷TCP Keepalive 和HTTP Keep-Alive是一个东西吗? 对于这个问题,我们要先知道这两个KeepAlive分别代表什么? TCP的Keepalive是由TCP层(内核层&a…

移远通信率先通过ISO/SAE 21434汽车网络安全管理体系认证

近日,移远通信车载前装BU获得了由国际独立第三方检测、检验和认证机构TV NORD颁发的ISO/SAE 21434汽车网络安全管理体系认证证书。 ISO/SAE 21434标准认证的通过,表明移远通信车载前装BU的网络安全风险管理满足了产品从概念设计、开发、生产、运营到售后…

我的面试八股(数据库)

数据库范式? 数据库范式有三种 1NF 第一范式,属性(对应表中的字段)不能再分割,就是这个字段只能是一个值,不能再分为多个其它字段了,1NF是所有关系型数据库的最基本要求。 2NF 第二范式&am…

Spring Security 02 搭建环境

搭建环境 导入依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency><groupId>org.springframework.boot</groupId><artifa…

第31天-贪心-第八章 ● 122.买卖股票的最佳时机II ● 55. 跳跃游戏 ● 45.跳跃游戏II

文章目录1. 买卖股票的最佳时机2. 跳跃游戏3. 跳跃游戏 ||1. 买卖股票的最佳时机 - LeetCode链接 给你一个整数数组 prices &#xff0c;其中 prices[i] 表示某支股票第 i 天的价格。 在每一天&#xff0c;你可以决定是否购买和/或出售股票。你在任何时候 最多 只能持有 一股 …

docker安装jenkins安装流程(一)

1.下载安装jdk 官网&#xff1a;https://jdk.java.net/ https://www.oracle.com/java/technologies/downloads/ 上传到linux服务器 cd /usr mkdir jdk tar -zxvf 所要解压的文件名 编辑profile文件&#xff1a;vim /etc/profile 把光标移到最后一行&#xff0c;键盘按 i&…

技术分享 | 如何优雅的删除 Zabbix 的 history 相关历史大表

作者&#xff1a;徐文梁 爱可生DBA成员&#xff0c;一个执着于技术的数据库工程师&#xff0c;主要负责数据库日常运维工作。擅长MySQL,redis&#xff0c;其他常见数据库也有涉猎&#xff0c;喜欢垂钓&#xff0c;看书&#xff0c;看风景&#xff0c;结交新朋友。 本文来源&…

Vue动图数据表格,根据字段是否为空,控制表格列的隐藏和显示

所在前面的话&#xff0c;我是个前端小白&#xff0c;大佬请绕行&#xff0c;可能大佬觉得很简单&#xff0c;但是我真的花了好几个小时去解决&#xff0c;所以记录一下&#xff0c;下次也可以作为参考。 我主要是以第二种方式进行修改的 开门见山 简述问题&#xff1a;大家…

《这就是软件工程师》- 每位软件工程师值的看的一本书,尤其是刚刚步入IT行业的年轻人

文章目录第一部分&#xff5c;行业地图1、现实&#xff1a;为什么会有996&#xff1f;1&#xff09;行业处于特定的发展阶段2&#xff09;公司组织管理问题2、进阶&#xff1a;软件工程师的四大台阶1&#xff09;新手阶段【执行力】2&#xff09;进阶阶段【设计能力】3&#xf…

电子行业数字化工厂的发展现状如何

随着科技的不断发展&#xff0c;电子行业的生产制造方式也在不断地进步。数字化工厂建设是电子行业中的一个重要发展方向&#xff0c;它可以提高生产效率&#xff0c;降低生产成本&#xff0c;提高产品质量&#xff0c;减少人力资源的使用。本文将从数字化工厂的概念、发展历程…

Zookeeper总结

目录 1、概念 2、什么是Zookeeper 3、如何下载 4、部署运行 4.1、解压文件 4.2、修改配置文件 4.3、创建持久化目录 4.4、配置jdk 4.5、启动zookeeper服务 4.6、查看zookeeper运行状态 5、系统模型 5.1、数据模型&#xff08;文件系统&#xff09; 5.2、znode节点类型 持久…

Google FLASH-QUAD Transformer模型的设计雷点

这个模型用来做无序弱监督分类&#xff0c;效果好&#xff0c;特别是收敛速度比标准多头Attention层快多了&#xff0c;完全没得比。 问题1 但这模型我用来做自回归生成&#xff0c;非常垃圾。 同时尝试了 GPT 和 T5 这两种模型结构的设计&#xff0c;明明Loss正常下降&#…

环境变量相关知识

目录 目录 谢谢你的阅读&#xff0c;这是对我最大的鼓舞 先说结论&#xff1a; 开始论述&#xff1a; 让我们举个例子 相关指令 创建本地变量 创建环境变量 方法一&#xff1a; 方法二&#xff1a; 删除环境变量 子进程中也有环境变量 第一种&#xff1a; 第二种 …

【PlumGPT】与PlumGPT开启智能对话之旅

文章目录 一、前言二、PlumGPT介绍篇三、PlumGPT登录篇四、PlumGPT体验篇1、与PlumGPT聊天2、让PlumGPT翻译3、让PlumGPT创作4、请PlumGPT写推荐信5、让PlumGPT展示图片6、让PlumGPT充当百科小助手 五、PlumGPT总结篇 PlumGPT入口体验链接&#xff1a;https://plumgpt.com 一、…

【Kubernetes】 故障转移和自愈能力机制详解

文章目录一. 引言1. 介绍Kubernetes2. 故障转移和自愈能力的重要性二. Kubernetes 概览1. Kubernetes 架构2. Kubernetes 组件和功能三. 故障转移1. 如何定义故障转移2. Kubernetes 中的故障转移机制2.1 健康检查2.2 Pod 和 ReplicaSet2.3 控制器和故障转移3. Pods和ReplicaSet…

LS1028+TSN+Vxworks实时系统解决方案

TSN&#xff08;时间敏感网络&#xff09;正在各类市场兴起。它可以为过去不曾存在的全新应用提供实时通信。 例如&#xff0c;将控制功能从驱动中解耦出来并移至边缘计算。下一代自动控制器可以并行处理视频流和控制流等各种工作负载&#xff0c;在一台机器上运行全部深度学习…

【高危】Google Chrome V8 类型混淆漏洞(CVE-2023-2033)

漏洞描述 Google Chrome V8是Google开源的JavaScript和WebAssembly引擎&#xff0c;被用在Chrome和Node.js等浏览器和平台中。 该项目受影响版本存在类型混淆漏洞&#xff0c;攻击者可通过诱导用户打开恶意链接来触发此漏洞&#xff0c;可能导致浏览器崩溃或执行任意代码。由…

跟姥爷深度学习2 TensorFlow的基本用法

一、前言 前面我们浅用TensorFlow做了个天气预测&#xff0c;虽然效果不咋样&#xff0c;但算是将整个流程跑通了。这一篇我们在之前基础上对TensorFlow的一些参数进行简单介绍&#xff0c;在接口文件的基础上了解各参数的简单含义和用法。 二、再次构建模型 我们先将之前的…

基于组合双向拍卖的共享储能机制研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

规模化敏捷框架之LeSS

Scrum 是目前比较流行的敏捷框架&#xff0c;Scrum 敏捷开发团队由产品负责人&#xff08;Product Owner&#xff09;、敏捷教练&#xff08;Scrum Master&#xff09;、软件开发人员和其他合作人员组成。团队在这个指导框架下协同工作、开发、创造和交付有价值的产品来解决复杂…