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

stm32中断详解

stm32中断详解

文章目录

  • stm32中断详解
    • 1.什么是中断?
      • 1.STM32中断系统特点
      • 2.中断处理流程
      • 3.中断配置与使用
    • 2.AFIO寄存器
    • 3.NVIC寄存器
    • 3.中断分组、抢占优先级和响应优先级
      • 1. 中断分组
      • 2. 抢占优先级
      • 3. 响应优先级
      • 4.配置与应用
    • 4.中断服务函数
    • 5.配置中断流程
      • 1.配置外设
      • 2.配置AFIO寄存器
      • 3.配置EXTI
      • 4.配置NVIC
      • 5.编写中断服务函数
        • 1.EXTI4_IRQHandler
        • 2.EXTI9_5_IRQHandler
    • 6.完整程序

1.什么是中断?

中断是在处理器执行程序过程中,遇到需要立即处理的内外部紧急事件时,暂时中断当前任务,转而执行专门的处理程序来应对这些事件的一种机制。一旦事件处理完成,处理器会自动返回到之前被中断的地方继续执行原来的程序。这种机制提高了CPU的运行效率,避免了因不断轮询等待事件状态改变而浪费资源,并且能够实现实时处理和多任务管理,在嵌入式系统中尤为重要。
在这里插入图片描述

1.STM32中断系统特点

STM32微控制器的中断系统非常强大且灵活,具备以下特点:

  • 中断源丰富:STM32拥有众多内置和外部中断源,包括定时器、串口、I²C、SPI、DMA、ADC以及每个GPIO引脚都可配置为中断源。

  • 中断控制器:采用Nested Vectored Interrupt Controller (NVIC),支持多级中断嵌套和优先级管理,允许在处理中断时响应更高级别的中断请求。

  • 中断优先级管理:STM32允许用户通过编程配置中断的优先级,支持优先级分组,以适应不同的应用需求。优先级分组将优先级分为抢占优先级和子优先级,以实现复杂的中断处理逻辑。

  • 中断向量表:存储中断服务例程(ISR)的入口地址,可以重映射到SRAM中以提高中断响应速度。

  • EXTI:External Interrupt/Event Controller,用于管理外部中断和事件,使得每个GPIO都能作为中断输入,增加了灵活性。

2.中断处理流程

  1. 中断请求:当某个事件发生时,相应的中断请求被触发。
  2. 中断响应:如果该中断未被屏蔽且优先级高于当前正在执行的任务,CPU将保存当前状态(如PC指针和寄存器内容),然后跳转到中断向量表执行中断服务例程(ISR)。
  3. 中断服务:ISR执行,处理中断事件。
  4. 中断返回:ISR执行完毕后,CPU恢复之前保存的状态,继续执行被打断的任务。

3.中断配置与使用

在编程STM32时,通常需要通过配置寄存器来使能中断、设置中断优先级,并编写对应的中断服务例程(ISR)。可以使用标准库、HAL库或LL库等不同层次的API来简化配置过程。

2.AFIO寄存器

AFIO寄存器在中断处理中的主要用途是实现GPIO引脚到外部中断线(EXTI)的映射。STM32的外部中断/事件控制器(EXTI)可以连接到多个GPIO引脚,但并不是每个GPIO直接连接到一个独立的中断线。因此,需要通过AFIO寄存器来指定哪些GPIO引脚的信号应该被路由到EXTI的哪一条中断线上。

AFIO中的外部中断配置寄存器(EXTICR1至EXTICR4)用于配置GPIO与EXTI线的关联。每个EXTICR寄存器有4组设置位,每组4位,分别对应4个GPIO端口(PA至PG)。通过设置这些位,可以决定当某个GPIO端口上的信号变化时,应触发哪个EXTI线的中断。

例如,如果你想将PA0设置为中断输入,并让它触发EXTI线0,就需要在AFIO_EXTICR1的EXTI0[3:0]位中设置相应的值,指示PA0作为EXTI0的输入源。这样,当PA0上发生预设的中断事件(如上升沿、下降沿或双边沿)时,EXTI0中断就会被触发。

AFIO寄存器在中断处理中的核心作用是确保GPIO信号能够正确地连接到EXTI系统,进而触发中断,使得软件能够及时响应外部事件。

3.NVIC寄存器

