【STM32】EXTI外部中断

1 中断系统

1.1 中断简介

中断:在主程序运行过程中,出现了特定的中断触发条件(中断源),使得CPU暂停当前正在运行的程序,转而去处理中断程序,处理完成后又返回原来被暂停的位置继续运行。

比如:对于外部中断而言,可以是引脚电平发生跳变;对于定时器而言,可以是定时事件到了。对于串口通信而言,可以是接收到了数据。

中断优先级:当有多个中断源同时申请中断时,CPU会根据中断源的轻重缓急进行裁决,优先响应更加紧急的中断源。(自己设置的)

中断嵌套:当一个中断程序正在运行时,又有新的更高优先级的中断源申请中断,CPU再次暂停当前中断程序,转而去处理新的中断程序,处理完成后依次进行返回。

1.2 中断流程图

程序由硬件电路自动跳转到中断程序。

保存现场,还原现场(使用C语言编程不用我们考虑,操作系统做)

正常情况下,程序在主函数中执行,当中断条件满足时,主程序会暂停,然后自动跳转到中断程序;当中断程序执行完后,再返回主程序继续执行。一般中断程序都是在一个子函数的,这个函数不需要我们调用,当中断来临时,由硬件自动调用这个函数。

1.3 STM32的中断

68个可屏蔽中断通道,包含EXTITIMADCUSARTSPII2CRTC等多个外设。

中断通道就是中断源的意思

EXTI:外部中断

TIM:定时器

ADC:模数转换器

USART:串口

SPI通信

I2C通信

RTC实时时钟

使用NVIC统一管理中断,每个中断通道都拥有16个可编程的优先等级,可对优先级进行分组,进一步设置抢占优先级和响应优先级

灰色的是内核中断。比如第一个:复位中断,当产生复位中断时,程序就会自动执行复位中断函数。

外部中断对应的中断资源

613可设置EXTI0EXTI线0中断0x0000_0058
714可设置EXTI1EXTI线1中断0x0000_005C
815可设置EXTI2EXTI线2中断0x0000_0060
916可设置EXTI3EXTI线3中断0x0000_0064
1017可设置EXTI4EXTI线4中断0x0000_0068
2330可设置EXTI9_5EXTI线[9:5]中断0x0000_009C
4047可设置EXTI15_10EXTI线[15:10]中断0x0000_00E0

最右边是地址,因为中断函数的地址由编译器来分配的,它是不固定的,但是中断跳转,由于硬件的限制,只能跳转到固定的地址执行程序,所以为了能让硬件跳转到一个不固定的中断函数中,这里需要在内存中定义一个地址的列表,这个列表地址是固定的,中断发生后,就跳转到这个固定的位置。然后这个固定位置由编译器,再加上一条跳转 到中断函数的代码,这样中断跳转就可以跳转到任意位置了。这个中断地址的列表就叫中断向量表。(相当于中断跳转的跳板,使用C语言编程不需要关心)

1.4 NVIC的基本结构

NVIC:Nest Vector Interrupt Controller,嵌套中断向量控制器,是用来管理中断嵌套的,核心任务在于其优先级的管理。NVIC给每个中断赋予先占优先级(抢占优先级)和次占优先级(响应优先级)。

NVIC是内核外设,是CPU的小助手。

一个外设可能会同时占用多个中断通道,所以有n条线。

NVIC只有一个输出口,NVIC根据每个中断的优先级分配中断的先后顺序,之后通过一个输出口告诉CPU该处理哪个中断(医生-CPU,叫号系统-NVIC)

1.5 NVIC优先级分组

NVIC的中断优先级由优先级寄存器的4位(0~15)决定,这4位可以进行切分,分为:

高n位的抢占优先级低4-n位的响应优先级(插队)

抢占优先级高的可以中断嵌套响应优先级高的可以优先排队(插队)抢占优先级和响应优先级均相同的按中断号排队

分组方式

抢占优先级

响应优先级

分组0

0位,取值为0

4位,取值为0~15

分组1

1位,取值为0~1

3位,取值为0~7

分组2

2位,取值为0~3

2位,取值为0~3

分组3

