STM32F4中断(Interrupt)详解

2023-05-16

STM32F4中断(Interrupt)详解

文章目录

  • STM32F4中断(Interrupt)详解
    • 一、中断是什么?
    • 二、STM32的中断体系
      • 2.1 STM32的中断分类
      • 2.2 STM32中断优先级
        • 2.2.1 抢占优先级
        • 2.2.2 响应优先级
        • 2.2.3 自然优先级
      • 2.3 STM32中断实现方法
        • 2.3.1 中断执行过程
        • 2.3.2 中断实现
      • 2.4 中断的具体应用场景
    • 三、STM32中断的配置
      • 3.1 NVIC配置方法:
        • 3.1.1 NVIC配置函数
        • 3.1.2 初始化NVIC控制器的一般步骤:
      • 3.2 开启中断触发条件
        • 3.2.1 片上外设(串口,定时器等)—内部中断
        • 3.2.2 片外外设(按键,指纹模块等)—外部中断
      • 3.3 外部中断
        • 3.3.1 外部中断配置流程
      • 3.4 软件中断
        • 3.4.1 配置EXTI寄存器
        • 3.4.2 配置NVIC控制器
      • 3.5 中断服务函数
        • 3.5.1 片上外设的中断服务函数
        • 3.5.2 片外外设中断服务函数
        • 3.5.3 软件中断服务函数

一、中断是什么?

中断就是在程序正常运行时,突然发生一件"不正常"的事,CPU就需要暂停正在处理的事立马去处理这件"不正常"的事,处理完后再回到原来的事情

中断是指计算机运行过程中,出现某些意外情况需主机干预时,机器能自动停止正在运行的程序并转入处理新情况的程序,处理完毕后又返回原被暂停的程序继续运行。 — 百度百科

可以拿平常生活中的例子来说,一场考试,监考老师在监考时会不停的在教室里转圈(CPU正常执行既定程序),突然有个考生举手说想上厕所(意外情况),监考老师立马走过去(暂停正常任务),然后示意他去上厕所,随后监考老师继续巡视(返回正常任务)

二、STM32的中断体系

2.1 STM32的中断分类

  • 内核中断—NVIC嵌套向量控制器控制的片上外设异常
  • 外部中断—由外部中断线接收来自外部的电平异常
  • 软件中断—由外部中断线接收来自软件产生的异常

2.2 STM32中断优先级

为使系统能及时响应并处理发生的所有中断,系统根据引起中断事件的重要性和紧迫程度,硬件将中断源分为若干个级别,称作中断优先级。

在实际系统中,常常遇到多个中断源同时请求中断的情况,这时CPU必须确定首先为哪一个中断源服务,以及服务的次序。解决的方法是中断优先排队,即根据中断源请求的轻重缓急,排好中断处理的优先次序即优先级( Priority ),又称优先权,先响应优先级最高的中断请求。另外,当CPU正在处理某一中断时,要能响应另一个优先级更高的中断请求,而屏蔽掉同级或较低级的中断请求,形成中断嵌套 —百度百科

  • ARM公司规定中断优先级分为: 抢占/占先优先级 响应/次级优先级 自然优先级

  • ARM公司用8位二进制数来表示这三个优先级

  • ST(意法半导体)公司只用了4位二进制数来表示这三个优先级,故最多可以配置16个优先级

  • 优先级**序号越小,优先级越高**

  • 每个project只能有一个优先级分组

在查找优先级分组时,要去<内核手册>里查看,不同版本分组会有不同

分组号抢占优先级所占位响应优先级所占位抢占优先级范围响应优先级范围
3(0b011)400-15None
4(0b100)310-70-1
5(0b101)220-30-3
6(0b110)130-10-7
7(0b111)04None0-15

2.2.1 抢占优先级

不管中断产生的先后顺序,只比较抢占优先级的高低,优先级高的立即执行,例如:如果一个中断执行过程中,又有一个更高抢占优先级中断产生,CPU则会暂停当前中断跑去执行更高抢占优先级中断**,实现中断嵌套**

2.2.2 响应优先级

如果两个相同抢占优先级的中断产生,那么两个中断会按照响应优先级顺序进行排队,优先级高的先执行

