中断控制器

news2024/11/16 13:47:00

1. 中断的理解

1.1 什么是中断

中断:  通常指  某种事件(中断源)  触发了  需要打断CPU , 让CPU暂停当前处理的(保存现场) 任务(usr模式下)  打断(irq异常) 转而去处理  这个事件(在irq模式中)  ,事件处理结束后 需要回到(恢复现场)  打断处继续向后执行  

1.2  中断控制器的作用

中断控制器作用: 通用中断控制器 

1. 扩展中断接口  CPU--irq   中断控制器(GIC)   ----- 中断源 

2. 中断源管理  使能或不使能 某些中断 

3. 管理中断源 优先级  

4. 管理 中断送哪个CPU处理  (多核处理器)

(NVIC) 嵌套向量中断控制器 

5. 中断嵌套   高优先级的中断 将 可以打断 低优先级的程序执行 

中断系统: 是CPU实现 异步功能的 必要设备  

1.3 中断控制器:  原理 

如图所示 内部结构

1.4 中断挂起

指中断触发时, 中断控制器或中断源本身, 将中断信号记录到一个寄存器(挂起寄存器)中若挂起寄存器中  有中断被挂起了, 表示 该中断触发了,但还没有处理或正在处理中 处理完中断后 应立即清除中断挂起, 否则该挂起的中断 将会持续尝试打断CPU 

若有多个地方存在中断挂起 清除中断时 应 先清除先挂起的中断寄存器 

3. 实验4 按键中断实验

3.1 原理图

实验4:  按键中断实验 :  使用中断法 实现 按键点击 控制LED 亮灭  

1. 硬件设备  

KEY  按键  使用 K2  ===>  GPX1_1  

2. 电路图  

使用 K2  ===>  GPX1_1  

3. 控制器   

外部中断:  中断信号来源于芯片外部  通过GPIO进入芯片内部 如 按键  一些模块  

内部中断:  中断信号来源于芯片内部  由控制器触发的 如 串口中断  定时器中断  ....

外部中断 经过了 GPIO控制器 传入

3.2 配置寄存器

配置寄存器   参考图片 

中断号:  就是芯片制造厂商 对 芯片中 所有的中断源 进行的 一个编号 

749 页  9.2.2 章节  Table 9-2 GIC Interrupt Table (SPI[127:0])

3.2.1 寄存器配置:  GPX1_1

GPX1_1 中断输入模式

GPX1CON[1]  [7:4] = 0xF = WAKEUP_INT1[1]   外部中断输入模式 

EXT_INT41_CON 中断触发模式

GPX1  对应   EXT_INT41_CON  (子啊比如GPX2----EXT_INT40_CON,以此类推)

EXT_INT41_CON [1]:  367 页   配置中断触发模式  

低电平触发 

高电平触发

上升沿触发  [6:4] = 0x3  上升沿触发

下降沿触发 

边沿触发 

EXT_INT41_MASK  中断屏蔽寄存器

EXT_INT41_MASK:  GPIO中断屏蔽寄存器

EXT_INT41_MASK [1] = 0  使能中断  

3.2.2 GIC配置 面向中断源

ICDDCR 总中断使能

ICDDCR  总中断使能寄存器  = 1使能  打开总中断

ICDISER 端口中断使能

ICDISER_CPU: 配置端口中断使能寄存器 ,就是配置哪些中断源能够使能,哪些不能

该寄存器 存储了 所有的 中断端口的 使能情况 共 0-4 个寄存器