3位,取值为0~7

1位,取值为0~1

分组4

4位,取值为0~15

0位,取值为0

值越小,优先级越高,0是最高优先级。

分组0就是0位的抢占等级,取值只能是0;4位的响应等级,取值可以是0-15;

分组1就是1位的抢占等级,取值可以是0-1;3位的响应等级,取值可以是0-7;

分组2就是2位的抢占等级,取值可以是0-3;2位的响应等级,取值可以是0-3;

分组3就是3位的抢占等级,取值可以是0-7;1位的响应等级,取值可以是0-1;

分组4就是4位的抢占等级,取值可以是0-15;0位的响应等级,取值只能是0;

数值小的优先响应。

1.6 EXTI外部中断

  1. EXTI(Extern Interrupt)外部中断;
  2. EXTI可以监测指定GPIO口的电平信号,当其指定的GPIO口产生电平变化时,EXTI将立即向NVIC发出中断申请,经过NVIC裁决后即可中断CPU主程序,使CPU执行EXTI对应的中断程序;
  3. 支持的触发方式:上升沿(低->高)/下降沿/双边沿/软件触发;
  4. 支持的GPIO口:所有GPIO口,但相同的Pin不能同时触发中断(PA0和PB0不能同时用);
  5. 通道数:16GPIO_Pin(0-15),外加PVD输出、RTC闹钟、USB唤醒、以太网唤醒;
  6. 触发响应方式:中断响应/事件响应。

中断响应:申请中断,让CPU执行中断函数;

事件响应:STM32对外部中断新增的额外功能;当外部中断检测到引脚电平变化时,正常的流程是选择触发中断,但是在STM32中也可以选择触发一个事件。如果选择触发事件,那外部的中断信号就不会通向CPU了,而是通向其他外设,用来触发其他外设的操作,比如触发ADC转换,触发DMA等。

总结:中断响应是正常的流程,引脚电平变化触发中断

事件响应不会触发中断,而是触发别的外设操作,属于外设间的联合工作

外部中断有个功能,就是从低功耗模式的停止模式下唤醒STM32;对于PVD电压电压检测,当电源从电压过低恢复时,就需要PVD借助外部中断退出停止模式;对于RTC闹钟而言,有时候为了省电,RTC定一个闹钟之后,STM32会进入停止等待模式,等到闹钟响的时候再唤醒,这也需要借助外部中断。

1.7 EXTI的基本结构