在STM32等基于ARM Cortex-M系列的微控制器中,NVIC(Nested Vectored Interrupt Controller)是中断管理系统的核心组件,它包含了一系列寄存器用于控制中断的使能、优先级、状态以及中断处理流程。以下是NVIC中几个关键寄存器的简要说明:

  1. 中断使能寄存器(ISER[0-1])

    • 这些寄存器用于使能中断。每个中断在ISER中有对应的一个位,写1到该位置可以使能相应的中断。STM32F103XX有两组ISER寄存器,每组控制32个中断,共管理64个中断。
  2. 中断除能寄存器(ICER[0-1])

    • 与ISER相反,这些寄存器用于除能中断。写1到对应位会禁止相应中断。
  3. 中断挂起寄存器(ISPR[0-1])

    • 当中断被挂起时(即中断产生但尚未处理,因为有更高优先级的中断正在处理),对应位会被置1。
  4. 中断解挂寄存器(ICPR[0-1])

    • 用于解除中断挂起状态,写1到对应位可以解挂一个已挂起的中断。
  5. 中断激活标志寄存器(IABR[0-1])

    • 反映当前正在执行的中断状态,如果某个中断正在被服务,则其对应位为1。
  6. 中断优先级寄存器(IPRx [0-4])

    • 这些寄存器用于设置每个中断的优先级。根据优先级分组配置,每个中断占用寄存器中的1到4位,用于设置抢占优先级和响应优先级。
  7. 中断控制与状态寄存器(ICSR)

    • 包含控制位和状态位,用于控制中断的处理流程,如软件触发中断、读取当前正在执行的中断等。
  8. 系统控制块的中断控制寄存器(SCB_AIRCR)

    • 控制整个系统的中断行为,包括中断优先级分组的设置(PRIGROUP位),以及系统复位等。
  9. 中断清除挂起寄存器(ICSR)中的相关位

    • 用于清除挂起的中断标志,使得中断可以被再次触发。

3.中断分组、抢占优先级和响应优先级

在STM32中断系统中,为了更好地管理中断处理的顺序和优先级,采用了中断分组、抢占优先级和响应优先级的概念。

1. 中断分组

中断分组是指将中断优先级分成抢占优先级和响应优先级两个部分,通过配置系统控制寄存器(SYSCFG)中的相关位来确定分组方式。STM32允许用户选择4种不同的分组模式:

  • 分组0:所有中断只有抢占优先级,没有响应优先级,最多支持16个优先级。
  • 分组1:每个中断由4位表示优先级,其中最高2位表示抢占优先级,低2位表示响应优先级,最多支持4个抢占优先级和4个响应优先级。
  • 分组2:每个中断由4位表示优先级,其中最高3位表示抢占优先级,最低1位表示响应优先级,最多支持8个抢占优先级和2个响应优先级。
  • 分组3分组4:每个中断由4位表示优先级,其中最高4位表示抢占优先级,没有响应优先级,最多支持16个抢占优先级。
    在这里插入图片描述

2. 抢占优先级

抢占优先级决定了中断能否打断其他中断服务程序的执行。一个高抢占优先级的中断可以打断低抢占优先级中断的服务,即使后者正在执行。当一个更高优先级的中断到来时,当前中断服务会被暂停,处理器先处理更高优先级的中断。

3. 响应优先级

响应优先级用于管理同级抢占优先级中断的执行顺序。当两个中断的抢占优先级相同,但一个响应优先级高于另一个时,响应优先级高的中断会优先得到服务。如果两个中断的抢占优先级和响应优先级都相同,那么按照中断产生的先后顺序处理。

4.配置与应用

在实际应用中,通过编程配置中断分组和各个中断的优先级,可以满足不同应用场景对实时性和任务调度的需求。通常使用库函数如HAL库的HAL_NVIC_SetPriority()函数来设置中断的优先级,同时考虑系统的实时性要求和中断处理的复杂度来合理安排中断分组和优先级配置。正确设置中断优先级和分组是保证嵌入式系统高效稳定运行的关键之一。

4.中断服务函数