2.2.3 自然优先级

自然优先级是事先已经规定好的优先级序列当抢占优先级、响应优先级都相同时,先执行自然优先级高的中断

2.3 STM32中断实现方法

2.3.1 中断执行过程

在这里插入图片描述

2.3.2 中断实现

STM32中断由嵌套向量中断控制器(NVIC)控制,它与处理器接口紧密配合,所有中断信号都要经过NVIC来进行控制,包括外部中断和软件中断

在这里插入图片描述

2.4 中断的具体应用场景

  • 时间片(非阻塞程序)的编写
  • 串口接受数据
  • 按键的触发等等

三、STM32中断的配置

3.1 NVIC配置方法:

3.1.1 NVIC配置函数

(1)NVIC分组函数:NVIC_SetPriorityGrouping

参数:7-分组号

返回:void

(2)NVIC优先级编码:NVIC_EncodePriority

参数1:分组号(同分组函数参数)

参数2:抢占优先级

参数3:响应优先级

返回:u32的一个编码数

功能:这个函数负责**把分组方式,抢占优先级,响应优先级的数值编码成一个32位的数字返回,方便在优先级设置函数里作为参数使用**(所以需要定义一个临时变量去存储该函数的返回值)

(3)NVIC优先级设置:NVIC_SetPriority

参数1:中断源编号(已经在stm32f4xx.h里定义成枚举类型)

参数2:中断优先级编码,使用的就是NVIC_EncodePriority函数的返回值

返回:void

(4)NVIC中断使能:NVIC_EnableIRQ

参数:中断源编号(已经在stm32f4xx.h里定义成枚举类型)

返回:void

3.1.2 初始化NVIC控制器的一般步骤:

  1. 找设置优先级组别函数:在<core_cm4.h>里寻找
  2. 找配置抢占优先级、响应优先级的函数:在<core_cm4.h>里寻找(配置抢占/响应优先级时,可调用NVIC_EncodePriority()函数对参数进行组合)
  3. 找NVIC中断使能函数:在<core_cm4.h>里寻找

例:初始化USART1的NVIC控制器为第5组,抢占优先级为1,自然优先级为3

usart1_Init();//事先要写好并调用usart1的初始化函数
void nvic_Init(void)
{
    u32 temp;
    
    NVIC_SetPriorityGrouping(7-5);//第五组写成7-5更具易读性
    temp = NVIC_EncodePriority(7-5,1,3);//temp存储返回值
    NVIC_SetPriority(USART1_IRQn,temp);//去文件里找中断源编号
    NVIC_EnableIRQ(USART1_IRQn);//NVIC中断使能
}

3.2 开启中断触发条件

3.2.1 片上外设(串口,定时器等)—内部中断

只需开启其相应的中断位即可

例:串口接收到数据时产生中断

USART1->CR1 |= (1<<5);//接收数据中断使能

3.2.2 片外外设(按键,指纹模块等)—外部中断

则还需要配置外部中断(EXTI寄存器和SYSCFG寄存器)

3.3 外部中断

如同配置内部中断一样,但像按键,指纹模块等外部设备,系统没有固定的中断源供使用,这时候就需要配置外部中断控制器

3.3.1 外部中断配置流程

(1)时钟使能SYSCFG寄存器—APB2–14位

(2)配置SYSCFG外部中断配置寄存器SYSCFG_EXTICR[0:3]

引脚0~3:SYSCFG_EXTICR[0]

引脚4~7:SYSCFG_EXTICR[1]

以此类推

(3)配置EXTI寄存器

  1. 中断屏蔽寄存器(EXTI_IMR)置1
  2. 事件屏蔽寄存器(EXTI_EMR)置0
  3. 上升/下降沿触发选择寄存器(EXTI_RTSR/EXTI_FTSR):根据需要配置
  4. 软件中断事件寄存器(EXTI_SWIER)置0

(4)配置NVIC控制器

(5)按内部中断的方法配置NVIC控制器,但中断源是外部中断线EXTI

例:配置GPIOC端口13引脚的Key2下降沿触发中断

中断为第五组,抢占优先级为1,响应优先级为2