最左边是GPIO口的外设(GPIOA等,每个GPIO有16个引脚),前面介绍了EXTI模块只有16个GPIO的通道,但是这里每个GPIO都有16个引脚,如果每个引脚占用一个通道,那EXTI的16个通道显然就不够用了,所以在这里,会有一个AFIO中断引脚选择的电路模块,AFIO是一个数据选择器,它可以在这前面3个GPIO外设的16个引脚里选择其中一个连接到
后面EXTI的通道里,所以说相同的Pin不能同时触发中断(PA0和PB0不能同时用),然后通过AFIO选择之后的16个通道,就接到了EXTI边沿检测及控制电路上。同时下面PVD、RTC、USB、ETH外设也是并列进来的,加起来就组成了EXTI的20个输入信号。然后进过EXTI电路之后,分为两种输出,上面的接到了NVIC,是用来触发中断的(外部中断的EXTI9-5会触发同一个中断函数,EXTI15-10会触发同一个中断函数,编程的时候,需要再根据标志位区分到底是哪个中断进来的

疑问:为什么不是5-9,10-15呢

答:数字越小,优先级越高,排在后面?

下面的20条输出线路到了其他外设,这是用来触发其他外设操作的(事件响应)。

1.8 AFIO复用IO口

AFIO主要用于引脚复用功能的选择和重定义(数据选择器)

在STM32中,AFIO主要完成两个任务:复用功能引脚重映射中断引脚选择

一系列的数据选择器。

1.9 EXTI框图

右下角是输入线,进入边沿检测电路,在上面的上升沿触发选择寄存器和下降沿触发选择寄存器选择是上升沿触发还是下降沿触发,还是都触发。接着进入或门输出端,引脚触发和软件中断读接到这个或门上。触发信号通过或门之后,兵分两路,上一路是触发中断的,下一路是触发事件的。

触发中断首先会置一个挂起寄存器,相当于中断标志位,读取这个寄存器判断是哪个通道出发的中断;如果中断寄存器置1,它就会继续向左走,和中断屏蔽寄存器共同进入一个与门(中断屏蔽寄存器置1,另一个直接输出,即允许中断。中断屏蔽寄存器置0则相反,即屏蔽中断),然后至NVIC中断控制器。

接下来是事件的输出部分,与事件屏蔽寄存器进入到与门,实现开关控制,最后通过一个脉冲发生器到其他外设。

2 硬件电路

使用外部中断的特性:对于STM32而言,想要获取的信号是外部驱动很快的突发信号,比如旋转编码器的输出信号,可能很久不拧它,此时不需要STM32做任何事;但是一拧它,就会有很多脉冲波形需要STM32接收,信号是突发的,STM32不知道什么时候会来;同时它是外部驱动的,STM32只能被动读取。最后,这个信号非常快,STM32稍微晚一点来读取就会错过很多波形。有脉冲过来,STM32立即进入到中断函数处理。

还有比如:红外遥控接收头的输出

不推荐读取按键,无法处理抖动,可以在主循环中读取及定时器读取。

2.1 旋转编码器简介

旋转编码器:用来测量位置、速度或旋转方向的装置,当其旋转轴旋转时,其输出端可以输出与旋转速度和方向对应的方波信号,读取方波信号的频率和相位信息即可得知旋转轴的速度和方向。

类型:机械触点式/霍尔传感器式/光栅式

当光栅编码盘转动时,传感器的激光就会出现遮挡、透过、遮挡、透过的现象,输出的电平是高低电平交替的方波。方波的个数代表转过的角度,方波的频率表示转速。不过这个模块只有一路输出,正转和反转波形无法区分,所以这种测速方式只能测位置和速度,不能测旋转方向。

拆解

左右是两部分开关触点,内测的两个细的触点都是和中间引脚相连,外侧的左边接A,右边接B。金属盘是设计好的,让两侧触点的通断产生一个90°的相位差,最终配合外部电路,这个编码器的两个输出就会输出这样的波形。正转时(B相滞后90°,反向旋转时,B相超前90°)就可以测方向了:

2.2 硬件电路

先看左边电路,接了一个10K的上拉电阻,默认没有旋转的情况下,这个点被上拉为高电平,通过R3电阻,输出的也是高电平。

当旋转时,内部触点导通,这个点就被拉倒GND了,再通过A端口输出就是低电平了

R3限流电阻,防止模块引脚电流过大,C1是滤波电容,防止输出抖动信号。

右边一样,中间C接到GND。

2.3 手册

NVIC是内核外设,所以在《STM32F10xxx Cortex-M3编程手册》(内核相关的)查找

中断分组配置

中文版《Cortex-M3权威指南》

中断介绍-《STM32F10xxx参考手册(中文)》

AFIO外设

3 EXTI外部中断之对射式红外传感器计次

3.1 接线图

3.2 封装模块

按这个图来配置

AFIO的配置函数。数据选择器输入为GPIOB的14号引脚,输出端固定连接的是EXTI14

// 在GPIO库文件中
void GPIO_EXTILineConfig(uint8_t GPIO_PortSource, uint8_t GPIO_PinSource);/*** @brief  Selects the GPIO pin used as EXTI Line.* @param  GPIO_PortSource: selects the GPIO port to be used as source for EXTI lines.*   This parameter can be GPIO_PortSourceGPIOx where x can be (A..G).* @param  GPIO_PinSource: specifies the EXTI line to be configured.*   This parameter can be GPIO_PinSourcex where x can be (0..15).* @retval None*/
void GPIO_EXTILineConfig(uint8_t GPIO_PortSource, uint8_t GPIO_PinSource)
{uint32_t tmp = 0x00;/* Check the parameters */assert_param(IS_GPIO_EXTI_PORT_SOURCE(GPIO_PortSource));assert_param(IS_GPIO_PIN_SOURCE(GPIO_PinSource));tmp = ((uint32_t)0x0F) << (0x04 * (GPIO_PinSource & (uint8_t)0x03));AFIO->EXTICR[GPIO_PinSource >> 0x02] &= ~tmp;AFIO->EXTICR[GPIO_PinSource >> 0x02] |= (((uint32_t)GPIO_PortSource) << (0x04 * (GPIO_PinSource & (uint8_t)0x03)));
}

配置EXTI,选择边沿触发方式(上升沿/下降沿/双边沿),选择响应方式(中断/事件)

void EXTI_DeInit(void);                                        // 复位
void EXTI_Init(EXTI_InitTypeDef* EXTI_InitStruct);             // 初始化
void EXTI_StructInit(EXTI_InitTypeDef* EXTI_InitStruct);       // 结构体初始化
void EXTI_GenerateSWInterrupt(uint32_t EXTI_Line);             // 软件触发外部中断// 在主函数中查看和清除标志位
FlagStatus EXTI_GetFlagStatus(uint32_t EXTI_Line);             // 获取指定的标志位是否被置1
void EXTI_ClearFlag(uint32_t EXTI_Line);                       // 对置1的标志位清除// 在中断函数中查看和清除标志位
ITStatus EXTI_GetITStatus(uint32_t EXTI_Line);
void EXTI_ClearITPendingBit(uint32_t EXTI_Line);

配置NVIC,给中断设置一个优先级

void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup);                // 中断分组
void NVIC_Init(NVIC_InitTypeDef* NVIC_InitStruct);                         // 初始化NVIC
void NVIC_SetVectorTable(uint32_t NVIC_VectTab, uint32_t Offset);          // 设置中断向量表
void NVIC_SystemLPConfig(uint8_t LowPowerMode, FunctionalState NewState);  // 系统低功耗配置