中断服务函数(Interrupt Service Routine, ISR)是嵌入式系统编程中的关键部分,特别是在使用STM32等微控制器时。当一个中断事件发生时,处理器会暂停当前正在执行的任务,保存现场(即当前的工作状态),然后跳转到相应的中断服务函数去处理这个事件。处理完成后,处理器恢复之前保存的现场并继续执行被打断的任务。以下是关于STM32中断服务函数的一些关键特点和注意事项:

  1. 命名规则:STM32的中断服务函数遵循特定的命名约定,这些函数名通常在启动文件(如startup_stm32f10x_hd.sstartup_stm32f40_41xxx.s)中预定义。例如,USART1_IRQHandler是USART1中断的服务函数,EXTI0_IRQHandler对应EXTI线0的中断。

  2. 无返回值与形参:中断服务函数没有返回值,也不接受任何参数。这是因为中断可能在任何时刻发生,无法预测调用环境,所以不能依赖于常规的函数调用约定。

  3. 弱定义:在启动文件中,中断服务函数常常以.weak属性声明,这意味着如果用户没有提供具体的实现,编译器会提供一个默认的空实现(通常只是返回)。用户需要在自己的代码中重新定义这些函数以添加实际的中断处理逻辑。

  4. 执行速度:中断服务函数应尽可能简短且快速执行,以减少中断延迟并尽快让系统回到正常运行状态。复杂的处理应当委托给普通任务或使用中断后处理机制。

  5. 中断优先级:STM32支持多个级别的中断优先级管理,开发者可以通过配置NVIC(Nested Vectored Interrupt Controller)来设定每个中断的优先级,决定中断的响应顺序。

  6. 中断禁止与使能:在中断服务函数内部,有时需要临时禁止某些中断,以防止中断嵌套引起的问题。处理完毕后,应恢复中断使能状态。

  7. 保存与恢复上下文:对于需要执行多条指令的复杂ISR,可能需要显式保存和恢复CPU寄存器的值,以避免破坏中断前的程序状态。不过,Cortex-M内核提供了自动保存和恢复某些寄存器的功能(通过使用PendSV或其它机制)。

编写中断服务函数时,遵循最佳实践是非常重要的,以确保系统的稳定性和可靠性。

5.配置中断流程

1.配置外设

这里以stm32F103x的两个外部按键为例

	RCC_APB2PeriphClockCmd(KEY_GPIO_CLK, ENABLE);GPIO_InitTypeDef GPIO_InitStruct;GPIO_InitStruct.GPIO_Pin = KEY1_GPIO_PIN|KEY2_GPIO_PIN;GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;GPIO_Init(KEY_GPIO_PORT, &GPIO_InitStruct);

首先打开总线时钟,配置引脚以及引脚输出模式,这部分内容比较简单,这里不再详细赘述。

2.配置AFIO寄存器

RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
GPIO_EXTILineConfig(GPIO_PortSourceGPIOC, GPIO_PinSource4);
GPIO_EXTILineConfig(GPIO_PortSourceGPIOC, GPIO_PinSource5);
  1. RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);

    这行代码的作用是使能高级控制外设时钟(APB2总线上的时钟)给AFIO(alternate function input/output,备用功能输入输出)模块。在STM32中,AFIO模块负责重映射和中断线的配置,比如将GPIO引脚映射到外部中断线上。调用RCC_APB2PeriphClockCmd函数并传入RCC_APB2Periph_AFIO作为参数,以及ENABLE标志,是为了确保在接下来对AFIO进行配置之前,相关的时钟已经被开启。

  2. GPIO_EXTILineConfig(GPIO_PortSourceGPIOC, GPIO_PinSource4);

    GPIO_EXTILineConfig(GPIO_PortSourceGPIOC, GPIO_PinSource5);

    这两行代码用于配置GPIO引脚作为外部中断线(EXTI)的输入。GPIO_EXTILineConfig函数有两个参数,第一个参数指定GPIO端口来源,第二个参数指定该端口上的具体引脚。在第一个调用中,GPIOC端口的第4号引脚(PC4)被配置为与某个EXTI线相连;在第二个调用中,配置的是GPIOC端口的第5号引脚(PC5)。

    通过这些配置,当PC4或PC5上的信号发生变化时,将会触发对应的EXTI中断。