其中 0 号寄存器存储 CPU 的  PPI (私有中断SGI  (软件中断)

1-4号 存储的 是 SPI 共享中断的 使能情况  

GPX1_1  的SPI 端口是什么???

通过 中断源表 查询可得  GPX1_1 --- EINT[9] ---- ID(57) --- SPI中断端口号 25

57号 中断ID  在 ICDISER_CPU 的1号寄存器 的  [25]bit 

若中断ID为 x  问 ICDISER_CPU 配置 第几号 的 多少bit位  

寄存器号 = 中断ID / 32 的商    对应bit = 中断ID % 32

ICDIPR  端口优先级配置寄存器

ICDIPR: 端口优先级配置寄存器  每个端口 8bit 宽度 优先级范围 0-255

0-39 共40个寄存器 

0-7  用于配置 SGI 和 PPI 

8-38 配置  SPI 

实际管脚对应的 寄存器号 = 中断ID / 4 的商    对应bit位域 = 中断ID % 4

余0  [7:0]   余1 [15:8]   余2[23:16]   余3 [31:24]

ICDIPTR 中断源 送哪个cpu

ICDIPTR_CPU: 用于配置 中断源 送哪个或哪些CPU处理 

寄存器分步格局 与ICDIPR 完全一样 

8bit 每个bit 分别表示要送哪个CPU  

3.2.3 GIC 面向cpu

ICCICR 中断响应使能寄存器

ICCICR   CPU中断响应使能寄存器   = 1 使能   =0 不使能

ICCPMR  优先级过滤寄存器  

ICCPMR   优先级过滤寄存器        

3.3 写程序

1. 配置必要寄存器 

2. 打开 do_irq 的 注释 

3. 实现 do_irq 函数 

注意

打开start.S文件修改,如下

ICCIAR 获取中断号

访问CPU0.ICCIAR寄存器得到中断号

EXT_INT41_PEND 清除中断 源头的挂起 

ICDICPR 在清除GIC分配器层中断挂起

ICCEOIR 清除cpu中断挂起

key_exit-----> main


#include"exynos_4412.h"
#include"uart.h"

void key_exit_init(){
    //GPIO     key2    GPX1_1
    //1. 配置引脚为外部中断输入模式
    GPX1.CON = (GPX1.CON & ~(0xf<<4)) | (0xf << 4);
    
    //2. 配置中断触发模式 这里配置为上升沿触发 [6:4] = 0x3
    EXT_INT41_CON = (EXT_INT41_CON & ~(0x7<<4)) | (0x3 << 4);
    
    //3. 配置中断掩码屏蔽寄存器
    //配置为使能中断 [1] = 0
    EXT_INT41_MASK &= ~(1<<1);


    // gic 面向中断源
    //4. 打开总中断
    //[0] = 1
    ICDDCR = 1; 

    //5. 配置端口中断使能寄存器 
    //就是配置哪些中断源能够使能,哪些不能
    //找到中断源的 中断号(57)寄存器编号1=57/32(即ICDISER1)  端口号(25=57%32)
    //配置为 1  使能
    ICDISER.ICDISER1 |= 1<<25;

    //6. 端口优先级设置寄存器 ,这里我们设置优先级为  5
    //14 = 57/4  1=57%4  ---->[15:8]
    ICDIPR.ICDIPR14 = (ICDIPR.ICDIPR14 & ~(0xff<<8)) | (5 << 8);

    //7. 配置中断源送去哪个cpu处理   0x1表示直送cpu0
    //寄存器分步格局 与ICDIPR 完全一样 
    ICDIPTR.ICDIPTR14 = (ICDIPTR.ICDIPTR14 & ~(0xff<<8)) | (0x1 << 8);


    //GIC 面向cpu
    //8. cpu响应中断使能  =1 使能  =0 不使能
    CPU0.ICCICR = 1;

    //9. cpu优先级过滤寄存器 这里我们设置为255 只有比255优先级还低的会被过滤,因为255至最低的优先级
    //我们前面设置的优先级为5 优先级高于255 所以不会被过滤
    CPU0.ICCPMR = 255;
}

//中断响应,c语言入口函数,在汇编汇总调用,当irq异常触发时
void do_irq(){
    // 1.获取中断号,用于区分哪个中断源触发的中断
    int irq_id = 0;
    //访问CPU0.ICCIAR寄存器得到中断号 说明CPU0.ICCIAR的[9:0]存储了中断号
    irq_id = CPU0.ICCIAR;
    printf("irq_id = %d\n",irq_id);
 
    //2.根据中断id来处理对应的事件
    switch(irq_id)
    {
        case 57:
            printf("key2 clicl!!!\n");
            //清除中断挂起 
            //先清除中断 源头的挂起 //GPX1_1  写1清除
            EXT_INT41_PEND |= 1<<1;
            
            //在清除GIC分配器层中断挂起 与ICDISER_CPU 结构一样 id:57
            //置为1  清除
            ICDICPR.ICDICPR1 |= 1<<25;
            break;
    }
    //最后清除cpu中断挂起
    //写入中断id清除对应中断挂起
    CPU0.ICCEOIR = irq_id;
    
}


int main()
{
    int a = 100;
    //初始化串口
    uart_init();

    //初始化中断
    key_exit_init();

    printf("hello!a=%d\r\n",a);
    while(1);
    return 0;
}


4. 使用中断 按下k2 控制led3亮灭

key2_led3---main.c


#include"exynos_4412.h"
#include"uart.h"
//中断的使用

//初始化led3
void led3_init(){
    //配置引脚模式
    GPX1.CON = (GPX1.CON & ~(0xf<<0)) | (0x1 << 0);
    //配置数据寄存器
    // GPX1.DAT |= 1;
    GPX1.DAT &= ~1;
    //配置上下拉寄存器
    GPX1.PUD &= ~(0x3<<0);
}



//初始化中断
void key_exit_init(){
    //GPIO     key2    GPX1_1
    //1. 配置引脚为外部中断输入模式
    GPX1.CON = (GPX1.CON & ~(0xf<<4)) | (0xf << 4);
    
    //2. 配置中断触发模式 这里配置为上升沿触发 [6:4] = 0x3
    EXT_INT41_CON = (EXT_INT41_CON & ~(0x7<<4)) | (0x3 << 4);
    
    //3. 配置中断掩码屏蔽寄存器
    //配置为使能中断 [1] = 0
    EXT_INT41_MASK &= ~(1<<1);


    // gic 面向中断源
    //4. 打开总中断
    //[0] = 1
    ICDDCR = 1; 

    //5. 配置端口中断使能寄存器 
    //就是配置哪些中断源能够使能,哪些不能
    //找到中断源的 中断号(57)寄存器编号1=57/32(即ICDISER1)  端口号(25=57%32)
    //配置为 1  使能
    ICDISER.ICDISER1 |= 1<<25;

    //6. 端口优先级设置寄存器 ,这里我们设置优先级为  5
    //14 = 57/4  1=57%4  ---->[15:8]
    ICDIPR.ICDIPR14 = (ICDIPR.ICDIPR14 & ~(0xff<<8)) | (5 << 8);

    //7. 配置中断源送去哪个cpu处理   0x1表示直送cpu0
    //寄存器分步格局 与ICDIPR 完全一样 
    ICDIPTR.ICDIPTR14 = (ICDIPTR.ICDIPTR14 & ~(0xff<<8)) | (0x1 << 8);


    //GIC 面向cpu
    //8. cpu响应中断使能  =1 使能  =0 不使能
    CPU0.ICCICR = 1;

    //9. cpu优先级过滤寄存器 这里我们设置为255 只有比255优先级还低的会被过滤,因为255至最低的优先级
    //我们前面设置的优先级为5 优先级高于255 所以不会被过滤
    CPU0.ICCPMR = 255;
}

//中断响应,c语言入口函数,在汇编汇总调用,当irq异常触发时
void do_irq(){
    // 1.获取中断号,用于区分哪个中断源触发的中断
    int irq_id = 0;
    //访问CPU0.ICCIAR寄存器得到中断号 说明CPU0.ICCIAR的[9:0]存储了中断号
    irq_id = CPU0.ICCIAR;
    printf("irq_id = %d\n",irq_id);
 
    //2.根据中断id来处理对应的事件
    switch(irq_id)
    {
        case 57:
            printf("key2 clicl!!!\n");

            GPX1.DAT ^= (1<<0); 


            //清除中断挂起 
            //先清除中断 源头的挂起 //GPX1_1 写1清除
            EXT_INT41_PEND |= 1<<1;

            //在清除GIC分配器层中断挂起 与ICDISER_CPU 结构一样 id:57
            //置为1  清除
            ICDICPR.ICDICPR1 |= 1<<25;
            break;
    }
    //最后清除cpu中断挂起
    //写入中断id清除对应中断挂起
    CPU0.ICCEOIR = irq_id;
    
}


int main()
{
    int a = 100;
    //初始化串口
    uart_init();

    led3_init();
    
    //初始化中断
    key_exit_init();

    printf("hello!a=%d\r\n",a);

    while(1);
    return 0;
}



5. 实现 K2  K3  K4的 中断程序 

key_led---main.c


#include"exynos_4412.h"
#include"uart.h"

//实现 K2  K3  K4的 中断程序
//延时函数
void delay(int m)
{
	int i;
	while(m--)
	  for(i=0; i < 10000 ; i++);
}

//中断初始化
void key_exti_init()
{
	//gpio
	//K2 --- GPX1-1 ----- ID 57
	//K3 --- GPX1-2 ----- ID 58
	//K4 --- GPX3-2 ----- ID 64
	//GPX1CON[1]  [7:4] = 0xF = WAKEUP_INT1[1]   外部中断输入模式 
	GPX1.CON |= 0xf<<4;
	GPX1.CON |= 0xf<<8;
	GPX3.CON |= 0xf<<8;

	//EXT_INT41_CON [1]: [6:4] = 0x3  上升沿触发
	EXT_INT41_CON = (EXT_INT41_CON & ~ ( 0x7<< 4)) | ( 0x3 << 4); 
	EXT_INT41_CON = (EXT_INT41_CON & ~ ( 0x7<< 8)) | ( 0x3 << 8); 
	EXT_INT43_CON = (EXT_INT43_CON & ~ ( 0x7<< 8)) | ( 0x3 << 8); 

	//GPIO中断屏蔽寄存器 [1] = 0  使能中断  
	EXT_INT41_MASK &= ~(1<<1); 
	EXT_INT41_MASK &= ~(1<<2); 
	EXT_INT43_MASK &= ~(1<<2); 

	//gic 面向中断源
	//ICDDCR  总中断使能寄存器  = 1使能 
	ICDDCR = 1;

	//ICDISER_CPU: 中断使能, GIC端口使能 中断ID 57
	//寄存器编号1 = 57/32 商  25 = 57 % 32
	ICDISER.ICDISER1 |= 1<<25;  // 57
	ICDISER.ICDISER1 |= 1<<26;  // 58
	ICDISER.ICDISER2 |= 1<<0 ;  // 64
	
	//端口优先级设置寄存器  14 == 57 /4商 
	ICDIPR.ICDIPR14 = (ICDIPR.ICDIPR14 & ~(0xff << 8))|(5  << 8);
	ICDIPR.ICDIPR14 = (ICDIPR.ICDIPR14 & ~(0xff << 16))|(5 << 16);
	ICDIPR.ICDIPR16 = (ICDIPR.ICDIPR16 & ~(0xff << 0))|(5  << 0);

	//ICDIPTR_CPU: 用于配置 中断源 送哪个或哪些CPU处理  1表示只送CPU0
	ICDIPTR.ICDIPTR14 = (ICDIPTR.ICDIPTR14 & ~(0xff <<8)) | ( 0x1<<8);
	ICDIPTR.ICDIPTR14 = (ICDIPTR.ICDIPTR14 & ~(0xff <<16)) | ( 0x1<<16);
	ICDIPTR.ICDIPTR16 = (ICDIPTR.ICDIPTR16 & ~(0xff <<0)) | ( 0x1<<0);

	//GIC 面向CPU
	//使能CPU0相应中断
	CPU0.ICCICR = 1;
	//优先级过滤寄存器 只有当优先级高于该值的中断源才可以送该CPU
	CPU0.ICCPMR = 255;
}
//中断相应 C语言入口函数 在汇编中被调用,当irq异常触发时
void do_irq(  )
{
	//如何区分哪个中断源触发的中断
	//1. 获得中断号 
	int irq_id = 0;
	irq_id = CPU0.ICCIAR;
	printf("irq_id=%d\r\n",irq_id); //打印调试  /r可以使超级终端光标回到起始位置
	//2. 根据中断id来处理对应的事件
	switch(irq_id)
	{
		case 57: // K2 id=57
			delay(1);//延时消抖
            //因为前面已经延时了一段时间,这里再判断一下管脚的电平,几乎可以确认到这里的是松开手的高电平了
			if(GPX1.DAT & (1<<1))//这里读取一下管脚的电平只有松开手时,触发高电平才可以进入if
			{
				printf("K2 click!\r\n");
			}
            // printf("K2 click!\n");
			//3. 中断处理完后 清楚中断挂起 
			//先清楚中断源头的挂起
			EXT_INT41_PEND |= 1<<1; //GPX1_1
			//在清楚GIC分配器层中断挂起 与 ICDISER_CPU 结果一样 id:57
			ICDICPR.ICDICPR1 |= 1<<25; 
			break;
		case 58:
            delay(1);//延时消抖
            if((GPX1.DAT & (1<<2))){
			    printf("K3 click!\n");
            }
			//先清楚中断源头的挂起
			EXT_INT41_PEND |= 1<<2; //GPX1_2
			//在清楚GIC分配器层中断挂起 与 ICDISER_CPU 结果一样 id:57
			ICDICPR.ICDICPR1 |= 1<<26; // id 58 
			break;
		case 64:
            delay(1);//延时消抖
            if((GPX3.DAT & (1<<2))){
                printf("K4 click!\n");
            }
			//先清楚中断源头的挂起
			EXT_INT43_PEND |= 1<<2; //GPX3_2
			//在清楚GIC分配器层中断挂起 与 ICDISER_CPU 结果一样 id:57
			ICDICPR.ICDICPR2 |= 1<<0; // id 64 
			break;
	//case .... 
	
	}
	//最后清除CPU中断挂起 
	//写入中断id 清除对应中断挂起
	CPU0.ICCEOIR = irq_id;
}

int main()
{
    int a = 100;
    uart_init();
	key_exti_init();

    printf("hello!a=%d\r\n",a);
    while(1);
    return 0;
}


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

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

相关文章

程序员如何应对中年危机

中年危机是一个普遍存在的问题&#xff0c;不仅仅局限于程序员这个职业。不过&#xff0c;对于程序员来说&#xff0c;由于技术更新迅速&#xff0c;中年危机可能更加明显。以下是一些应对中年危机的建议&#xff1a; 持续学习新技术和工具&#xff1a;计算机技术发展迅速&…

特殊类的设计(含单例模式)

文章目录 一、设计一个不能被拷贝的类二、设计一个只能在堆上创建的类三、设计一个只能在栈上创建的类四、设计一个不能被继承的类五、单例模式1.懒汉模式2.饿汉模式 一、设计一个不能被拷贝的类 拷贝只会放生在两个场景中&#xff1a;拷贝构造函数以及赋值运算符重载&#xf…

MySQL介绍、安装和卸载

MySQL介绍、安装和卸载 1. 数据库基本概念2. 数据库类型和常见的关系型数据库2.1 数据库类型2.2 常见的关系型数据库 3. MySQL介绍4. MySQL8的安装和卸载 1. 数据库基本概念 1. 数据 所谓数据&#xff08;Data&#xff09;是指对客观事物进行描述并可以鉴别的符号&#xff0c;…

(四)流程控制ifelse

文章目录 if else用法示例1演示1示例2演示2示例3演示3示例4演示4 逻辑与或非示例1演示1示例2演示2示例3演示3 if elseif else示例1演示1示例2演示2 if else 用法 if(条件表达式成立或为真){ //执行里面 }else{ //否则执行这里面 } 这里:条件表达式成立或为真&#xff0c;数值…

《WebKit 技术内幕》学习之十五(6):Web前端的未来

6 Chromium OS和Chrome的Web应用 6.1 基本原理 HTML5技术已经不仅仅用来编写网页了&#xff0c;也可以用来实现Web应用。传统的操作系统支持本地应用&#xff0c;那么是否可以有专门的操作系统来支持Web应用呢&#xff1f;当然&#xff0c;现在已经有众多基于Web的操作系统&…

环形链表的检测与返回

环形链表 王赫辰/c语言 - Gitee.com 快慢指针的差距可以为除一以外的数吗&#xff1f;不可以如果差奇数则无法发现偶数环&#xff0c;是偶数无法发现奇数环&#xff0c;本题思路为指针相遇则为环&#xff0c;而以上两种情况会稳定差一&#xff0c;导致指针永不相遇 最终返回…

<蓝桥杯软件赛>零基础备赛20周--第19周--最短路

报名明年4月蓝桥杯软件赛的同学们&#xff0c;如果你是大一零基础&#xff0c;目前懵懂中&#xff0c;不知该怎么办&#xff0c;可以看看本博客系列&#xff1a;备赛20周合集 20周的完整安排请点击&#xff1a;20周计划 每周发1个博客&#xff0c;共20周。 在QQ群上交流答疑&am…

单片机学习笔记---独立按键控制LED亮灭

直接进入正题&#xff01; 今天开始我们要学习一个新的模块&#xff1a;独立按键&#xff01; 先说独立按键的内部结构&#xff1a; 它相当于一种电子开关&#xff0c;按下时开关接通&#xff0c;松开时开关断开&#xff0c;实现原理是通过轻触按键内部的金属弹片受力弹动来实…

深度学习知识

context阶段和generation阶段的不同 context阶段&#xff08;又称 Encoder&#xff09;主要对输入编码&#xff0c;产生 CacheKV(CacheKV 实际上记录的是 Transformer 中 Attention 模块中 Key 和 Value 的值&#xff09;&#xff0c;在计算完 logits 之后会接一个Sampling 采…

CC++内存管理【非常详细,对新手友好】

文章目录 一、程序内存划分1.基础知识2. 堆栈的区别3. 题目练手 二、C语言中动态内存管理方式三、C中动态内存管理方式1. new/delete操作内置类型2. new/delete操作自定义类型 四、operator new和operator delete函数1. 汇编查看编译器底层调用2. 透过源码分析两个全局函数 五、…

GD32移植FreeRTOS+CLI过程记录

背景 之前我只在STM32F0上基于HAL库和CubeMX移植FreeRTOS&#xff0c;但最近发现国产化替代热潮正盛&#xff0c;许多项目都有国产化器件指标&#xff0c;而且国产单片机确实比意法的便宜&#xff0c;所以也买了块兆易创新的GD32F303开发板&#xff0c;试一试它的优劣。虽然GD…

【开源】基于JAVA的班级考勤管理系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 系统基础支持模块2.2 班级学生教师支持模块2.3 考勤签到管理2.4 学生请假管理 三、系统设计3.1 功能设计3.1.1 系统基础支持模块3.1.2 班级学生教师档案模块3.1.3 考勤签到管理模块3.1.4 学生请假管理模块 3.2 数据库设…

【系统备份/迁移】解决克隆win10系统分区后,进系统黑屏、有鼠标指针(无需修改注册表)

【解法】简单来说就是&#xff0c;在PE系统中修复引导&#xff0c;修复成功后再进入系统就正常了。 1、问题 笔者通过DiskGenius克隆系统分区来备份自己的win10系统。克隆完成后&#xff0c;进入新系统里&#xff0c;发现是黑屏&#xff0c;移动鼠标时可以看到鼠标指针&#x…

通过铭文赛道的深度链接,XDIN3 与 opBNB 的双向奔赴

​进入到 2024 年以来&#xff0c;随着铭文市场基建设施的不断完善&#xff0c;铭文正在被赋予捕获价值与流动性的能力&#xff0c;并且铭文投资者们也正在趋于理性&#xff0c;这也意味着铭文赛道正在向价值回归的全新方向发展。 XDIN3 是推动铭文资产捕获价值的重要基建设施&…

第7章 面向对象基础(下)

第7章 面向对象基础&#xff08;下&#xff09; 学习目标 会区分静态的类变量和非静态的实例变量 会区分静态的类方法和非静态的实例方法 了解类初始化 认识枚举类型 会使用枚举类型 认识包装类 会使用包装类进行处理字符串 会分析包装类的相关面试题 能够声明抽象类 能够说出…

ZigBee学习——浅析协议栈

✨记录学习过程 文章目录 一、初识OSAL1.1 Z-Stack和Zigbee的OSAL是什么关系&#xff1f;1.2 OSAL可以解决Z-stack在不同厂商的芯片上的使用吗&#xff1f; 二、协议栈运行机制2.1 初始化涉及内容2.2 初始化过程 一、初识OSAL OSAL&#xff0c;全称是操作系统抽象层&#xff0…

【驱动系列】C#获取电脑硬件显卡核心代号信息

欢迎来到《小5讲堂》&#xff0c;大家好&#xff0c;我是全栈小5。 这是《驱动系列》文章&#xff0c;每篇文章将以博主理解的角度展开讲解&#xff0c; 特别是针对知识点的概念进行叙说&#xff0c;大部分文章将会对这些概念进行实际例子验证&#xff0c;以此达到加深对知识点…

代码随想录算法训练营day4 | 链表(2)

一、LeetCode 24 两两交换链表中的节点 题目链接&#xff1a;24.两两交换链表中的节点https://leetcode.cn/problems/swap-nodes-in-pairs/ 思路&#xff1a;设置快慢指针&#xff0c;暂存节点逐对进行交换。 代码优化前&#xff1a; /*** Definition for singly-linked list…

总结和考试

总结和考试 1. 代码规范1.1 名称1.2 注释1.3 todo1.4 条件嵌套1.5 简单逻辑先处理1.6 循环1.7 变量和值 2.知识补充2.1 pass2.2 is 比较2.3 位运算 3.阶段总结4.考试题 1. 代码规范 程序员写代码是有规范的&#xff0c;不只是实现功能而已。 1.1 名称 在Python开发过程中会创…

EndNote20 添加GBT7714文献格式

GBT 7714格式是中国国家标准《文后参考文献著录规则》的规定&#xff0c;用于指导学术论文、期刊文章等文献的参考文献著录。GBT 7714标准规定了参考文献的格式、内容和著录要求&#xff0c;以确保文献的一致性和标准化。 在EndNote 20中&#xff0c;若需要按照GBT 7714格式在W…