-
2020-12-28 21:29:32
外部中断NMI中断.ppt
* 1、先看其引脚结构再看功能1。 可编程的含义:通过对芯片编程,使芯片实现不同的功能。 中断比较多的情况下,使用中断控制器来管理中断。 用来管理系统的硬件中断。 * 1、数据总线驱动器 和CPU的DB相连,用于传送CPU给8259的命令字、8259的状态字、和中断类型号n。 2、读写控制逻辑接收CPU送来的读写命令信号、片选信号、端口选择信号A0。A0用来选择8259的两个地址,奇地址和偶地址。注意:片选线CS用来区别哪一个芯片工作,而地址线A0用来选择不同的端口。在可编程接口芯片中都存在这个规律。 3、级联缓冲比较器:8259和系统的链接有两种方式:缓冲方式和非缓冲方式。8259A,可以直接接在数据总线上叫做非缓冲方式。这时候SP、EN引脚用来做输入端,如果=1,则8259为主片,如果为0则变为从片。如果是单片8259 则该引脚接高电平。缓冲方式,指8259通过总线驱动器和数据总线相连。 * DIP封装 28引脚的芯片。 一方面考虑 管脚 什么功能?和谁相连?输入输出? * 优先级固定方式:中断优先级分别为0-7级,IR0具有最高优先级,IR7优先级最低。 特殊全嵌套方式用于级联的情况,当主片的IR0引脚上有中断请求,已经响应该中断。当IR0引脚上的从片的另一引脚也产生中断请求,对主片来说就出现了同级中断响应,但是也能分出优先级的高低。 * * 特殊屏蔽方式用途及使用方法 用途:希望一个中断服务程序能动态地改变系统的优先级结构。 例如:当CPU正在处理中断程序的某一部分时,希望禁止低级中断请求,但在执行中断服务程序的另一部分时,希望开放较低级中断请求,此时可采用特殊屏蔽方式。通过OCW3设置/取消特殊屏蔽方式。在特殊屏蔽方式下,如果屏蔽某一级中断(通过OCW1置位IMR寄存器中的某位),则其ISR相应位清“0”,这样就开放了低级的中断。 功能:此方式可以实现对本级中断进行屏蔽,而允许优先级比它高或者低的中断进入。 * 中断结束处理,事实上是对ISR中对应位的处理。什么时候对ISR中正在服务的中断位清零,决定了结束方式的不同。 通常可以有三种结束方式: 自动中断结束方式是处理器一进入中断过程,8259A自动将ISR中对应位清零。 普通结束方式:CPU用输出指令往8259A发EOI命令时清零ISR中对应位。即设置OCW2. 特殊中断结束方式:CPU在程序中向8259A发中断结束命令。 注意:ISR中正在服务的中断位清零(中断结束)和中断服务程序结束 是两个不同的概念,二者时间可以不一致。但一般要求的理想情况要一致为好。所以自动结束方式通常不使用。 * 1、关于8259A的编程主要有三个方面: 初始化命令字的写入,即ICW1~ICW4的写入 操作命令字的使用,OCW1~OCW3 工作状态信息的读取,包括读取IRR、ISR、IMR三个寄存器和1个查询字。 2、初始化命令字写入寄存器:ICW1~ICW4 ,由初始化程序设置。一经写定,在系统工作过程中不再更改 操作命令字写入寄存器:OCW1~OCW3。由应用程序设定,控制中断处理过程,在系统工作过程中可以重新设置 * * MOV AL,40h OUT 21H,AL * 问题:如何区别主片和从片呢?答:主片和从片的地址是不同的。用地址区分。 (1)完全嵌套方式(默认): 特点:固定0-7级,IR0级别最高,IR7级别最低。 (2)特殊全嵌套方式:用于8259级联时 与完全嵌套方式区别在于可以嵌套响应同级中断请求。 * * 1、查询字的结构 I - - - - W2 W1 W0 2、如果是读取IMR寄存器的内容,直接用 IN AL,21H ;IMR寄存器从奇地址端口读取。 * 1、只有两个端口地址,但是要写7个寄存器和读3个寄存器,使用什么样的方法来区分这些寄存器呢? 主要从三个方面考虑:第一,A0地址来区分 第二,初始化时按照顺序来。第三,部分寄存器有一些标志位。 * 对INTR中断的响应,要经过2个INTA周期,每个周期有4个时钟周期,即4个T状态。第一个响应周期,通知外设准备响应中断, 外设应该准备好中断向量号,第二个中断响应总线周期,CPU将接收外设接口发来的中断类型号。 1)普通中断结束方式 配合全嵌套优先权工作方式使用。 当CPU用输出指令向8259A发出正常中断结束EOI命令时,8259A就会把ISR中已置1的位中的级别最高位复位。因为在全嵌套方式中,置1的级别最高ISR位对应了最后一次被响应的和被处理的中断,也就是当前正在处理的中断,所以,把已置1的位中级别最高的ISR位复位相当于结束了当前正在处理的中断。 2)特殊中断结束方式(SEOI) 在非全嵌套方式下,由于中断优先级不断改变,无法确知当前
更多相关内容 -
嵌入式系统/ARM技术中的自学Cortex-M3(3):外部中断0
2020-10-22 21:52:00LPC1768微处理器包括4个外部中断,分别是EINT0、EINT1、EINT2、EINT3对应的引脚分别是P2.10~P2.13,这几个引脚也可以作为通用IO口使用。名个外部中断可以设置成低电平/高电平或上升沿/下降沿有效,它们还有一个功能... -
STM32的“外部中断”和“事件”区别和理解 .
2020-08-09 20:23:32事件是中断的触发源,开放了对应的中断屏蔽位,则事件可以触发相应的中断。 事件还是其它一些操作的触发源,比如DMA,还有TIM中影子寄存器的传递与更新;而中断是不能触发这些操作的,所以要把事件与中断区分开。 -
外部中断实验报告
2017-02-22 14:27:55外部中断实验报告 -
STM32外部中断与I/O引脚对应关系
2013-08-01 21:24:44STM32的外部中断与I/O的对应关系,一看便明了,很清晰。 -
STM32f10x 外部中断及中断分组
2021-01-20 11:04:39利用外部中断来实现按键控制LED灯的亮灭。 实验工具:MDK5,STM32F103ZET6开发板 使用固件库编程 LED灯引脚PD13,按键PE0 首先了解一下32的外部中断 STM32 的每个 IO 都可以作为外部中断的中断输入口,STM32F103 的... -
STM32F103和F429外部中断引脚分布.zip
2021-08-06 20:29:24STM32F103和F429外部中断引脚分布.zip -
stm8 外部中断 源代码
2020-03-20 22:09:23stm8 外部中断 程序源代码 只需要改一下对应的io口数字就可以使用,适合学习如何编写外部中断程序。 -
STM32CubeMx外部中断配置.zip
2021-06-03 16:47:47EXTI(External interrupt/event controller)—外部中断/事件控制器,管理了控制器的 20个中断/事件线。每个中断/事件线都对应有一个边沿检测器,可以实现输入信号的上升沿检测和下降沿的检测。EXTI 可以实现对每个... -
信捷 XC系列PLC应用之外部输入中断例程.rar
2019-10-24 02:41:07信捷 XC系列PLC应用之外部输入中断例程rar,信捷 XC系列PLC应用之外部输入中断例程 -
STM32外部中断
2021-05-22 21:58:11外部中断概述 外部中断是单片机实时地处理外部事件的一种内部机制。当某种外部事件发生时,单片机的中断系统将迫使CPU暂停正在执行的程序,转而去进行中断事件的处理;中断处理完毕后.又返回被中断的程序处,继续...参考正点原子视频
外部中断概述
外部中断是单片机实时地处理外部事件的一种内部机制。当某种外部事件发生时,单片机的中断系统将迫使CPU暂停正在执行的程序,转而去进行中断事件的处理;中断处理完毕后.又返回被中断的程序处,继续执行下去
STM32的每个IO口都可以作为外部中断输入
STM32的中断控制器支持19个外部中断/事件请求:- 线0~15:对应外部IO口的输入中断
- 线16:连接到PVD输出
- 线17:连接到RTC闹钟事件
- 线18:连接到USB唤醒事件
每个外部中断线可以独立的配置触发方式(上升沿,下降沿或者双边沿触发),触发/屏蔽,专用的状态位
从上面可以看出,STM32供IO使用的中断线只有16个,但是STM32F10x系列的IO口多达上百个,STM32F103ZET6(112个IO口),STM32F103RCT6(51个IO口),那么中断线怎么跟IO口对应呢
外部中断通用I/O映像
每个GPIOx的同一编号的引脚(共7个)与一条中断线对应。比如PA0、PB0、PC0、PD0、PE0、PF0、PG0一条中断线GPIOx.0映射到EXTI0
GPIOx.1映射到EXTI1
…
GPIOx.15映射到EXTI15注意事项
- 同一时间,只能有一个I/O口映射到中断线EXTIx上,也就是说,PA0和PB0不能同一时间映射到同一个中断线,而PA0、PA1则可以同时映射,因为它们不是在同一个中断线上
- 对于每个中断线,我们可以设置相应的触发方式(上升沿触发,下降沿触发,边沿触发)以及使能
- 从表中可以看出,外部中断线5~9分配一个中断向量,共用一个服务函数。外部中断线10 ~ 15分配一个中断向量,共用一个中断服务函数
是不是16个中断线就可以分配16个中断服务函数呢?
答案:不是的。因为IO口外部中断在中断向量表中只分配了7个中断向量,也就是只能使用7个中断服务函数
中断服务函数列表
EXTIO_IRQHandler EXTI1_IRQHandler EXTI2_IRQHandler EXTI3_IRQHandler EXTI4_IRQHandler EXTI9_5_IRQHandler EXTIO15_10_IRQHandler
外部中断常用库函数
void GPIO_EXTILineConfig(uint8_t GPIO_PortSource,uint8_t GPIO_PinSource); //设置IO口与中断线的映射关系 exp:void GPIO_EXTILineConfig(GPIO_PortSourceGPIOE,GPIO_PinSource2); void EXTI_Init(EXTI_InitTypeDef*EXTI_InitStruct); //初始化中断线:触发方式等 ITStatus EXTI_GetITStatus(uint32_t EXTI_Line); //判断中断线中断状态,是否发生 void EXTI_ClearITPendingBit(uint32_t EXTI_Line); //清除中断线上的中断标志位
EXTI_Init函数
void EXTI_Init(EXTI_InitTypeDef EXTI_InitStruct);*
typedef struct { uint32_t EXTI_Line;//指定要配置的中断线 EXTIMode_TypeDef EXTI_Mode;//模式:事件OR中断 EXTITrigger_TypeDef EXTI_Trigger;//触发方式:上升沿/下降沿/双沿触发 FunctionalState EXTI_LineCmd;//使能 OR失能 }EXTI_InitTypeDef;
//GPIO_EXTILineConfig(GPIO_PortSourceGPIOE,GPIO_PinSource3); EXTI_InitStructure.EXTI_Line=EXTI_Line3; EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; EXTI_InitStructure.EXTI_LineCmd=ENABLE; EXTI_Init(&EXTI_InitStructure);
GPIO_EXTILineConfig这个函数的作用是什么?参数GPIO_PinSource0是不是必须和EXTI_InitStructure.EXTI_Line = EXTI_Line0一致,为同一个口?
回答:
刚刚测试了一下,GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource0);这话可以去掉,写与不写都一样,但是换成GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource0);你就进不去中断了,,,,,,所以原因我推测:A0对EXTI0是默认的,可以去查手册上相关寄存器的默认值,你要是用B0口做中断的话,就不行,,,,,至于A0设为输入可以去掉,可能也是因为默认设为输入的关系,严格的说,去掉可行但是不严谨。
外部中断的一般配置步骤
-
初始化IO口为输入
GPIO_Init()
-
开启IO口复用时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
-
设置IO口与中断线的映射关系
void GPIO_EXTILineConfig();
-
初始化线上中断,设置触发条件等
EXTI_Init();
-
配置中断分组(NVIC),并使能中断
NVIC_Init();
-
编写中断服务函数
EXTIx_IRQHandler();
-
清除中断标志位
EXTI_ClearITPendingBit();
-
ESP32 外部中断原理分析 & GPIO外部中断实战
2021-10-17 22:34:12ESP32外部中断原理&实战 阅读建议: 有一定Cortex-m架构知识基础。 外部中断原理 外部中断实战 首先配置GPIO ESP-IDF提供了一个结构体方便对其进行初始化,结构体如下: typedef struct { uint64_t ...ESP32 外部中断原理分析 & GPIO外部中断实战
阅读建议:
有一定Cortex-m架构、Xtensa® 32-bit LX6 架构知识基础。
软件环境
- VSCODE-ESP32-IDF4.3 插件版
- LVGL project for ESP32
硬件环境
- ESP32-D2WD
外部中断原理
ESP32-GPIO
ESP32 共有 34 个 GPIO 管脚,通过配置对应的寄存器,可以为这些管脚分配不同的功能,包括如下几类 GPIO:只有数字功能的 GPIO、带模拟功能的 GPIO、带电容触摸功能的 GPIO 等。
带模拟功能的 GPIO 和带电容触摸功能的 GPIO 可以被配置为数字 GPIO。大部分带数字功能的 GPIO 都可以被配置为内部上拉/下拉,或者被设置为高阻。当被配置为输入时,可通过读取寄存器获取输入值。输入管脚也可以被设置为通过边缘触发或电平触发来产生 CPU 中断。大部分数字 IO 管脚都是双向、非反相和三态的,包括带有三态控制的输入和输出缓冲器。这些管脚可以复用作其他功能,例如SDIO、UART、SPI 等(更多信息请参考附录 IO_MUX)。当芯片低功耗运行时,GPIO 可被设定为保持状态。ESP32-INTERRUPT
ESP32 中断矩阵将任一外部中断源单独分配到每个 CPU 的任一外部中断上。这提供了强大的灵活性,能适应不同的应用需求。这和Cortex-m架构的外部中断并不相同并不是通过NVIC向量表的方式而是中断矩阵来设置。
图1: 中断矩阵结构图 主要特性
• 接受 71 个外部中断源作为输入
• 为两个 CPU 分别生成 26 个外部中断(总共 52 个) 作为输出
• 屏蔽 CPU 的 NMI 类型中断
• 查询外部中断源当前的中断状态值得注意的是这里分出了两个概念:外部中断源、 CPU的外部中断 ,这是理解ESP32中断的核心。
ESP32-外部中断源
ESP32 总共有 71 个外部中断源。图2列出了所有外部中断源。ESP32 中的 71 个外部中断源中有 67 个可以分配给两个 CPU。其余的 4 个外部中断源只能分配给特定的 CPU,每个 CPU 2 个。GPIO_INTERRUPT_PRO和GPIO_INTERRUPT_PRO_NMI 只可以分配PRO _CPU,GPIO_INTERRUPT_APP 和GPIO_INTERRUPT_APP_NMI 只可以分配给 APP_CPU。因此,PRO_CPU 与 APP_CPU 各可以分配到 69 个外部中断源。
图2: 外部中断源 图3: 外部GPIO中断源 ESP32-CPU的外部中断
两个 CPU(PRO_CPU 和 APP_CPU)各有 32 个中断,其中 26 个为外部中断。图3列出了每个 CPU 所有的
中断。图4: CPU的外部中断 ESP32-CPU的外部中断 & 外部中断源
每一个外设的中断对应着一个中断源,每一个中断源对应着一个中断源重定向寄存器,如图3所示,GPIO_INTERRUPT_PRO中断源就对应着PRO_GPIO_INTERRUPT_PRO_MAP_REG寄存器通过设置这个寄存器就可以映射到对应的CPU的外部中断如图4所示。每当中断发生时,就可以通过对应CPU的外部中断的回调函数实现中断处理与服务。
值得注意的是:
CPU的一个外部中断可以由多个中断源触发,只要在对应的寄存器中写入对应的外部中断号即可。(将各个寄存器 PRO_Xn_MAP_REG (APP_Xn_MAP_REG) 都配成同样的 中断号。这些外设中断都会触发CPU Interrupt_P)。外部中断实战
- 首先配置GPIO
ESP-IDF提供了一个结构体方便对其进行初始化,结构体如下:
typedef struct { uint64_t pin_bit_mask; /*!< GPIO pin: set with bit mask, each bit maps to a GPIO */ gpio_mode_t mode; /*!< GPIO mode: set input/output mode */ gpio_pullup_t pull_up_en; /*!< GPIO pull-up */ gpio_pulldown_t pull_down_en; /*!< GPIO pull-down */ gpio_int_type_t intr_type; /*!< GPIO interrupt type */ } gpio_config_t;
这结构体中的五个成员都需要初始化,其中第一个通过设置对应位就可以开启对应号码的GPIO,剩下的就是模式设置和中断管理成员。
下面展示一个初始化的例子#define GPIO(n) (1ULL<<n) #define EXTI_Num 0 gpio_config_t EXTI_config; EXTI_config.pin_bit_mask=GPIO(EXTI_Num); /*!< GPIO pin: set with bit mask, each bit maps to a GPIO */ EXTI_config.mode=GPIO_MODE_INPUT; /*!< GPIO mode: set input/output mode*/ EXTI_config.pull_up_en = 1; /*!< GPIO pull-up*/ EXTI_config.pull_down_en = 0; EXTI_config.intr_type=GPIO_INTR_NEGEDGE; /*!< GPIO interrupt type*/
这个例子通过宏定义
#define GPIO(n) (1ULL<<n)
来设定对应GPIO的位,这里就是设置 GPIO0,模式因为是外部中断所以设定为输入模式,同时因为是低电平触发,需要将IO口先拉高,所以这里使能了EXTI_config.pull_up_en = 1;
将其拉高,最后一个是中断模式的设定,官方一共给出了6种中断模式,如下。typedef enum { GPIO_INTR_DISABLE = 0, /*!< Disable GPIO interrupt */ GPIO_INTR_POSEDGE = 1, /*!< GPIO interrupt type : rising edge */ GPIO_INTR_NEGEDGE = 2, /*!< GPIO interrupt type : falling edge */ GPIO_INTR_ANYEDGE = 3, /*!< GPIO interrupt type : both rising and falling edge */ GPIO_INTR_LOW_LEVEL = 4, /*!< GPIO interrupt type : input low level trigger */ GPIO_INTR_HIGH_LEVEL = 5, /*!< GPIO interrupt type : input high level trigger */ GPIO_INTR_MAX, } gpio_int_type_t;
从上向下分别是不使能中断,上下沿触发中断,高低电平触发中断,这里使用的是下降沿触发中断。
最后通过
gpio_config
函数来将结构体的设置导入到对应寄存器。gpio_config(&EXTI_config);
接下来就是对应中断的设定。
首先开启GPIO中断,注意这个函数并不是需要每一个GPIO中断都要使用一次,而是开启整个gpio的中断,并向当前运行的核心注册GPIO中断,也就是说你调用这个函数在哪个核心,中断处理函数就在哪个核心进行运行。函数如下:gpio_install_isr_service(ESP_INTR_FLAG_LEVEL3);
其中 ESP_INTR_FLAG_LEVEL3 也是一个宏定义它规定了这个中断的优先级如上文所属,所有中断优先级定义如下:
/** @brief Interrupt allocation flags * * These flags can be used to specify which interrupt qualities the * code calling esp_intr_alloc* needs. * */ //Keep the LEVELx values as they are here; they match up with (1<<level) #define ESP_INTR_FLAG_LEVEL1 (1<<1) ///< Accept a Level 1 interrupt vector (lowest priority) #define ESP_INTR_FLAG_LEVEL2 (1<<2) ///< Accept a Level 2 interrupt vector #define ESP_INTR_FLAG_LEVEL3 (1<<3) ///< Accept a Level 3 interrupt vector #define ESP_INTR_FLAG_LEVEL4 (1<<4) ///< Accept a Level 4 interrupt vector #define ESP_INTR_FLAG_LEVEL5 (1<<5) ///< Accept a Level 5 interrupt vector #define ESP_INTR_FLAG_LEVEL6 (1<<6) ///< Accept a Level 6 interrupt vector #define ESP_INTR_FLAG_NMI (1<<7) ///< Accept a Level 7 interrupt vector (highest priority) #define ESP_INTR_FLAG_SHARED (1<<8) ///< Interrupt can be shared between ISRs #define ESP_INTR_FLAG_EDGE (1<<9) ///< Edge-triggered interrupt #define ESP_INTR_FLAG_IRAM (1<<10) ///< ISR can be called if cache is disabled #define ESP_INTR_FLAG_INTRDISABLED (1<<11) ///< Return with this interrupt disabled #define ESP_INTR_FLAG_LOWMED (ESP_INTR_FLAG_LEVEL1|ESP_INTR_FLAG_LEVEL2|ESP_INTR_FLAG_LEVEL3) ///< Low and medium prio interrupts. These can be handled in C. #define ESP_INTR_FLAG_HIGH (ESP_INTR_FLAG_LEVEL4|ESP_INTR_FLAG_LEVEL5|ESP_INTR_FLAG_LEVEL6|ESP_INTR_FLAG_NMI) ///< High level interrupts. Need to be handled in assembly. #define ESP_INTR_FLAG_LEVELMASK (ESP_INTR_FLAG_LEVEL1|ESP_INTR_FLAG_LEVEL2|ESP_INTR_FLAG_LEVEL3| \ ESP_INTR_FLAG_LEVEL4|ESP_INTR_FLAG_LEVEL5|ESP_INTR_FLAG_LEVEL6| \ ESP_INTR_FLAG_NMI) ///< Mask for all level flags
最后是注册中断回调函数开启中断:
gpio_isr_handler_add(EXTI_Num,EXIT_Handelr,NULL);
到这里一个外中断就初始化完成了。
-
浅谈S3C2440的中断寄存器及中断过程
2021-01-19 18:41:51中断分两大类:外部中断和内部中断。 1.1 外部中断寄存器 24个外部中断占用GPF0-GPF7(EINT0-EINT7),GPG0-GPG15(EINT8-EINT23)。用这些脚做中断输入,则必须配置引脚为中断,并且不要上拉。具体可参考... -
STM32-外部中断
2021-10-02 22:07:221 外部中断概述 EXTI(External interrupt/event controller)—外部中断/事件控制器,和在STM32NVIC中断优先级管理(中断向量表)中讲述的CM3内核的外部中断不同。特指的是,在中断向量表中的EXTI的外部中断。STM...1 外部中断概述
EXTI(External interrupt/event controller)—外部中断/事件控制器,和在STM32NVIC中断优先级管理(中断向量表)中讲述的CM3内核的外部中断不同。特指的是,在中断向量表中的EXTI的外部中断。STM32的每个IO都可以作为外部中断输入。EXTI管理了控制器的 20个中断/事件线。每个中断/事件线都对应有一个边沿检测器,可以实现输入信号的上升沿检测和下降沿的检测。EXTI 可以实现对每个中断/事件线进行单独配置,可以单独配置为中断或者事件,以及触发事件的属性。
1.1 外部中断线
STM32的中断控制器支持19个外部中断、事件请求(也就是19条外部中断线),每个中断设有状态位,每个中断/ 事件都有独立的触发和屏蔽设置。STM32的19个外部中断对应着19路中断线,分别是EXTI_Line0-EXTI_Line18::
线0~15:对应外部IO口的输入中断;
线16:连接到PVD输出;
线17:连接到RTC闹钟事件;
线18:连接到USB唤醒事件。外部中断的功能框图包含了外部中断最核心内容,掌握了功能框图,对外部中断就有一个整体的把握,在编程时思路就非常清晰。外部中断功能框图见图。
在图可以看到很多在信号线上打一个斜杠并标注“20”字样,这个表示在控制器内部类似的信号线路有 20 个,这与外部中断总共有 20 个中断/事件线是吻合的。所以我们只要明白其中一个的原理,那其他 19 个线路原理也就知道了。外部中断可分为两大部分功能,一个是产生中断,另一个是产生事件,这两个功能从硬件上就有所不同。
首先我们来看图中红色虚线指示的电路流程。它是一个产生中断的线路,最终信号流入到 NVIC 控制器内。
编号 1 是输入线,外部中断控制器有 19 个中断/事件输入线,这些输入线可以通过寄存器设置为任意一个 GPIO,也可以是一些外设的事件,这部分内容我们将在后面专门讲解。输入线一般是存在电平变化的信号。
编号 2 是一个边沿检测电路,它会根据上升沿触发选择寄存器(EXTI_RTSR)和下降沿触发选择寄存器(EXTI_FTSR)对应位的设置来控制信号触发。边沿检测电路以输入线作为信号输入端,如果检测到有边沿跳变就输出有效信号 1 给编号 3 电路,否则输出无效信号0。而 EXTI_RTSR 和 EXTI_FTSR 两个寄存器可以控制器需要检测哪些类型的电平跳变过程,可以是只有上升沿触发、只有下降沿触发或者上升沿和下降沿都触发。
编号 3 电路实际就是一个或门电路,它一个输入来自编号 2 电路,另外一个输入来自软件中断事件寄存器(EXTI_SWIER)。EXTI_SWIER允许我们通过程序控制就可以启动中断/事件线,这在某些地方非常有用。我们知道或门的作用就是有 1 就为 1,所以这两个输入随便一个有有效信号 1就可以输出 1 给编号 4和编号 6电路。
编号 4 电路是一个与门电路,它一个输入是编号 3 电路,另外一个输入来自中断屏蔽寄存器(EXTI_IMR)。与门电路要求输入都为 1 才输出 1,导致的结果是如果 EXTI_IMR 设置为 0 时,那不管编号 3 电路的输出信号是 1 还是 0,最终编号 4 电路输出的信号都为 0;如果EXTI_IMR设置为1时,最终编号4电路输出的信号才由编号3电路的输出信号决定,这样我们可以简单的控制 EXTI_IMR 来实现是否产生中断的目的。编号 4 电路输出的信号会被保存到挂起寄存器(EXTI_PR)内,如果确定编号 4 电路输出为 1 就会把 EXTI_PR 对应位置 1。
编号 5 是将 EXTI_PR 寄存器内容输出到 NVIC 内,从而实现系统中断事件控制。
接下来我们来看看绿色虚线指示的电路流程。它是一个产生事件的线路,最终输出一个脉冲信号。
产生事件线路是在编号3电路之后与中断线路有所不同,之前电路都是共用的。
编号 6 电路是一个与门电路,它一个输入来自编号 3 电路,另外一个输入来自事件屏蔽寄存器(EXTI_EMR)。如果 EXTI_EMR设置为 0时,那不管编号 3电路的输出信号是 1还是 0,最终编号 6 电路输出的信号都为 0;如果 EXTI_EMR 设置为 1 时,最终编号 6 电路输出的信号才由编号 3 电路的输出信号决定,这样我们可以简单的控制 EXTI_EMR 来实现是否产生
事件的目的。
编号 7 是一个脉冲发生器电路,当它的输入端,即编号 6 电路的输出端,是一个有效信号 1 时就会产生一个脉冲;如果输入端是无效信号就不会输出脉冲。
编号 8 是一个脉冲信号,就是产生事件的线路最终的产物,这个脉冲信号可以给其他外设电路使用,比如定时器 TIM、模拟数字转换器 ADC等等,这样的脉冲信号一般用来触发 TIM 或者 ADC开始转换。
产生中断线路目的是把输入信号输入到 NVIC,进一步会运行中断服务函数,实现功能,这样是软件级的。而产生事件线路目的就是传输一个脉冲信号给其他外设使用,并且是电路级别的信号传输,属于硬件级的。
另外,EXTI是在 APB2总线上的,在编程时候需要注意到这点。每条外部中断线可以独立的配置触发方式(上升沿、下降沿或者双边沿触发)、使能/失能中断、专用的状态位。
外部中断有 20个中断/事件线,每个 GPIO都可以被设置为输入线,占用 EXTI0至 EXTI15,还有另外四根用于特定的外设事件。可以看出,STM32供IO使用的中断线只有16条,但是STM32F10x系列的IO口多达上百个,其中STM32F103ZET6有112个引脚(7组GPIO,每组16个)。那么中断线怎么跟IO口对应呢?
从上图可以轻易地看出来:每个GPIOx的同一编号的引脚(共7个)与一条中断线对应。比如PA0、PB0、PC0、PD0、PE0、PF0、PG0一条中断线。EXTI0至 EXTI15用于 GPIO,通过编程控制可以实现任意一个 GPIO作为外部中断的输入源。由表可知,EXTI0 可以通过 AFIO 的外部中断配置寄存器 1(AFIO_EXTICR1)的EXTI0[3:0]位选择配置为 PA0、PB0、PC0、PD0、PE0、PF0、PG0,其他 EXTI线(EXTI中断/事件线)使用配置都是类似的。
注意一下:同一个时间,只能有一个IO口映射到同一个中断线。也就是说,PA0和PB0不能同一时间映射到同一个中断线,而PA0、PA1则可以同时映射,因为它们不是在同一个中断线上。1.2 中断服务函数
那么是不是16个中断线就可以分配16个中断服务函数呢?
答案也不是。之前在STM32NVIC中断优先级管理文章中,我们介绍了中断向量表。在中断向量表中,IO口外部中断在中断向量表中只分配了7个中断向量,也就是只能使用7个中断服务函数。
从上图中可以看出,外部中断线5~9分配一个中断向量,共用一个服务函数;外部中断线10~15分配一个中断向量,共用一个中断服务函数;而中断向量线0-4则单独使用一个中断服务函数。也就是说,IO口的外部中断最多只能使用7个。
中断服务函数的映射关系:
GPIO IRQn IRQHandler GPIO_Pin0 EXTI0_IRQn EXTI0_IRQHandler GPIO_Pin1 EXTI1_IRQn EXTI1_IRQHandler GPIO_Pin2 EXTI2_IRQn EXTI2_IRQHandler GPIO_Pin3 EXTI3_IRQn EXTI3_IRQHandler GPIO_Pin4 EXTI4_IRQn EXTI4_IRQHandler GPIO_Pin5 — GPIO_Pin9 EXTI9_5_IRQn EXTI9_5_IRQHandler GPIO_Pin10 — GPIO_Pin15 EXTI15_10_IRQn EXTI15_10_IRQHandler 下面列举了中断服务函数的名称(在启动文件startup_stm32f10x_hd.s上):
void EXTI0_IRQHandler() void EXTI1_IRQHandler() void EXTI2_IRQHandler() void EXTI3_IRQHandler() void EXTI4_IRQHandler() void EXTI9_5_IRQHandler() void EXTI15_10_IRQHandler()
2 外部中断相关配置寄存器
2.1 中断屏蔽寄存器(EXTI_IMR)
作用:每一位对应着一条中断线。清零表示屏蔽该线路上的中断请求;置1表示打开该线路上的中断请求。这是一个 32 寄存器。但是只有前 19 位有效。当位 x 设置为1 时,则开启这个线上的中断,否则关闭该线上的中断。
2.2 事件屏蔽寄存器(EXTI_EMR)
作用:每一位对应着一条中断线。清零表示屏蔽该线路上的事件请求;置1表示打开该线路上的事件请求。同IMR ,只是该寄存器是针对事件的屏蔽和开启。
2.3 上升沿触发选择寄存器(EXTI_RTSR)
作用:每一位对应着一条中断线。清零表示关闭上升沿触发中断或事件;置1表示打开上升沿触发中断或事件。该寄存器同IMR ,也是一个32为的寄存器,只有前 19位有效。位 x 对应线x 上的上升沿触发,如果设置为 1 ,则是允许上升沿触发中断/ 事件。否则,不允许。
2.4 下降沿触发选择寄存器(EXTI_FTSR)
作用:每一位对应着一条中断线。清零表示关闭下降沿触发中断或事件;置1表示打开下降沿触发中断或事件。同 PTSR,不过这个寄存器是设置下降沿的。下降沿和上升沿可以被同时设置,这样就变成了任意电平触发了。
2.5 软件触发事件寄存器(EXTI_SWIER)
作用:每一位对应着一条中断线。当EXTIx中断有效且SWIER=0时,向SWIER写1将触发中断请求。通过向该寄存器的位x 写入 1 ,在未设置 IMR 和EMR的时候,将设置PR中相应位挂起。如果设置了IMR 和EMR时将产生一次中断。被设置的SWIER位,将会在PR中的对应位清除后清除。
2.6 挂起寄存器(EXTI_PR)
作用:每一位对应着一条中断线。如果第i个中断触发了,则PR位对应位自动置1;向PR位写入1清零该位,同时清除SWIER位。0 ,表示对应线上没有发生触发请求。1,表示外部中断线上发生了选择的边沿事件。通过向该寄存器的对应位写入 1 可以清除该位。在中断服务函数里面经常会要向该寄存器的对应位写1 来清除中断请求。
2.7 EXTICR寄存器组(EXTICR[0]~ EXTICR[3])
EXTICR寄存器组,总共有4 个,因为编译器的寄存器组都是从0 开始编号的,所以EXTICR[0]~ EXTICR[3],对应《STM32参考手册》里的 EXTICR1~ EXTICR 4(查了好久才搞明白这个数组的含义!!)。每个 EXTICR只用了其低16 位。
EXTICR[0] ~EXTICR[3]的分配如下:
3 外部中断配置相关库函数
3.1 1个映射函数
void GPIO_EXTILineConfig(uint8_t GPIO_PortSource, uint8_t GPIO_PinSource);
作用:设置IO口与中断线之间的映射关系。
3.2 1个初始化函数
void EXTI_Init(EXTI_InitTypeDef* EXTI_InitStruct);
作用:初始化中断线,设置触发方式、中断还是事件等等。
3.3 2个标志位函数
ITStatus EXTI_GetITStatus(uint32_t EXTI_Line); void EXTI_ClearITPendingBit(uint32_t EXTI_Line);
作用:前者判断中断线中断状态,是否发生;后者清除中断线上的中断标志位。
实际上固件库除了这两个标志位函数之外,还提供了两个函数来判断外部中断状态和清除爱步状态标志位的函数,分别为:
FlagStatus EXTI_GetFlagStatus(uint32_t EXTI_Line); void EXTI_ClearFlag(uint32_t EXTI_Line);
它们的作用和前面两个函数的作用类似,只是在EXTI_GetITStatus()函数中,会先判断这种中断是否使能,使能了才去判断中断标志位,而EXTI_GetFlagStatus则直接判断状态标志位。
4 外部中断一般步骤
1)开启IO口时钟,初始化IO口为输入。调用函数:GPIO_Init();
2)开启IO口复用时钟。调用函数:RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
3)设置IO口与中断线的映射关系。调用函数:GPIO_EXTILineConfig();
4)初始化线上中断,设置触发条件等。调用函数:EXTI_Init();
5)配置中断分组(NVIC),并使能中断。调用函数:NVIC_Init();
6)编写中断服务函数。调用函数:EXTIx_IRQHandler();
7)清除中断标志位。调用函数:EXTI_ClearITPendingBit()。下面按照这个一般步骤来进行一个简单的外部中断程序:
void KEY_Init(void) //IO初始化 { GPIO_InitTypeDef GPIO_InitStructure; //使能PORTA,PORTE时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOE,ENABLE); //初始化GPIO模式和对应管脚 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4;//KEY0-KEY2 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //设置成上拉输入 GPIO_Init(GPIOE, &GPIO_InitStructure);//初始化GPIOE2,3,4 //初始化 WK_UP-->GPIOA.0 下拉输入 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; //PA0设置成输入,默认下拉 GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.0 }
void EXTIX_Init(void) { EXTI_InitTypeDef EXTI_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; //按键端口初始化 KEY_Init(); //使能复用功能时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE); //GPIOE.2 中断线以及中断初始化配置 下降沿触发 //选择EXTI信号源 GPIO_EXTILineConfig(GPIO_PortSourceGPIOE,GPIO_PinSource2); //确定中断线、中断模式、触发方式并使能: EXTI_InitStructure.EXTI_Line=EXTI_Line2; //KEY2 EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; EXTI_InitStructure.EXTI_LineCmd = ENABLE; EXTI_Init(&EXTI_InitStructure); //根据EXTI_InitStruct中指定的参数初始化外设EXTI寄存器 //GPIOE.3 中断线以及中断初始化配置 下降沿触发 //KEY1 //选择EXTI信号源 GPIO_EXTILineConfig(GPIO_PortSourceGPIOE,GPIO_PinSource3); //确定中断线、中断模式、触发方式并使能: EXTI_InitStructure.EXTI_Line=EXTI_Line3; EXTI_Init(&EXTI_InitStructure); //根据EXTI_InitStruct中指定的参数初始化外设EXTI寄存器 //GPIOE.4 中断线以及中断初始化配置 下降沿触发 //KEY0 //选择EXTI信号源 GPIO_EXTILineConfig(GPIO_PortSourceGPIOE,GPIO_PinSource4); //确定中断线、中断模式、触发方式并使能: EXTI_InitStructure.EXTI_Line=EXTI_Line4; EXTI_Init(&EXTI_InitStructure); //根据EXTI_InitStruct中指定的参数初始化外设EXTI寄存器 //GPIOA.0 中断线以及中断初始化配置 上升沿触发 PA0 WK_UP //选择EXTI信号源 GPIO_EXTILineConfig(GPIO_PortSourceGPIOA,GPIO_PinSource0); //确定中断线、中断模式、触发方式并使能: EXTI_InitStructure.EXTI_Line=EXTI_Line0; EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising; EXTI_Init(&EXTI_InitStructure); //根据EXTI_InitStruct中指定的参数初始化外设EXTI寄存器 //确定中断源、优先级(抢占优先级和子优先级),使能: NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn; //使能按键WK_UP所在的外部中断通道 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02; //抢占优先级2, NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x03; //子优先级3 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能外部中断通道 NVIC_Init(&NVIC_InitStructure); //确定中断源、优先级(抢占优先级和子优先级),使能: NVIC_InitStructure.NVIC_IRQChannel = EXTI2_IRQn; //使能按键KEY2所在的外部中断通道 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02; //抢占优先级2, NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x02; //子优先级2 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能外部中断通道 NVIC_Init(&NVIC_InitStructure); //确定中断源、优先级(抢占优先级和子优先级),使能: NVIC_InitStructure.NVIC_IRQChannel = EXTI3_IRQn; //使能按键KEY1所在的外部中断通道 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02; //抢占优先级2 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x01; //子优先级1 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能外部中断通道 NVIC_Init(&NVIC_InitStructure); //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器 //确定中断源、优先级(抢占优先级和子优先级),使能: NVIC_InitStructure.NVIC_IRQChannel = EXTI4_IRQn; //使能按键KEY0所在的外部中断通道 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02; //抢占优先级2 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x00; //子优先级0 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能外部中断通道 NVIC_Init(&NVIC_InitStructure); //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器 } //外部中断0服务程序 void EXTI0_IRQHandler(void) { delay_ms(10);//消抖 if(WK_UP==1) //WK_UP按键 { BEEP=!BEEP; } EXTI_ClearITPendingBit(EXTI_Line0); //清除LINE0上的中断标志位 } //外部中断2服务程序 void EXTI2_IRQHandler(void) { delay_ms(10);//消抖 if(KEY2==0) //按键KEY2 { LED0=!LED0; } EXTI_ClearITPendingBit(EXTI_Line2); //清除LINE2上的中断标志位 } //外部中断3服务程序 void EXTI3_IRQHandler(void) { delay_ms(10);//消抖 if(KEY1==0) //按键KEY1 { LED1=!LED1; } EXTI_ClearITPendingBit(EXTI_Line3); //清除LINE3上的中断标志位 } void EXTI4_IRQHandler(void) { delay_ms(10);//消抖 if(KEY0==0) //按键KEY0 { LED0=!LED0; LED1=!LED1; } EXTI_ClearITPendingBit(EXTI_Line4); //清除LINE4上的中断标志位 }
EXTIX_Init函数
1)RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE),使能复用功能时钟,这个步骤不能省略,否则肯定会出问题。STM32端口复用和重映射(AFIO辅助功能时钟)
2)在编写中断处理函数的过程中,在最后一步,一定要记得清除中断标志位。调用函数:EXTI_ClearITPendingBit()。否则下次中断就不会发生。这里我们配置两个的中断软件优先级一样,如果出现了两个按键同时按下的情况,那怎么办,到底该执行哪一个中断?当两个中断的软件优先级一样的时候,中断来临时,具体先执行哪个中断服务函数由硬件的中断编号决定,编号越小,优先级越高。有关外设的硬件编号可查询《STM32F10X-中文参考手册》的中断和事件章节中的向量表,表中的位置编号即是每个外设的硬件中断优先级。当然,我们也可以把抢占优先级设置成一样,子优先级设置成不一样,这样就可以区别两个按键同时按下的情况,而不用硬件去对比硬件编号。
GPIO_EXTILineConfig(uint8_t GPIO_PortSource, uint8_t GPIO_PinSource);用于选择 GPIO 管脚用作外部中断线路。库里面是这样定义的:/** * @摘要 选择用于EXTI线的GPIO管脚。 * @参数 GPIO_PortSource: 选择GPIO端口作为EXTI线路的源。 * 该参数可以是GPIO_PortSourceGPIOx, x可以是(A..G)。 * @参数 GPIO_PinSource: 指定要配置的EXTI线路。 * 该参数可以是GPIO_PinSourcex,其中x可以是(0..15)。 * @返回值 无 */ void GPIO_EXTILineConfig(uint8_t GPIO_PortSource, uint8_t GPIO_PinSource) { uint32_t tmp = 0x00; /* 检查参数 */ 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))); }
-
STM32外部中断与各通道对应关系
2018-07-12 14:02:46一:外部中断使用配置过程:(1)配置时钟信号(2)引脚属性(3)NVIC配置(4)外部中断配置二:STM32外部中断与各通道对应关系 -
STM32中断一些概念(主要是外部中断与中断通道)
2019-04-25 17:32:49startup_stm32f10x_hd.s,stm32f10x_exti.h,stm32f10x_exti.c,另外,这里说的外部中断是相对于M3内核之外的,主要是外设中断如:如I/O口相应的外接设备中断,USART、Timer等其它本身固件中断。 对于cortex_m3内核... -
STM32F103:外部中断(EXTI)——原理和程序
2021-11-23 13:50:08一、外部中断(EXTI)—简介 EXTI (External interrupt/event controller)——外部中断/事件控制器。 互联型STM32有20个能够产生事件/中断请求的边沿检测器,STM32F103系列有19个能够产生事件/中断请求的边沿检测器。 ... -
【51单片机——外部中断应用】哪些I/O口可以用外部中断?
2020-04-11 22:17:041、外部中断0:INT0,其对应的引脚为P3^2。 #include "reg52.h" typedef unsigned int u16; typedef unsigned char u8; sbit k3=P3^2; //定义按键K3,外部中断0触发I/O口 sbit led=P2^0; //定义P20... -
51单片机外部中断0实例详解
2021-05-22 03:49:54151单片机的中断源51单片机共有5个中断源,分别为:外部中断0定时器0中断外部中断1定时器1中断串口中断每一个中断都对应一个中断向量,中断向量表如下所示:2什么是中断事件当中断发生时单片机将正在执行的程序暂时... -
单片机与DSP中的浅谈S3C2440的中断寄存器及中断过程
2020-10-16 09:22:41中断分两大类:外部中断和内部中断。 1.1 外部中断寄存器 24个外部中断占用GPF0-GPF7(EINT0-EINT7),GPG0-GPG15(EINT8-EINT23)。用这些脚做中断输入,则必须配置引脚为中断,并且不要上拉。具体可参考... -
Proteus仿真:外部中断应用实例
2021-02-25 20:42:35因仿真库中无74LS348仿真元件,仿真电路使用74HC148和74HC245模拟74LS348,8路外部中断输入全部为低有效,对应的中断发生时,使用printf函数从串口输出“extended interput x happened”,x为对应的中断编号。... -
【51单片机】外部中断
2021-12-07 11:12:1351的 外部中断 与 定时器(内部中断) 有一个共同特点,那就是与主程序是并行工作的,就是主程序在运行的时候,中断也在等待触发条件,当中断被触发的时候会暂停主程序转而执行中断服务程序,只有中断服务程序执行完后... -
Cortex-M0系列 ~ 外部中断开启/关闭
2020-11-05 17:10:44CortexM0的外部中断配置见相关博文 → Cortex-M0系列 ~ 外部中断 外部中断算是中断机制中的一种,只要中断引脚触发,便会打断当前的执行任务到外部中断函数中 如遇到有重要任务执行时不想被外部中断所打断,便需要... -
【stm32f407】外部中断实现按键中断方式
2017-06-07 11:20:44外部中断 STM32F4的每个IO都可以作为外部中断的中断输入口,这点也是STM32F4的强大之处。STM32F407的中断控制器支持22个外部中断/事件请求。每个中断设有状态位,每个中断/事件都有独立的触发和屏蔽设置。 STM32F... -
51单片机中断号对应的中断类型
2019-08-07 08:36:08中断源 默认中断级别 外部中断0 INT0 最高 interrupt 0 定时器0中断 T0 ... -
外部中断与内部中断原理与使用
2021-07-26 09:36:51外部中断源2个 1.INT0 — 由P3.2端口控制引入,低水平或者下降沿引起。(下降沿就是给5V后给0V形成下降电压) 2.INT1 —由P3.3端口控制引入,低水平或者下降沿引起。 (这两个中断源标志与中断方式由特殊功能寄存器... -
51单片机学习笔记之中断(外部中断、定时器中断、中断嵌套)
2021-08-03 15:31:41要学习51单片机中断的朋友,拥有这一篇博文就够了,深入浅出,里面包含了寄存器,外部中断、定时器中断、中断嵌套等的讲解,还有代码实战。快一万字,写得不容易,还请大家点赞支持一下,后续持续更新(一)寄存器1.... -
13 . 外部中断实验
2021-05-13 10:50:46外部中断实验 介绍了STM32F10x 的中断,就来学习下外部中断。要实现的功能与按键实验一样,即通过按键控制LED,只不过这里采用外部中断方式进行控制。 1. 外部中断介绍 EXTI 简介 STM32F10x 外部中断/事件控制器... -
8051外部中断1解析
2019-07-23 10:41:21程序实现的功能: 在实验板上左下方有一...(外部中断1和外部中断0在处理上类似, 红色的部分为不同之处) 中断处理程序标号: 外部中断0 -----------> 0 定时器0中断 -----------> 1 外部中断1 -----------&... -
51单片机学习——8.1外部中断0和1
2021-02-13 08:49:54外部中断0和1外部中断原理编程原理(外部中断0)代码实现 外部中断原理 外部中断0:(P3.2)可由IT0(TCON.0)选择其为低电平有效还是下降沿有效。当CPU检测到P3.2引脚上出现有效的中断信号时,中断标志IE0(TCON.1)置...