3.配置EXTI

	EXTI_InitTypeDef EXTI_InitStruct;EXTI_InitStruct.EXTI_Line = EXTI_Line4 | EXTI_Line5;EXTI_InitStruct.EXTI_Mode = EXTI_Mode_Interrupt;EXTI_InitStruct.EXTI_Trigger = EXTI_Trigger_Rising;EXTI_InitStruct.EXTI_LineCmd = ENABLE;EXTI_Init(&EXTI_InitStruct);
  1. EXTI_InitTypeDef EXTI_InitStruct;
    这行代码声明了一个EXTI_InitTypeDef类型的结构体变量EXTI_InitStruct,该结构体包含了EXTI(External Interrupt/Event)的所有初始化配置参数。

  2. EXTI_InitStruct.EXTI_Line = EXTI_Line4 | EXTI_Line5;
    这里设置了要配置的外部中断线。通过按位或运算符|,同时选择了EXTI线4(EXTI_Line4)和EXTI线5(EXTI_Line5),意味着接下来的配置将应用于这两个中断线。

  3. EXTI_InitStruct.EXTI_Mode = EXTI_Mode_Interrupt;
    配置EXTI的工作模式为中断模式(EXTI_Mode_Interrupt)。EXTI可以工作在中断模式或事件模式,这里选择的是中断模式,意味着当指定的事件发生时,会触发CPU中断。

  4. EXTI_InitStruct.EXTI_Trigger = EXTI_Trigger_Rising;
    设置触发条件为上升沿触发(EXTI_Trigger_Rising)。EXTI可以配置为上升沿、下降沿、双边沿或电平触发。这里配置的是当EXTI线上的信号从低到高变化(上升沿)时触发中断。

  5. EXTI_InitStruct.EXTI_LineCmd = ENABLE;
    启用所选的EXTI线(EXTI_Line4和EXTI_Line5)。通过设置EXTI_LineCmdENABLE,确保这些中断线在配置后处于启用状态。

  6. EXTI_Init(&EXTI_InitStruct);
    最后,调用EXTI_Init函数并将EXTI_InitStruct结构体的地址作为参数传递,完成EXTI的初始化配置。这个函数根据结构体中的设置,对EXTI模块进行相应的配置,使得指定的中断线按照所配置的模式、触发条件等开始工作。

4.配置NVIC

	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);NVIC_InitTypeDef NVIC_InitStruct;NVIC_InitStruct.NVIC_IRQChannel = EXTI4_IRQn;NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 2;NVIC_InitStruct.NVIC_IRQChannelSubPriority =1;NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;NVIC_Init(&NVIC_InitStruct);NVIC_InitStruct.NVIC_IRQChannel = EXTI9_5_IRQn;NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 1;NVIC_InitStruct.NVIC_IRQChannelSubPriority =1;NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;NVIC_Init(&NVIC_InitStruct);
  1. NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
    这行代码设置了中断优先级分组为第2组。在STM32中,中断优先级分为抢占优先级和响应优先级,通过NVIC_PriorityGroupConfig函数可以配置这两类优先级的比例。第2组表示有2位用于抢占优先级,2位用于响应优先级,总共支持4个抢占优先级和4个响应优先级。

  2. NVIC_InitTypeDef NVIC_InitStruct;
    定义了一个NVIC_InitTypeDef类型的结构体变量NVIC_InitStruct,用于存储中断通道的初始化配置信息。

3-7行和10-14行分别配置了两个中断通道:

  • 对于EXTI4_IRQn:

    • NVIC_InitStruct.NVIC_IRQChannel = EXTI4_IRQn;:指定了中断通道为EXTI4的中断。
    • NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 2;:设置抢占优先级为2。
    • NVIC_InitStruct.NVIC_IRQChannelSubPriority = 1;:设置响应优先级为1。
    • NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;:使能该中断通道。
  • 对于EXTI9_5_IRQn:

    • 类似地,这里配置了EXTI9_5(这是一个组合中断,代表EXTI5到EXTI9的中断)的中断通道,抢占优先级设置为1,响应优先级也是1,并且也使能了这个中断通道。

8行和15行:

  • NVIC_Init(&NVIC_InitStruct);:调用NVIC_Init函数,将NVIC_InitStruct结构体中的配置应用到相应的中断通道上。第一次调用是为EXTI4,第二次调用是为EXTI9_5。

现在来分析两个中断(EXTI4和EXTI9_5)的响应顺序:

  • EXTI4_IRQn 的配置是:抢占优先级为2,响应优先级为1。
  • EXTI9_5_IRQn 的配置是:抢占优先级为1,响应优先级也为1。

在STM32的中断优先级管理中,当一个中断发生时,处理器首先比较它们的抢占优先级。具有较高抢占优先级的中断可以打断正在处理的较低抢占优先级中断。如果抢占优先级相同,则会比较响应优先级,响应优先级较高的中断会优先得到服务,前提是当前没有更高抢占优先级的中断在处理中。