中断函数是固定的,每个通道对应一个中断函数,参考启动文件。

基本框架写完后,使用调试模式测试

CountSensor模块

#include "stm32f10x.h"                  // Device header
#include "Delay.h"uint16_t CountSensor_Count;// CountSensor初始化模块
void CountSensor_Init(void)
{// 配置外部中断// 1配置GPIO/AFIO,把时钟外设都打开RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);// EXTI和NVIC的时钟都打开着不手动开启// 2配置GPIO,选择端口为输入模式GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;     // 上拉输入GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOB, &GPIO_InitStructure);// 3配置AFIO。数据选择器输入为GPIOB的14号引脚,输出端固定连接的是EXTI14GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource14);// 4配置EXTI,选择边沿触发方式(上升沿/下降沿/双边沿),选择响应方式(中断/事件)EXTI_InitTypeDef EXTI_InitStructure;EXTI_InitStructure.EXTI_Line = EXTI_Line14;						// 指定配置中断线14EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;				// 选择中断模式EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;			// 上升沿触发,遮挡的时候触发
//	EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;			// 下降沿触发,离开的时候触发
//	EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling;	// 遮挡和离开的时候触发EXTI_InitStructure.EXTI_LineCmd = ENABLE;						// 开启EXTIEXTI_Init(&EXTI_InitStructure);// 配置NVIC,给中断一个优先级NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);					// 2位抢占,2位响应,整个工程只有一种NVIC_InitTypeDef NVIC_InitStructure;NVIC_InitStructure.NVIC_IRQChannel = EXTI15_10_IRQn;			// 指定中断通道,选的是14NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;		// 指定抢占优先级NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;				// 指定响应优先级NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;					// 使能NVIC_Init(&NVIC_InitStructure);
}// 中断函数,无参无返回值
void EXTI15_10_IRQHandler(void)
{// 先判断中断标志位,确保是设置的中断源触发的这个函数if (EXTI_GetITStatus(EXTI_Line14) == SET){// 执行中断程序
//		Delay_ms(1000);			// 消除抖动CountSensor_Count++;	// 计数// 中断程序结束后,清除中断标志位;不清除就会一直申请中断,卡死在中断函数里EXTI_ClearITPendingBit(EXTI_Line14);}
}// 返回计数
uint16_t CountSensor_GetCount(void)
{return CountSensor_Count;
}