Key2_Init();//事先要写好并调用Key2的初始化函数
void exti15_10_Init(void)
{
    u32 priority;
    
    //时钟使能SYSCFG寄存器—APB2–14位
    RCC->APB2ENR |= (0x01<<14);
    //配置SYSCFG外部中断配置寄存器SYSCFG_EXTICR[0:3]
    SYSCFG->EXTICR[3] |= (0x02<<4);//PC13
    //EXTI寄存器配置
    EXTI->IMR	|=	(0x01<<X10_15);//开放来自13线的中断请求
	EXTI->EMR	&= ~(0x01<<X10_15);//屏蔽来自13线的事件请求
	EXTI->RTSR	&= ~(0x01<<X10_15);//屏蔽13线上升沿触发
	EXTI->FTSR	|=	(0x01<<X10_15);//允许13线下降沿触发
	EXTI->SWIER	&= ~(0x01<<X10_15);//使能模块级中断
    //NVIC控制器配置
    NVIC_SetPriorityGrouping(7-5);//第五组
    priority = NVIC_EncodePriority(7-5,1,2);//抢占1,响应2
    NVIC_SetPriority(EXTI15_10_IRQn,priority);//由于没有EXTI13,则使用EXTI15_10_IRQn中断号
    NVIC_EnableIRQ(EXTI15_10_IRQn);//使能中断线
}

3.4 软件中断

软件中断即利用产生软件中断事件来发起中断,例如当需要软件中断时,设置软EXTI的挂起寄存器为1,则可以直接进入软件中断服务函数

3.4.1 配置EXTI寄存器

  1. 上升/下降沿触发器置0
  2. 软件中断事件寄存器置1
  3. 事件屏蔽寄存器置0
  4. 中断屏蔽寄存器置1

3.4.2 配置NVIC控制器

按内部中断的方法配置NVIC控制器,但中断源是外部中断线EXTI

且配置软件中断时,EXTI线可以任意选,但尽量避开有其他中断的线

例:配置EXTI7线能够产生软件中断

中断为第五组,抢占优先级为0,响应优先级为2

void software_Init(Void)
{
    u32 temp;//用于配置NVIC优先级
    
    //上升/下降沿触发器置0
    EXTI->RTSR &= ~(0x01<<7);
    EXTI->FTSR &= ~(0x01<<7);
    //软件中断事件寄存器置1
    EXTI->SWIER |= (0x01<<7);
    //事件屏蔽寄存器置0
    EXTI->EMR &= ~(0x01<<7);
    //中断屏蔽寄存器置1
    EXTI->IMR |= (0x01<<7);
    
    NVIC_SetPriorityGrouping(7-5);//分组设置
    temp = NVIC_EncodePriority(7-5,0,2);//得到优先级序列
    NVIC_SetPriority(EXTI9_5_IRQn,temp);//设置优先级
    NVIC_EnableIRQ(EXTI9_5_IRQn);//使能中断线
}

3.5 中断服务函数

在中断初始化后,就可以使用中断服务函数,即产生中断时立即跳入中断服务函数执行相应的任务

3.5.1 片上外设的中断服务函数

STM32F4的片上外设一般都有自己的中断标志位,例如USART1的CR1寄存器中就有相应的中断标志位,该位一般都由硬件置一,比如读取到数据寄存器不为空时,USART_CR1中的RXNEIE就会置一并产生中断

  1. 在<startup_stm32f40_41xxx.s>文件里找到相应的中断服务函数名
  2. 判断是由哪一个中断标志位进入的中断并**清除标志位**
  3. 编写该中断所需要的功能

注意:中断服务函数一定要去复制粘贴,不要自己写

例:USART1的中断服务函数,由该中断服务函数得到主机发送来的一个字符串并存储

char usart1_str[255];//全局变量,用于存储字符串
void USART1_IRQHandler(void)
{
    static u8 i = 0;
    u8 ch;
    
    if(USART1->SR & (0x01<<5))//若是由读取数据寄存器产生的中断
    {
        usart1_str[i++] = USART1->DR;//读取字符,在读取的时候顺便清除了标志位
        if(i == 255)
        {
            i = 0;
        }
    }
    if(USART1->SR & (0x01<<4))//若是由于检测到空闲线路产生的中断
    {
        ch = USART1->DR;//清空标志位
        usart1_str[i] = '\0';//使之成为字符串
        i = 0;
    }
}