根据上述规则,EXTI9_5_IRQn 的抢占优先级为1,而 EXTI4_IRQn 的抢占优先级为2。因此,如果这两个中断同时请求服务,EXTI9_5_IRQn 会优先响应,因为它具有更高的抢占优先级,即使它的响应优先级与EXTI4相同。只有在EXTI9_5_IRQn被完全服务完毕或者被挂起(如果有更高抢占优先级的中断插入)后,才会轮到EXTI4_IRQn被处理。

5.编写中断服务函数

注意:STM32的中断服务函数遵循特定的命名约定,这些函数名通常在启动文件。

void EXTI4_IRQHandler(void)
{if(EXTI_GetITStatus(EXTI_Line4) == SET){EXTI_ClearITPendingBit(EXTI_Line4);for(uint8_t i = 0 ; i < 5 ; i++){LED_FLASH();}}
}
void EXTI9_5_IRQHandler(void)
{if(EXTI_GetITStatus(EXTI_Line5) == SET){EXTI_ClearITPendingBit(EXTI_Line5);for(uint8_t i = 0 ; i < 5 ; i++){LED3_FLASH();}}
}
1.EXTI4_IRQHandler

这是EXTI4中断的处理函数。当中断控制器检测到EXTI线4上有中断请求时,会调用此函数。

  1. if(EXTI_GetITStatus(EXTI_Line4) == SET)
    这行代码检查EXTI线4是否确实产生了中断(即中断挂起位是否为SET)。EXTI_GetITStatus函数用于获取指定EXTI线的中断挂起状态。

  2. EXTI_ClearITPendingBit(EXTI_Line4);
    如果EXTI4确实产生了中断,这行代码会清除该中断的挂起位,防止中断标志一直存在,导致函数被重复调用。

  3. for(uint8_t i = 0 ; i < 5 ; i++) { LED_FLASH(); }
    进行一个循环,调用LED_FLASH()函数5次。这通常是用于示例目的,表示当EXTI4中断发生时,执行操作,让LED闪烁5次。

2.EXTI9_5_IRQHandler

这是EXTI9_5中断的处理函数,它实际上是一个组合中断,覆盖了EXTI5到EXTI9。但在这个示例中,只针对EXTI线5进行了处理。

  1. if(EXTI_GetITStatus(EXTI_Line5) == SET)
    检查EXTI线5是否有中断挂起,即是否真的发生了中断。

  2. EXTI_ClearITPendingBit(EXTI_Line5);
    清除EXTI线5的中断挂起位,确保中断被妥善处理后不会再次误触发。

  3. for(uint8_t i = 0 ; i < 5 ; i++) { LED3_FLASH(); }
    同样地,执行一个循环,调用LED3_FLASH()函数5次,这里的操作是控制第三个LED闪烁,以区别于EXTI4的中断响应。

根据之前的配置信息,EXTI9_5_IRQHandler中断的抢占优先级被设置为了1,而EXTI4_IRQHandler中断的抢占优先级为2。在STM32的中断管理系统中,具有更高抢占优先级的中断可以打断正在执行的较低抢占优先级中断。

EXTI9_5_IRQHandler中断在EXTI4_IRQHandler中断服务例程执行过程中触发,由于EXTI9_5_IRQHandler具有更高的抢占优先级,它将能够打断EXTI4_IRQHandler的执行,处理器会先完成EXTI9_5_IRQHandler的处理,然后再返回继续执行(或重新开始,如果必要的话)EXTI4_IRQHandler

这种中断嵌套处理机制确保了高优先级的中断能够得到及时响应,从而满足实时系统中的紧急处理需求。

6.完整程序