这里上升沿触发,遮挡的时候触发,下降沿触发,离开的时候触发。

3.3 主函数

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "OLED.h"
#include "CountSensor.h"int main()
{CountSensor_Init();									// 初始化计数配置OLED_Init();										// 初始化OLEDOLED_ShowString(1, 1, "Count:");   					// 显示字符串while (1){OLED_ShowNum(1, 7, CountSensor_GetCount(), 5);	// 显示计数}
}

4 EXTI外部中断之旋转编码器计次

4.1 接线图

4.2 封装模块

EnCoder模块

#include "stm32f10x.h"                  // Device headerint16_t EnCoder_Count = 0;// EnCoder初始化模块
void EnCoder_Init(void)
{// 配置外部中断// 1配置GPIO/AFIO,把时钟外设都打开RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);// EXTI和NVIC的时钟都打开着不手动开启// 2配置GPIO,选择端口为输入模式GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;     // 上拉输入GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOB, &GPIO_InitStructure);// 3配置AFIO。数据选择器输入为GPIOB的0和1号引脚,输出端固定连接的是EXTI0和EXTI1GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource0);GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource1);// 4配置EXTI,选择边沿触发方式(上升沿/下降沿/双边沿),选择响应方式(中断/事件)EXTI_InitTypeDef EXTI_InitStructure;EXTI_InitStructure.EXTI_Line = EXTI_Line0 | EXTI_Line1;			// 指定配置中断线0和1EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;				// 选择中断模式EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;			// 上升沿触发,遮挡的时候触发
//	EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;			// 下降沿触发,离开的时候触发
//	EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling;	// 遮挡和离开的时候触发EXTI_InitStructure.EXTI_LineCmd = ENABLE;						// 开启EXTIEXTI_Init(&EXTI_InitStructure);// 配置NVIC,给中断一个优先级NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);					// 2位抢占,2位响应,整个工程只有一种NVIC_InitTypeDef NVIC_InitStructure;// 指定0通道NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;				// 指定中断通道,选的是0NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;		// 指定抢占优先级NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;				// 指定响应优先级NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;					// 使能NVIC_Init(&NVIC_InitStructure);// 指定1通道NVIC_InitStructure.NVIC_IRQChannel = EXTI1_IRQn;				// 指定中断通道,选的是1NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;		// 指定抢占优先级NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;				// 指定响应优先级NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;					// 使能NVIC_Init(&NVIC_InitStructure);
}// 中断函数
void EXTI0_IRQHandler(void)
{// 先判断中断标志位,确保是设置的中断源触发的这个函数if (EXTI_GetITStatus(EXTI_Line0) == SET){// 执行中断程序// 判断GPIO_Pin_1输出是0if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_1) == 0){EnCoder_Count--;}// 中断程序结束后,清除中断标志位;不清除就会一直申请中断,卡死在中断函数里EXTI_ClearITPendingBit(EXTI_Line0);}}// 中断函数
void EXTI1_IRQHandler(void)
{// 先判断中断标志位,确保是设置的中断源触发的这个函数if (EXTI_GetITStatus(EXTI_Line1) == SET){// 执行中断程序// 判断GPIO_Pin_0输出是0if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_0) == 0){EnCoder_Count++;}// 中断程序结束后,清除中断标志位;不清除就会一直申请中断,卡死在中断函数里EXTI_ClearITPendingBit(EXTI_Line1);}
}// get函数
int16_t EnCoder_Get(void)
{int16_t temp = EnCoder_Count;EnCoder_Count = 0;return temp;
}

4.3 主函数

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "OLED.h"
#include "EnCoder.h"int16_t num;int main()
{EnCoder_Init();										// 初始化计数配置OLED_Init();										// 初始化OLEDOLED_ShowString(1, 1, "Data:");   					// 显示字符串while (1){num += EnCoder_Get();OLED_ShowSignedNum(1, 6, num, 5);				// 显示数据}
}

往右拧,数字变大,往左拧,数字变小。

(1)在中断函数中,最好不要执行耗时过长的代码;

(2)最好不要在中断函数和主函数调用相同的函数或者操作同一个硬件

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

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

相关文章

GSLB是什么?谈谈对该技术的一点理解

GSLB是什么&#xff1f;它又称为全局负载均衡&#xff0c;是主流的负载均衡类型之一。众所周知&#xff0c;负载均衡位于服务器的前面&#xff0c;负责将客户端请求路由到所有能够满足这些请求的服务器&#xff0c;同时最大限度地提高速度和资源利用率&#xff0c;并确保无任何…

AIGC发展史

1 AIGC概况 1.1 AIGC定义 AIGC&#xff08;AI Generated Content&#xff09;是指利用人工智能技术生成的内容。它也被认为是继PGC,UGC之后的新型内容生产方式&#xff0c;AI绘画、AI写作等都属于AIGC的具体形式。2022年AIGC发展速度惊人&#xff0c;迭代速度更是呈现指数级发…

揭秘接口测试的必备基础知识!

这一篇讲接口测试的基础&#xff0c;如果你还在做手工测试&#xff0c;你可以从这里开始入门&#xff0c;做接口测试是最容易的一种自动化测试。 一、接口测试是什么 首先要理解接口测试就是测接口&#xff0c;如图所示&#xff1a; 让我们以数据驱动的视角来看接口测试&#…

AI生成视频-Pika

背景介绍 Pika 是一个使用 AI 生成和编辑视频的平台。它致力于通过 AI 技术使视频制作变得简单和无障碍。 Pika 1.0 是 Pika 的一个重大产品升级&#xff0c;包含了一个新的 AI 模型,可以在各种风格下生成和编辑视频,如 3D 动画&#xff0c;动漫&#xff0c;卡通和电影风格。…

亚马逊云科技向量数据库与生成式AI的完美融合:落地实践详解(四)

以往 OpenSearch 摄入时的一些最佳实践中并不包含 knn 的情况&#xff0c;所以在 knn 索引存在的情况&#xff0c;不能完全参照之前的结论&#xff0c;通过以上三种不同的实验方式&#xff0c;在多次实验的过程中&#xff0c;本文得到了以下的一些实践经验和结论&#xff0c;供…

java中 list.size() = 1 但显示 All elements are null

一、问题描述 serve层定义一个对象集合接收mybatis返回的结果&#xff0c;查询结果为空&#xff0c;但是接收集合对象长度却为1&#xff0c;集合内部显示All elements are null&#xff1b;导致在直接调用list集合中一些方法时导致报错java.lang.NullPointerException: null …

字符函数,字符串函数(C语言)

字符函数&#xff0c;字符串函数是C语言中非常重要的函数族&#xff0c;它们在日常的编程过程中被广泛使用。它们不仅能够大大提高我们的编程效率&#xff0c;还可以为我们提供更灵活、更高效的操作方法。在本篇博客中&#xff0c;我们将一起深入了解这二类函数的基本概念和使用…

在外包待了6年,技术退步太明显......

先说情况&#xff0c;大专毕业&#xff0c;18年通过校招进入湖南某软件公司&#xff0c;干了接近6年的功能测试&#xff0c;今年年初&#xff0c;感觉自己不能够在这样下去了&#xff0c;长时间呆在一个舒适的环境会让一个人堕落!而我已经在一个企业干了四年的功能测试&#xf…

关于队列的简单理解

1.队列(Queue) 1.1 关于队列 队列 &#xff1a;只允许在一端进行插入数据操作&#xff0c;在另一端进行删除数据操作的特殊线性表&#xff0c; 队列具有先进先出 FIFO(First In First Out)的操作特性&#xff08;队列是个接口&#xff09;&#xff1b; 入队列&#x…

外包干了2个月,技术倒退2年。。。

先说一下自己的情况&#xff0c;本科生&#xff0c;20年通过校招进入深圳某软件公司&#xff0c;干了接近4年的功能测试&#xff0c;今年国庆&#xff0c;感觉自己不能够在这样下去了&#xff0c;长时间呆在一个舒适的环境会让一个人堕落!而我已经在一个企业干了四年的功能测试…

图书馆智能密集书架怎么用的

图书馆智能密集书架是一种高密度存储书籍的设备&#xff0c;通过机器控制和操作&#xff0c;实现了对书籍的高效存储和检索。使用专久智能智能密集书架的方法如下&#xff1a; 1.先进行授权认证&#xff0c;确认身份和权限&#xff0c;进行操作前要确保权限正确&#xff0c;以免…

日志JavaAgent-NoClassDefFoundError

一、引言 组内最近做了一个日志公共组件&#xff0c;用的是javaagent的方式&#xff0c;之前搞的maven jar包每次都要把所有系统都发一遍&#xff0c;太麻烦。 javaagent通过Java虚拟机&#xff08;JVM&#xff09;的Instrumentation API来实现代码的侵入。通过Instrumentation…

GNN Maximum Flow Problem (From Shusen Wang)

Maximum Flow Problem ShusenWang 图数据结构和算法课程笔记 Slides Maximum Flow Problem Description Naive Algorithm Residual Capacity - FlowLeft: Original GraphRight: Residual Graph - Bottleneck capacity 2- Iteration 2:- Find an augmenting path: s -&g…

HTTP会话技术---Cookie、Session和Token介绍及它们在JavaWeb中的使用

当涉及到Web应用程序的身份验证和状态管理时&#xff0c;我们通常会使用到Cookie、Session和Token这些会话技术。下面是对它们的介绍&#xff0c;并在JavaWeb中的示例 Cookie&#xff08;HTTP Cookie&#xff09; Cookie是一种存储在用户浏览器中的小型文本文件&#xff0c;由…

基于Springboot的在线问卷调查系统(有报告)。Javaee项目,springboot项目。

演示视频&#xff1a; 基于Springboot的在线问卷调查系统(有报告)。Javaee项目&#xff0c;springboot项目。 项目介绍&#xff1a; 采用M&#xff08;model&#xff09;V&#xff08;view&#xff09;C&#xff08;controller&#xff09;三层体系结构&#xff0c;通过Spring…

1-4节电池升降压充电IC解决方案

描述 MP2760是一款集成窄电压DC&#xff08;NVDC&#xff09;电源路径管理功能和USB On-the-Go(OTG)功能的升降压充电IC&#xff0c;兼容USB PD&#xff0c;适用于单节至4节串联的电池包应用。该芯片的充电输入电压范围广&#xff0c;可支持最高22V。 当启用电池放电模式&…

深入学习Synchronized各种使用方法

文章目录 前言一、synchronized关键字通用在下面四个地方&#xff1a;1.1synchronized修饰实例方法1.2synchronized修饰静态方法&#xff1a;1.3synchronized修饰实例方法的代码块1.4synchronized修饰静态方法的代码块2.读入数据 二.Sychronized关键特性2.1互斥2.2 刷新内存2.3…

CentOS 7 虚拟机java项目部署tomcat

首先安装java环境 下载安装包:jdk-19_linux-x64_bin.tar.gz_免费高速下载|百度网盘-分享无限制 (baidu.com) 将安装包上传到虚拟机 解压 tar zxvf jdk-19_linux-x64_bin.tar.gz 移动文件到 mv jdk-19.0.1 /usr/jdk-19.0.1 编辑配置文件 vim /etc/profile export JAVA…

解决cad找不到msvcr100.dll的有效方法,完美修复dll问题

在计算机使用过程中&#xff0c;我们经常会遇到一些错误提示&#xff0c;其中之一就是由于找不到msvcr100.dll文件而导致CAD软件无法正常运行的情况&#xff0c;系统无法找到所需的动态链接库文件。但是通过一些简单的解决方法&#xff0c;我们可以快速解决这个问题并继续我们的…

【动态规划】LeetCode-62.不同路径

&#x1f388;算法那些事专栏说明&#xff1a;这是一个记录刷题日常的专栏&#xff0c;每个文章标题前都会写明这道题使用的算法。专栏每日计划至少更新1道题目&#xff0c;在这立下Flag&#x1f6a9; &#x1f3e0;个人主页&#xff1a;Jammingpro &#x1f4d5;专栏链接&…