3.5.2 片外外设中断服务函数

由于片外外设(按键,指纹模块等)没有中断标志位,故采用边沿检测的方法来触发中断

  1. 在<startup_stm32f40_41xxx.s>文件里找到相应**中断线**的中断服务函数名
  2. 判断是由哪条中断线产生的中断并**清除标志位**
  3. 编写该中断所需要的功能

例:按键按下触发外部中断线13产生中断并使LED3切换状态

void EXTI15_10_IRQHandler(void)
{
    if(EXTI->PR & (0x01<<13))//如果是由线13(Key2---PC13)产生的中断
    {
        EXTI->PR |= (0x01<<13);//写1清除
        LED_TUN(3);
    }
}

3.5.3 软件中断服务函数

软件中断由于不是由硬件触发,所以软件中断的触发条件是在需要时调用,跟普通函数很像,但可以设置高优先级以保护软件中断服务函数不被其他中断打断

  1. 在需要软件中断的地方设置EXTI_PR寄存器为1以触发软件中断
  2. 在<startup_stm32f40_41xxx.s>文件里找到相应**中断线**的中断服务函数名
  3. 判断是由哪条中断线产生的中断并**清除标志位**
  4. 编写该中断所需要的功能

例:在USART1中断服务函数里,当字符接收完后,调用软件中断

该软件中断功能:比较USART1得到的字符串与目标字符串是否一致,一致则做相应操作

/**************************USART1中断服务函数里***************************************/
char usart1_str[255];//全局变量,用于存储字符串
void USART1_IRQHandler(void)
{
    static u8 i = 0;
    u8 ch;
    
    if(USART1->SR & (0x01<<5))//若是由读取数据寄存器产生的中断
    {
        usart1_str[i++] = USART1->DR;//读取字符,在读取的时候顺便清除了标志位
        if(i == 255)
        {
            i = 0;
        }
    }
    if(USART1->SR & (0x01<<4))//若是由于检测到空闲线路产生的中断
    {
        ch = USART1->DR;//清空标志位
        usart1_str[i] = '\0';//使之成为字符串
        i = 0;
        EXTI->PR |= (0x01<<7);//调用中断线7的软件中断
    }
}
/*********************************************************************************/