#include "bsp_exti.h"
#include "bsp_key.h"void EXTI_KEY_Config(void)
{RCC_APB2PeriphClockCmd(KEY_GPIO_CLK, ENABLE);GPIO_InitTypeDef GPIO_InitStruct;GPIO_InitStruct.GPIO_Pin = KEY1_GPIO_PIN|KEY2_GPIO_PIN;GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;GPIO_Init(KEY_GPIO_PORT, &GPIO_InitStruct);RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);GPIO_EXTILineConfig(GPIO_PortSourceGPIOC, GPIO_PinSource4);GPIO_EXTILineConfig(GPIO_PortSourceGPIOC, GPIO_PinSource5);EXTI_InitTypeDef EXTI_InitStruct;EXTI_InitStruct.EXTI_Line = EXTI_Line4 | EXTI_Line5;EXTI_InitStruct.EXTI_Mode = EXTI_Mode_Interrupt;EXTI_InitStruct.EXTI_Trigger = EXTI_Trigger_Rising;EXTI_InitStruct.EXTI_LineCmd = ENABLE;EXTI_Init(&EXTI_InitStruct);
}void EXTI_NVIC_Config(void)
{NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);NVIC_InitTypeDef NVIC_InitStruct;NVIC_InitStruct.NVIC_IRQChannel = EXTI4_IRQn;NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 2;NVIC_InitStruct.NVIC_IRQChannelSubPriority =1;NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;NVIC_Init(&NVIC_InitStruct);NVIC_InitStruct.NVIC_IRQChannel = EXTI9_5_IRQn;NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 1;NVIC_InitStruct.NVIC_IRQChannelSubPriority =1;NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;NVIC_Init(&NVIC_InitStruct);
}

相关文章:

stm32中断详解

stm32中断详解 文章目录 stm32中断详解1.什么是中断&#xff1f;1.STM32中断系统特点2.中断处理流程3.中断配置与使用 2.AFIO寄存器3.NVIC寄存器3.中断分组、抢占优先级和响应优先级1. 中断分组2. 抢占优先级3. 响应优先级4.配置与应用 4.中断服务函数5.配置中断流程1.配置外设…...

【LeetCode】最小栈

目录 一、题目二、解法完整代码 一、题目 设计一个支持 push &#xff0c;pop &#xff0c;top 操作&#xff0c;并能在常数时间内检索到最小元素的栈。 实现 MinStack 类: MinStack() 初始化堆栈对象。 void push(int val) 将元素val推入堆栈。 void pop() 删除堆栈顶部的元…...

链接追踪系列-09.spring cloud项目整合elk显示业务日志

准备工作&#xff1a; 参看本系列之前篇&#xff1a;服务器安装elastic search 本机docker启动的kibana-tencent 使用本机安装的logstash。。。 本微服务实现的logstash配置如下&#xff1a; 使用腾讯云redis 启动本机mysql 启动本机docker 启动nacos,微服务依赖它作为…...

老年生活照护实训室:让养老护理更个性化

本文探讨了老年生活照护实训室在实现养老护理个性化方面的重要作用。通过分析其提供的实践环境、专业培训、模拟案例和评估机制&#xff0c;阐述了如何培养护理人员的个性化服务能力&#xff0c;以满足老年人多样化的需求&#xff0c;提高养老护理的质量和满意度。 在老龄化社会…...

c++课后作业

把字符串转换为整数 int main() {char pn[21];cout << "请输入一个由数字组成的字符串&#xff1a; ";cin >> pn;int last 0;int res[10];int j strlen(pn);int idx 2;cout << "请选择&#xff08;2-二进制&#xff0c;10-十进制&#xf…...

SpringBoot+Vue实现简单的文件上传(txt篇)

SpringBootVue实现简单的文件上传 1 环境 SpringBoot 3.2.1&#xff0c;Vue 2&#xff0c;ElementUI 2 页面 3 效果&#xff1a;只能上传txt文件且大小限制为2M&#xff0c;选择文件后自动上传。 4 前端代码 <template><div class"container"><el-…...

LLMs之RAG:GraphRAG(本质是名词Knowledge Graph/Microsoft微软发布)的简介、安装和使用方法、案例应用之详细攻略

LLMs之RAG&#xff1a;GraphRAG(本质是名词Knowledge Graph/Microsoft微软发布)的简介、安装和使用方法、案例应用之详细攻略 导读&#xff1a;2024年7月3日&#xff0c;微软正式开源发布GraphRAG。GraphRAG可以提高大型语言模型在私有数据集上的推理能力。 背景痛点&#xff1…...

Linux 之前的 Unix 桌面沉浮启示录

It takes more than open source, it takes open standards and consensus 仅仅开源还不足以实现开放&#xff0c;还需开放标准和建立共识 Steven J. Vaughan-Nichols Sat 27 Jan 2024 // 12:33 UTC 现在&#xff0c;由于有了安卓和 ChromeOS&#xff0c;Linux 已成为重要的终端…...

面试问题梳理:项目中防止配置中的密码泄露-Jasypt

背景 想起面试的时候&#xff0c;面试官问我现在大家用Spring框架&#xff0c;数据库、ES之类的密码都是配置在配置文件中的&#xff0c;有很大的安全隐患&#xff0c;你有考虑过怎么解决嘛&#xff1f; 当时我回答是可以在项目启动的过程中的命令行追加的方式&#xff0c;感觉…...

engine.addImportPath()用于向 QML 引擎添加新的模块搜索路径

engine.addImportPath() 是 QQmlApplicationEngine 类中的一个方法&#xff0c;用于向 QML 引擎添加新的模块搜索路径。这在需要加载自定义模块或从非标准位置加载 QML 文件时非常有用。通过使用 addImportPath() 方法&#xff0c;可以让 QML 引擎在额外的路径中查找 QML 模块。…...

ServiceNow UI Jelly模板注入漏洞复现(CVE-2024-4879)

0x01 产品简介 ServiceNow 是一个业务转型平台。通过平台上的各个模块,ServiceNow 可用于从人力资源和员工管理到自动化工作流程或作为知识库等各种用途。 0x02 漏洞概述 由于ServiceNow的Jelly模板输入验证不严格,导致未经身份验证的远程攻击者可通过构造恶意请求利用,在…...

项目部署笔记

1、安全组需开放&#xff08;如果不开放配置nginx也访问不到&#xff09; 2、域名解析配置IP(子域名也需配置IP&#xff0c;IP地址可以不同) 3、如果出现图片获其他的文件找不到的情况请仔细检查一下路径是否正确 4、服务器nginx配置SSL证书后启动报错&#xff1a; nginx: […...

PyCharm\VsCode——Python第三方库下载换源

为什么要换源&#xff1f; Python第三方库下载默认镜像源在国外&#xff0c;因为特殊的原因在国内的你我利用这个镜像源往往速度会非常地慢&#xff0c;因此为了提速将这个默认镜像源换成国内的镜像源是非常有必要的。 镜像源的种类有哪些&#xff1f; 国外镜像源——官方 http…...

图片上传裁剪react-cropper

效果图 安装插件 npm i react-cropper 或者 yarn add react-cropper 主要代码 import React, { useRef, useState } from react; import Cropper from react-cropper; import cropperjs/dist/cropper.css; import ./index.less; import { UploadOutlined } from ant-d…...

跨越空间的编码:在PyCharm中高效使用远程解释器

跨越空间的编码&#xff1a;在PyCharm中高效使用远程解释器 PyCharm的强大功能之一是支持远程解释器&#xff0c;这使得开发者能够在远程服务器或虚拟机上运行、调试代码&#xff0c;享受本地开发环境的便利。本文将详细介绍如何在PyCharm中配置和使用远程解释器&#xff0c;包…...

Vue3单文件jsx输出多组件示例遇到的坑

感谢博主减肥吧Evan提供的SFC实现多组件的思路和实现&#xff0c;小卷在大佬的基础上再完善下实现。 我们从tsx的API使用上得到启发&#xff0c;可以在vue的单文件组件&#xff08;sfc&#xff09;中使用defineComponent来定义和导出多个独立的小组件。此时sfc中的<templat…...

OpenCV中的轮廓检测cv2.findContours()

文章目录 前言一、查找轮廓二、绘制轮廓轮廓面积轮廓周长 前言 轮廓提取的前提&#xff0c;将背景置为黑色&#xff0c;目标为白色&#xff08;利用二值化或Canny&#xff09; 边缘检测&#xff0c;例如Canny等&#xff0c;利用梯度变化&#xff0c;记录图像中的边缘像素点&a…...

JFlash读取和烧录加密stm32程序

JFlash读取和烧录加密stm32程序 安装后JFlash所在的目录&#xff1a;C:\Program Files\SEGGER\JLink 一、烧写加密程序 1、打开C:\Program Files\SEGGER\JLink目录&#xff0c;找到JFlash.exe,双击它&#xff0c;就可以打开该执行程序。见下图&#xff1a; 2、选择“Create …...

【总结】实际业务场景中锁、事务、异常如何考虑使用?

文章目录 锁处理目的&#xff1a;考虑锁控制思路&#xff1a;生命周期接口并发控制解决方案&#xff1a;测试锁是否生效&#xff1a;模拟多线程并发场景的2种方式&#xff1a; 事务处理目的&#xff1a;考虑事务控制思路&#xff1a;解决方案&#xff1a; 总结 锁处理 目的&am…...

Pytorch使用Dataset加载数据

1、前言&#xff1a; 在阅读之前&#xff0c;需要配置好对应pytorch版本。 对于一般学习&#xff0c;使用cpu版本的即可。参考教程点我 导入pytorch包&#xff0c;使用如下命令即可。 import torch # 注意虽然叫pytorch&#xff0c;但是在引用时是引用torch2、神经网络获取…...

2025年能源电力系统与流体力学国际会议 (EPSFD 2025)

2025年能源电力系统与流体力学国际会议&#xff08;EPSFD 2025&#xff09;将于本年度在美丽的杭州盛大召开。作为全球能源、电力系统以及流体力学领域的顶级盛会&#xff0c;EPSFD 2025旨在为来自世界各地的科学家、工程师和研究人员提供一个展示最新研究成果、分享实践经验及…...

高等数学(下)题型笔记(八)空间解析几何与向量代数

目录 0 前言 1 向量的点乘 1.1 基本公式 1.2 例题 2 向量的叉乘 2.1 基础知识 2.2 例题 3 空间平面方程 3.1 基础知识 3.2 例题 4 空间直线方程 4.1 基础知识 4.2 例题 5 旋转曲面及其方程 5.1 基础知识 5.2 例题 6 空间曲面的法线与切平面 6.1 基础知识 6.2…...

实现弹窗随键盘上移居中

实现弹窗随键盘上移的核心思路 在Android中&#xff0c;可以通过监听键盘的显示和隐藏事件&#xff0c;动态调整弹窗的位置。关键点在于获取键盘高度&#xff0c;并计算剩余屏幕空间以重新定位弹窗。 // 在Activity或Fragment中设置键盘监听 val rootView findViewById<V…...

ArcGIS Pro制作水平横向图例+多级标注

今天介绍下载ArcGIS Pro中如何设置水平横向图例。 之前我们介绍了ArcGIS的横向图例制作&#xff1a;ArcGIS横向、多列图例、顺序重排、符号居中、批量更改图例符号等等&#xff08;ArcGIS出图图例8大技巧&#xff09;&#xff0c;那这次我们看看ArcGIS Pro如何更加快捷的操作。…...

C++八股 —— 单例模式

文章目录 1. 基本概念2. 设计要点3. 实现方式4. 详解懒汉模式 1. 基本概念 线程安全&#xff08;Thread Safety&#xff09; 线程安全是指在多线程环境下&#xff0c;某个函数、类或代码片段能够被多个线程同时调用时&#xff0c;仍能保证数据的一致性和逻辑的正确性&#xf…...

以光量子为例,详解量子获取方式

光量子技术获取量子比特可在室温下进行。该方式有望通过与名为硅光子学&#xff08;silicon photonics&#xff09;的光波导&#xff08;optical waveguide&#xff09;芯片制造技术和光纤等光通信技术相结合来实现量子计算机。量子力学中&#xff0c;光既是波又是粒子。光子本…...

算法岗面试经验分享-大模型篇

文章目录 A 基础语言模型A.1 TransformerA.2 Bert B 大语言模型结构B.1 GPTB.2 LLamaB.3 ChatGLMB.4 Qwen C 大语言模型微调C.1 Fine-tuningC.2 Adapter-tuningC.3 Prefix-tuningC.4 P-tuningC.5 LoRA A 基础语言模型 A.1 Transformer &#xff08;1&#xff09;资源 论文&a…...

Proxmox Mail Gateway安装指南:从零开始配置高效邮件过滤系统

&#x1f49d;&#x1f49d;&#x1f49d;欢迎莅临我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐&#xff1a;「storms…...

深度学习之模型压缩三驾马车:模型剪枝、模型量化、知识蒸馏

一、引言 在深度学习中&#xff0c;我们训练出的神经网络往往非常庞大&#xff08;比如像 ResNet、YOLOv8、Vision Transformer&#xff09;&#xff0c;虽然精度很高&#xff0c;但“太重”了&#xff0c;运行起来很慢&#xff0c;占用内存大&#xff0c;不适合部署到手机、摄…...

xmind转换为markdown

文章目录 解锁思维导图新姿势&#xff1a;将XMind转为结构化Markdown 一、认识Xmind结构二、核心转换流程详解1.解压XMind文件&#xff08;ZIP处理&#xff09;2.解析JSON数据结构3&#xff1a;递归转换树形结构4&#xff1a;Markdown层级生成逻辑 三、完整代码 解锁思维导图新…...