//软件中断服务函数
void EXTI9_5_IRQHandler(void)
{
    if(EXTI->PR & (0x01<<7))//若是由线7产生的软件中断
    {
        EXTI->PR |= (0x01<<7);//写1清除标志位
        if(EXTI->PR & (1<<7))
        {
            //清除标志位
            EXTI->PR |= (1<<7);
            if(strcmp(usart1_str,"open") == 0)
            {
                LED_ON(3);
                LED_ON(4);
                motor_drive(OPEN);
            }else if(strcmp(usart1_str,"lock") == 0)
            {
                LED_OFF(3);
                LED_OFF(4);
                motor_drive(LOCK);
            }else
            {
                printf("请重新输入!\r\n");
            }
        }
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

STM32F4中断(Interrupt)详解 的相关文章

  • 64 位 Windows 中的汇编系统调用

    我使用的是 Windows 10 安装了 Cygwin 我一直使用 Cygwin 来使用 Cygwin 安装的 gcc 和 nasm 来编译 汇编 c 和汇编程序 据我所知 nasm有一个 f win64模式 因此它可以汇编64位程序 现在
  • 在 MCU 内部 FLASH 中从一个固件跳转到另一个固件

    我目前正在开发针对 STM32F030C8 的引导加载程序固件应用程序 我在分散文件中指定引导加载程序应用程序将占用主内存位置 0x08000000 到 0x08002FFF 扇区 0 到扇区 2 我还编写了一个主固件应用程序 存储在0x0
  • mpirun 的自定义中断处理程序

    显然 mpirun使用 SIGINT 处理程序将 SIGINT 信号 转发 到它生成的每个进程 这意味着您可以为启用 mpi 的代码编写一个中断处理程序 执行mpirun np 3 my mpi enabled executable然后将为
  • 只在 ISR 中读取的变量是否为 易失性?

    Is volatile需要一个在主循环中读写但在 ISR 中只读的变量吗 编辑 在编写 main 时 ISR 被禁用 因此 该变量被有效地原子地使用 EDIT 非常相关 中断的易失性与内存屏障 volatile是一种不好的同步访问方式 这是
  • 使用 Turbo C++ 3.0 处理键盘中断

    我有一个项目 那是一个简单的游戏 落块 游戏区域被视为一个网格 其大小为 20x20 屏幕顶部会有掉落的方块 底部有一个英雄 他会射击方块 游戏的目标是在方块到达底线之前将其射出 他始终坚守在底线 每当用户按下键盘的空格键时 我都会生成一个
  • 如何用中断串口读取串口?

    我正在尝试在 Linux 中读取 NMEA 消息 但我无法得到完整的消息 54 441 V 0 00 0 00 010720 N 42 GPVTG 0 00 T M 0 00 N 0 00 K N 32 GPGGA 020954 441 0
  • 如果段错误不可恢复,为什么将其称为错误(而不是中止)?

    我对术语的以下理解是这样的 1 中断是由硬件发起的 通知 用于调用操作系统运行其处理程序 2 陷阱是由软件发起的 通知 用于调用操作系统运行其处理程序 3 故障是处理器在发生错误但可恢复时引发的异常 4 中止是处理器在发生错误但不可恢复时引
  • 如何在 C 或内联汇编中设置 ARM 中断向量表分支?

    有人可以向我展示如何在没有 RTOS 或 Linux 操作系统的裸机环境中使用 C 或内联汇编设置 ARM9 中断向量表的示例吗 具体来说 如何使用内联汇编或 C 来设置用 C 编码的 IRQ 中断处理程序 ISR 的分支 timer1 6
  • 线程是否需要处于 RUNNABLE 状态才能被中断?

    java中的线程在被中断方法中断之前是否必须处于就绪状态 我尝试通过在下面输入上面给出的代码来检查这一点 class MyThread extends Thread public void run try for int i 0 i lt
  • IRQ 合并之前 NAPI 有哪些优点?

    众所周知 有两种方法可以避免高负载网络中硬件中断的一些开销 当硬件中断太多时 切换到它们会花费太多时间 这对于性能和程序风格的选择非常重要 NAPI 新API http en wikipedia org wiki New API 不使用硬件
  • 中断屏蔽:为什么?

    我正在阅读有关中断的内容 可以通过特殊的中断屏蔽来暂停非关键中断 这称为中断屏蔽 我不知道的是您何时 为什么可能想要或需要暂时中止中断 可能是信号量 或者在多处理器环境中编程 当操作系统准备运行自己的 让我们编排世界 代码时 它就会这样做
  • 在中断例程中使用 C++ 对象(和易失性对象)的正确方法是什么?

    我目前正在使用 Atmel AVR 微控制器 gcc 但希望答案适用于一般微控制器世界 即通常是单线程但带有中断 我知道如何使用volatile在 C 代码中访问可在 ISR 中修改的变量时 例如 uint8 t g pushIndex 0
  • 如何在 16 位 x86 实模式下通过 BIOS 访问 USB 端口?

    我是装配世界的新手 我正在尝试编写一些汇编代码来与串行 并行 VGA 键盘等硬件设备进行通信 我在 x86 intel 处理器的实模式下执行此操作 通过从我亲自编写的用于加载汇编代码的 boostrap 启动我的代码 嗯 根据我从阅读教程中
  • 软件生成的中断和软件生成的异常有什么区别?

    我正在阅读英特尔手册 3A 第 6 章中断和异常处理 中断和异常分别有3个来源 对于软件生成的中断 它说 INT n 指令允许从内部产生中断 软件通过提供中断向量号作为操作数 为了 例如 INT 35 指令强制隐式调用 中断 35 的中断处
  • 从没有中断引脚并且在测量准备好之前需要一些时间的传感器读取数据的最佳方法

    我正在尝试将压力传感器 MS5803 14BA 与我的板 NUCLEO STM32L073RZ 连接 根据 第 3 页 压力传感器需要几毫秒才能准备好读取测量值 对于我的项目 我对需要大约 10 毫秒来转换原始数据的最高分辨率感兴趣 不幸的
  • Java 硬件中断处理

    我想知道当硬件中断发生时是否可以自动调用Java方法 可能还有其他选择 我正在做类似的事情 在一个应用程序中 我监视 4 只鼠标的点击情况 这些点击会产生中断 但我很高兴不直接从 Java 处理它们 在Linux下 原来有设备文件 dev
  • request_threaded_irq 的“处理函数”中的 I2c 读取和写入操作如何影响整个驱动程序?

    我有一个带有 request threaded irq 的处理函数和线程函数的驱动程序代码 与此类似 irq handler fn disable device interrupt i2c read from register set di
  • 处理器处理中断的速度有多快

    我正在研究中断 因此 大多数架构都是中断驱动的 如果一切都是中断驱动的 那么处理器处理所有这些的速度有多快 例如 当按下键盘按键时 它会创建一个中断 要求内核在缓冲区中查找新字符 在这种情况下 处理器的服务速度有多快 而且当发出中断时 处理
  • 无滴答内核、isolcpus、nohz_full 和 rcu_nocbs

    我在 grub conf 中添加了 isolcpus 3 nohz full 3 rcu nocbs 3 RedHat 7 1 内核 linux 3 10 0 229 内核并根据http www breakage org 2013 11 1
  • C# 是否可以中断 ThreadPool 内的特定线程?

    假设我已将一个工作项排入队列ThreadPool 但是如果没有要处理的数据 从BlockingQueue 如果队列为空并且队列中不再有工作 那么我必须调用Thread Interrupt方法 如果我想中断阻塞任务 但是如何用 a 做同样的事

随机推荐

  • 换个角度聊聊PID吧,很干。

    01 前言 大家好 xff0c 前面发了几篇关于PID的文章 xff1a 点击图片即可阅读 教你10分钟完成智能小车的PID调速 快速调试PID参数的3种方法 02 自动控制系统 在直流有刷电机的基础驱动中 xff0c 如果电机负载不变 x
  • linux发起http请求,GET、POST

    GET请求 curl 推荐 curl v 34 https test com login username 61 tyw amp password 61 123 34 curl 34 https test com 34 URL指向的是一个文
  • VSCode对C++的DEBUG调试配置

    C 43 43 vscode上的调试配置 1 调试配置2 修改编译模式 按照本 的流程可在vscode平台上实现像在windows系统下VS调试C 43 43 程序的效果 1 调试配置 当写好代码和 CMakeLists txt 之后 xf
  • VSCode的C/C++扩展功能

    VSCode的C C 43 43 扩展功能 1 在 Linux 上 使用 C 43 43 1 1 创建 Hello World1 2 探索 IntelliSense1 3 构造 helloworld cpp1 3 1 运行 build1 3
  • 从源码理解智能指针(二)—— shared_ptr、weak_ptr

    目录 计数器 Ref count Ref count del Ref count del alloc Ptr base Ptr base的成员变量 构造函数 赋值重载 获取引用计数 减少引用计数 Reset函数 Resetw函数 share
  • muduo源码学习(1):异步日志——日志消息的存储及输出

    目录 前言 日志存储的实现 日志输出的实现 总结 前言 muduo中的日志 xff0c 是诊断日志 用于将代码运行时的重要信息进行保存 xff0c 方便故障诊断和追踪 日志一般有两种 xff0c 一种是同步日志 xff0c 一种是异步日志
  • muduo源码学习(2):异步日志——异步日志的实现

    目录 什么是异步日志 异步日志的实现 前端与后端 前端与后端的交互 资源回收 后端与日志文件 滚动日志 自动flush缓冲区 开启异步日志功能 总结 在前文中分析了日志消息的存储和输出 xff0c 不过并没有涉及到异步日志 xff0c 下面
  • muduo异步日志——core dump后查找还未来得及写出的日志

    目录 前言 生成core文件 gdb调试Core文件 前言 通过异步日志的实现可以知道 xff0c 日志消息并不是生成后立刻就会写出 xff0c 而是先存放在前端缓冲区currentBuffer或者前端缓冲区队列buffers中 xff0c
  • C++知识积累:成员函数运算符重载与非成员函数运算符重载

    运算符重载 xff0c 是C 43 43 多态的表现形式之一 xff0c 可以通过对运算符进行重载来实现运算符特定的功能 运算符重载一般具有以下原则 xff1a xff08 1 xff09 不可重载不存在的运算符 xff0c 如重载 来表示
  • (二叉树)二叉树的最近公共祖先

    题目描述 给定一个二叉树 找到该树中两个指定节点的最近公共祖先 百度百科中最近公共祖先的定义为 xff1a 对于有根树 T 的两个结点 p q xff0c 最近公共祖先表示为一个结点 x xff0c 满足 x 是 p q 的祖先且 x 的深
  • 有符号数、无符号数理解

    大家都知道 xff0c 在C C 43 43 中 xff0c 对于w位编译器 xff0c 其有符号数表示的数值范围为 2 w 1 2 w 1 1 xff0c 无符号数表示的数值范围为0 2 w 1 xff0c 举个例子 xff0c 在16位
  • ​PCB的 “ 黑科技 ” ,应该是这个。

    大家好 xff0c 我是张巧龙 xff0c 前段时间炒的很火的折叠屏手机不知道大家还记得不 xff1f 折叠屏手机之所以这么具有 34 韧性 34 xff0c 全靠背后的柔性电路板 FlexiblePrintedCircuit xff0c
  • 指针数组、数组指针——用指针访问数组方法总结

    目录 1 数组元素的访问 2 通过指针访问数组 2 1 通过指针访问一维数组 2 2 通过指针访问二维数组 2 2 1 指向元素的指针 2 2 2 指向每一行的指针 xff08 指针数组方式 xff09 2 2 3 指向整个数组的指针 xf
  • C++知识积累:如何获取虚函数表以及虚函数地址

    如果一个类中存在虚函数的话 xff0c 那么编译器就会为这个类生成一个虚函数表 xff0c 这个虚函数表中按照个虚函数的声明顺序存放了各个虚函数的地址 xff0c 需要注意的是 xff0c 这个虚函数表并不存在于类中 xff0c 而对于这个
  • C++多线程:互斥锁

    目录 1 前言 2 互斥锁 2 1 互斥锁的特点 2 2 互斥锁的使用 2 2 std lock guard 3 死锁 3 1 死锁的含义 3 2 死锁的例子 3 3 死锁的解决方法 1 前言 比如说我们现在以一个list容器来模仿一个消息
  • Linux下MySQL中文显示问号乱码问题解决

    本文主要针对于Linux下MySQL插入中文数据显示问号的问题 网上一种普遍使用的方法是修改 etc my cnf文件 xff08 我的这个文件位于 etc mysql my cnf xff09 xff0c 修改步骤如下 xff1a 1 在
  • Linux下更改文件权限

    目录 查看文件权限 修改文件权限 查看文件权限 查看文件权限可以通过ls l命令查看 xff0c 如下所示 xff1a 如果只想查看某一个文件的权限 xff0c 可以使用grep xff0c 如下所示 xff1a 可以发现 xff0c 每一
  • 【蓝桥杯算法提高VIP-开灯游戏(两种超易理懂解法:暴力/位操作(切换位))(纯正C语言代码)】

    蓝桥杯算法提高VIP 开灯游戏 题目描述 有9盏灯与9个开关 xff0c 编号都是1 9 每个开关能控制若干盏灯 xff0c 按下一次会改变其控制的灯的状态 亮的变成不亮 xff0c 不亮变成亮的 具体如下 xff1a 第一个开关控制第二
  • C语言二叉查找树(图文详解)(超详细)

    二叉查找树 本人在第一次学习二叉树的时候 感觉很懵懵懂懂 勉强知道了二叉树的结构和查找方式 但要我自己去动手写的时候 可是难上加难 所以这里我用干货 43 实际例子的方式让你上手二叉树 这个例子几乎可以套用到所有链式结构问题 我们开始吧 文
  • STM32F4中断(Interrupt)详解

    STM32F4中断 Interrupt 详解 文章目录 STM32F4中断 Interrupt 详解一 中断是什么 二 STM32的中断体系2 1 STM32的中断分类2 2 STM32中断优先级2 2 1 抢占优先级2 2 2 响应优先级