中断 订阅
中断是指计算机运行过程中,出现某些意外情况需主机干预时,机器能自动停止正在运行的程序并转入处理新情况的程序,处理完毕后又返回原被暂停的程序继续运行。 [1] 展开全文
中断是指计算机运行过程中,出现某些意外情况需主机干预时,机器能自动停止正在运行的程序并转入处理新情况的程序,处理完毕后又返回原被暂停的程序继续运行。 [1]
信息
应    用
计算机编程
外文名
Interrupt Request
分    类
硬性中断、软性中断
中文名
中断
学    科
计算机
顺    序
高级中断优先
中断术语解释
指处理机处理程序运行中出现的紧急事件的整个过程.程序运行过程中,系统外部、系统内部或者现行程序本身若出现紧急事件,处理机立即中止现行程序的运行,自动转入相应的处理程序(中断服务程序),待处理完后,再返回原来的程序运行,这整个过程称为程序中断;当处理机接受中断时,只需暂停一个或几个周期而不执行处理程序的中断,称为简单中断.中断又可分为屏蔽中断和非屏蔽中断两类.可由程序控制其屏蔽的中断称为屏蔽中断或可屏蔽中断.屏蔽时,处理机将不接受中断.反之,不能由程序控制其屏蔽,处理机一定要立即处理的中断称为非屏蔽中断或不可屏蔽中断.非屏蔽中断主要用于断电、电源故障等必须立即处理的情况.处理机响应中断时,不需执行查询程序.由被响应中断源向CPU发向量地址的中断称为向量中断,反之为非向量中断.向量中断可以提高中断响应速度。 [2] 
收起全文
精华内容
下载资源
问答
  • 中断

    万次阅读 多人点赞 2018-10-03 18:54:31
    整个过程称为中断处理,简称中断,而引起这一过程的事件称为中断事件。中断是计算机实现并发执行的关键,也是操作系统工作的根本。 分类  中断按事件来源分类,可以分为外部中断和内部中断中断事件来自于CPU...

    定义

           在计算机科学中,中断指计算机CPU获知某些事,暂停正在执行的程序,转而去执行处理该事件的程序,当这段程序执行完毕后再继续执行之前的程序。整个过程称为中断处理,简称中断,而引起这一过程的事件称为中断事件。中断是计算机实现并发执行的关键,也是操作系统工作的根本。

    分类

           中断按事件来源分类,可以分为外部中断和内部中断。中断事件来自于CPU外部的被称为外部中断,来自于CPU内部的则为内部中断。

           进一步细分,外部中断还可分为可屏蔽中断(maskable interrupt)和不可屏蔽中断(non-maskable interrupt)两种,而内部中断按事件是否正常来划分可分为软中断和异常两种。

           外部中断的中断事件来源于CPU外部,必然是某个硬件产生的,所以外部中断又被称为硬件中断(hardware interrupt)。计算机的外部设备,如网卡、声卡、显卡等都能产生中断。外部设备的中断信号是通过两根信号线通知CPU的,一根是INTR,另一根是NMI。CPU从INTR收到的中断信号都是不影响系统运行的,CPU可以选择屏蔽(通过设置中断屏蔽寄存器中的IF位),而从NMI中收到的中断信号则是影响系统运行的严重错误,不可屏蔽,因为屏蔽的意义不大,系统已经无法运行。

           内部中断来自于处理器内部,其中软中断是由软件主动发起的中断,常被用于系统调用(system call);而异常则是指令执行期间CPU内部产生的错误引起的。异常也和不可屏蔽中断一样不受eflags寄存器的IF位影响,区别在于不可屏蔽中断发生的事件会导致处理器无法运行(如断电、电源故障等),而异常则是影响系统正常运行的中断(如除0、越界访问等)。

    中断描述符表

           中断描述符表(Interrupt Descriptor Table,IDT)是保护模式下用于存储中断处理程序入口的数据结构,实模式中采用中断向量表(Interrupt Vector Table,IVT)。当CPU接收一个中断时,需要用中断向量在此表中检索对应的中断描述符,在该描述符中找到中断处理程序的起始地址,然后才能执行中断处理程序。

           中断描述符表中不仅仅有中断描述符,还可以有任务门描述符和陷阱门描述符,它们实质上都是记录着某段程序的起始地址,因此可以统称为门。

    中断处理过程及保护

           中断过程因中断来源而异,外部中断由外设发出,经中断代理芯片接收并处理后将该中断的中断向量号发送到CPU,最后由CPU执行该中断向量号对应的中断处理程序。内部中断则不经过中断代理芯片。

           中断在处理器内部的处理程序如下:

    (1)处理器根据中断向量号定位中断门描述符。

           中断向量号是中断描述符的索引,当处理器收到一个外部中断向量号后,它用此向量号在中断描述符表中查询对应的中断描述符,然后再去执行该中断描述符指向的中断处理程序。中断描述符占8字节,因此处理器用中断向量号乘8后再与IDTR中的中断描述符表地址相加得到中断描述符的位置。

    (2)特权级检查

           中断向量号只是一个整数,其中没有RPL,所以在对由中断引起的特权级转移特权级检查时并不涉及RPL。

           如果是由软中断int n、int3、和into这些由用户进程引发的中断,由用户代码控制,处理器要检查当前特权级CPL和门描述符DPL,数值上CPL≤门描述符DPL才能通过检查。通过上一步检查后还需要检查CPL和门描述符中所记录的选择子对应的目标代码段DPL,数值上CPL>目标代码段DPL才能通过检查,因为除返回指令外,特权转移只能由低到高。

           若中断是由外部设备或异常引起的,只检查CPL和目标代码段的DPL即可。

    (3)执行中断处理程序

           特权级检查通过后,将门描述符中目标代码段选择子加载到段寄存器CS中,把门描述符中的中断处理程序的偏移地址加载到EIP,然后开始执行中断处理程序。

           中断发生后,eflags中的NT位和TF位都会被置0。如果中断对应的门描述符是中断门,标志寄存器eflags中的IF位也会被置0以避免中断嵌套(中断处理过程中又处理新的中断),即默认情况下处理器对中断门描述符的中断例程处理是不可中断的。若中断发生时对应的门描述符是任务门或陷阱门的话,CPU不会将状态寄存器中的IF位清0,即允许中断嵌套。

     

                                                                                                   本文部分内容摘自《操作系统真象还原》,有改动

    展开全文
  • STM32—中断详解(配合按键中断代码,代码亲测)

    万次阅读 多人点赞 2019-07-25 17:35:23
    在STM32中执行中断主要分三部分: 1.配置NVIC_Config()函数 2.配置EXTI_Config()函数 3.编写中断服务函数 (注:本文章所用代码为中断按键代码,实现了按键进入中断从而控制LED亮灭) 配置NVIC_Config()函数 NVIC 是...

    在STM32中执行中断主要分三部分:
    1.配置NVIC_Config()函数
    2.配置EXTI_Config()函数
    3.编写中断服务函数

    (注:本文章所用代码为中断按键代码,实现了按键进入中断从而控制LED亮灭)

    配置NVIC_Config()函数

    NVIC 是嵌套向量中断控制器,控制着整个芯片中断相关的功能,它跟内核紧密耦合,是内核里面的一个外设。
    NVIC_Config()函数代码如下

    static void NVIC_Config(void) /* 主要是配置中断源的优先级与打开使能中断通道 */
    {
    	NVIC_InitTypeDef NVIC_InitStruct ;
    	
    	/* 配置中断优先级分组(设置抢占优先级和子优先级的分配),在函数在misc.c */
    	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1) ;
    	
    	/* 配置初始化结构体 在misc.h中 */
    	/* 配置中断源 在stm32f10x.h中 */
    	NVIC_InitStruct.NVIC_IRQChannel = KEY1_EXTI_IRQN ;
    	/* 配置抢占优先级 */
    	NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 1 ;
    	/* 配置子优先级 */
    	NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0 ;
    	/* 使能中断通道 */
    	NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE ;
    	/* 调用初始化函数 */
    	NVIC_Init(&NVIC_InitStruct) ;
    	
    	/* 对key2执行相同操作 */
    	NVIC_InitStruct.NVIC_IRQChannel = KEY2_EXTI_IRQN ;
    	NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 1 ;
    	NVIC_InitStruct.NVIC_IRQChannelSubPriority = 1 ;
    	NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE ;
    	NVIC_Init(&NVIC_InitStruct) ;
    	
    }
    

    配置NVIC_Config()的目的是选择中断源的优先级以及打开中断通道,主要功能通过配置NVIC初始化结构体NVIC_InitStruct来完成。通俗的讲,STM32中有很多中断,而当有多个中断同时发生时就涉及到中断执行的先后问题了,所以引入了中断优先级的概念,中断优先级越高中断就越先执行。在这里我们只讨论外部中断的优先级,在 NVIC 有一个专门的寄存器:中断优先级寄存器 NVIC_IPRx,用来配置外部中断的优先级。优先级高低的比较包括抢占优先级和子优先级,先比较抢占优先级,如果抢占优先级相同就比较子优先级,从而得出中断之间的优先级高低。NVIC的主要任务就是给对应的中断源分配中断优先级。 中断优先级分配的原理繁杂,但固件库编程的好处就是化繁为简,我们只需要按照NVIC_InitStruct()中的内容进行配置就行。

    接下来简单讲解一下NVIC_Config()函数的内容:
    1.首先设置中断优先级分组
    中断优先级分组其实是确立一个大纲,中断优先级寄存器 NVIC_IPRx中有4个位用来确定优先级,中断优先级的分组就是把这4个位分配在抢占优先级和子优先级中。比如设定一个位配置抢占优先级,其余三个位配置子优先级。通过函数NVIC_PriorityGroupConfig() ; 实现分组,详细代码如下:

    1 /**
    2 * 配置中断优先级分组:抢占优先级和子优先级
    3 * 形参如下:
    4 * @arg NVIC_PriorityGroup_0: 0bit for 抢占优先级
    5 *                   		   4 bits for 子优先级
    6 * @arg NVIC_PriorityGroup_1: 1 bit for 抢占优先级
    7 *                            3 bits for 子优先级
    8 * @arg NVIC_PriorityGroup_2: 2 bit for 
    9 *                            2 bits for 子优先级
    10 * @arg NVIC_PriorityGroup_3: 3 bit for 抢占优先级
    11 *                           1 bits for 子优先级
    12 * @arg NVIC_PriorityGroup_4: 4 bit for 抢占优先级
    13 *                           0 bits for 子优先级
    14 * @注意 如果优先级分组为 0,则抢占优先级就不存在,优先级就全部由子优先级控制
    15 */
    16 void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup)
    17 {
    18 // 设置优先级分组
    19 SCB->AIRCR = AIRCR_VECTKEY_MASK | NVIC_PriorityGroup;
    20 }
    

    2.优先级分组完毕后,是配置NVIC初始化结构体

    typedef struct {
    2 uint8_t NVIC_IRQChannel; // 中断源
    3 uint8_t NVIC_IRQChannelPreemptionPriority; // 抢占优先级
    4 uint8_t NVIC_IRQChannelSubPriority; // 子优先级
    5 FunctionalState NVIC_IRQChannelCmd; // 中断使能或者失能
    6 } NVIC_InitTypeDef;
    

    初始化结构体的作用是,收集中断源的信息(包括配置的是哪一个中断源、中断源的抢占优先级是多少、中断源的子优先级是多少、中断源的使能是否开启)。
    NVIC_IROChannel:用来设置中断源,不同的中断中断源不一样,且不可写错,即使写错了程序也不会报错,只会导致不响应中断。 stm32f10x.h 头文件里面的 IRQn_Type 结构体定义,这个结构体包含了所有的中断源。
    NVIC_IRQChannelPreemptionPriority和NVIC_IRQChannelSubPriority 分别设置抢占优先级和子优先级,具体的值要根据中断优先级分组来确定。
    NVIC_IRQChannelCmd:设置中断使能(ENABLE)或者失能(DISABLE),相当于一个电源总开关。
    3.最后借助NVIC初始化函数将NVIC初始化结构体中的信息写入相应的寄存器中 (体现了固件库编程的优点,不需要我们深入到寄存器层次去,只需要掌握相应函数的配置即可)

    配置EXTI_Config()函数

    EXTI(External interrupt/event controller):外部中断/事件控制器,管理了控制器的 20个中断/事件线。每个中断/事件线都对应有一个边沿检测器,可以实现输入信号的上升沿检测和下降沿的检测。 EXTI 可以实现对每个中断/事件线进行单独配置,可以单独配置为中断或者事件,以及触发事件的属性。
    按我的理解,EXTI是一个有着多达20个接口的控制器,它可以为每一个接入接口的信号源配置中断(或事件)线、设置信号的检测方式、设置触发事件的性质,也就是说,传入EXTI的仅仅是一个信号,EXTI的功能就是根据信号传入的“线”对信号做出相应的处理,然后将处理后的信号转向NVIC。 就像一个分拣机器,传入的东西经过筛选处理被送往不同的地方,只是EXTI分拣的是信号罢了。 如果说NVIC是配置中断源,那么EXTI就是向NVIC传送中断信号。

    EXTI功能框图:
    在这里插入图片描述EXTI 可分为两大部分功能,一个是产生中断,另一个是产生事件,线路1-2-4-5是产生中断的流程,20/代表着有20条相同的线路。

    接下来讲解一下EXTI_Config()函数代码:

    void EXTI_Config() /* 主要是连接EXTI与GPIO */
    {
    	GPIO_InitTypeDef GPIO_InitStruct ;
    	EXTI_InitTypeDef EXTI_InitStruct ;
    	
    	NVIC_Config();
    
    	/* 初始化要与EXTI连接的GPIO */
    	/* 开启GPIOA与GPIOC的时钟 */
    	RCC_APB2PeriphClockCmd(KEY1_EXTI_GPIO_CLK | KEY2_EXTI_GPIO_CLK, ENABLE) ;
    	
    	GPIO_InitStruct.GPIO_Pin = KEY1_EXTI_GPIO_PIN ;
    	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING ;
    	GPIO_Init(KEY1_EXTI_GPIO_PORT , &GPIO_InitStruct) ;
    	
    	GPIO_InitStruct.GPIO_Pin = KEY2_EXTI_GPIO_PIN ;
    	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING ;
    	GPIO_Init(KEY2_EXTI_GPIO_PORT , &GPIO_InitStruct) ;
    	
    	/* 初始化EXTI外设 */
    	/* EXTI的时钟要设置AFIO寄存器 */
    	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE) ;
    	/* 选择作为EXTI线的GPIO引脚 */
    	GPIO_EXTILineConfig( KEY1_GPIO_PORTSOURCE , KEY1_GPIO_PINSOURCE) ;
    	/* 配置中断or事件线 */
    	EXTI_InitStruct.EXTI_Line = KEY1_EXTI_LINE ;
    	/* 使能EXTI线 */
    	EXTI_InitStruct.EXTI_LineCmd = ENABLE ;
    	/* 配置模式:中断or事件 */
    	EXTI_InitStruct.EXTI_Mode = EXTI_Mode_Interrupt ;
    	/* 配置边沿触发 上升or下降 */
    	EXTI_InitStruct.EXTI_Trigger = EXTI_Trigger_Rising ;
    	EXTI_Init(&EXTI_InitStruct) ;
    	
    	GPIO_EXTILineConfig( KEY2_GPIO_PORTSOURCE , KEY2_GPIO_PINSOURCE) ;
    	EXTI_InitStruct.EXTI_Line = KEY2_EXTI_LINE ;
    	EXTI_InitStruct.EXTI_LineCmd = ENABLE ;
    	EXTI_InitStruct.EXTI_Mode = EXTI_Mode_Interrupt ;
    	EXTI_InitStruct.EXTI_Trigger = EXTI_Trigger_Falling ;
    	EXTI_Init(&EXTI_InitStruct);
    }
    
    

    代码可大体分为三部分:
    配置GPIO相应引脚、配置EXTI并连接GPIO引脚、传入NVIC_Config()
    1.配置GPIO相应引脚
    该代码是通过按键产生一个电平信号,然后经EXTI处理传入NVIC产生中断的,所以要配置连接按键的GPIO引脚,主要是设置相应的引脚模式为浮空输入 。老规矩,先开启相应GPIO的时钟,然后配置引脚初始化结构体,再利用初始化函数将初始化结构体写入寄存器中。
    2.配置EXTI并连接GPIO引脚
    要操作外设,首先要打开相关的时钟,EXTI挂载在APB2总线上,并且开启时钟时要操作AFIO寄存器 ,准备工作就绪后连接GPIO相应的引脚到EXTI中,前面说了EXTI有20个接口,所以特定的引脚有特定的接口,所以要根据GPIO_EXTILineConfig();函数选择用作EXTI线的GPIO引脚,函数说明如下

    /**
      * @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线就对应GPIO引脚号,这样看起来还比较直观。
    连接好GPIO引脚与EXTI后就该配置EXTI的初始化结构体了,结构体如下:

    typedef struct 
    {
    	 uint32_t EXTI_Line; // 中断/事件线
    	 EXTIMode_TypeDef EXTI_Mode; // EXTI 模式
    	 EXTITrigger_TypeDef EXTI_Trigger; // 触发类型
    	 FunctionalState EXTI_LineCmd; // EXTI 使能
     } EXTI_InitTypeDef;
    

    配置此结构体主要是:选择相应的EXTI线 、选择触发模式、选择产生的结果(中断还是事件)、是否使能EXTI线。
    EXTI_Line:中断线选择,可选 EXTI_0 至 EXTI_19(一共20个)。既然刚才配置好了与GPIO引脚对应的EXTI线,所以初始化结构体中的EXTI线就是与GPIO连接的那个线。
    EXTI_Mode: EXTI 模式选择,可选为产生中断或者产生事件。就是决定信号的发展方向,是产生中断呢?还是产生事件呢?此处是中断。
    EXTI_Trigger: EXTI 边沿触发模式,可选上升沿触发、下降 沿 触 发 或 者 上 升 沿 和 下 降 沿 都 触 发。触发信号。
    EXTI_LineCmd:控制是否使能 EXTI 线,可选使能 EXTI 线或禁用。
    初始化结构体配置完毕后交由初始化函数写入相应的寄存器中。
    3.传入NVIC_Config()
    之后就自动传入NVIC中了。。。

    编写中断服务函数

    到这里就万事俱备只欠东风了,中断的触发与处理及优先级定义都已经安排上了,最后一步就是编写中断函数的内容了,只要进入中断就会执行中断函数中的代码,所以这是收尾工作。STM32的中断服务函数不同于51单片机中的中断服务函数,STM32的所有中断函数都被偷偷安排了,每个中断都有其固定的名字,只有找到这个名字,在这个固定的函数名下编写中断服务函数才是有效的,所有中断函数的编写都要在stm32f10x_it.c 中,如示:
    在这里插入图片描述
    从所给的信息可得知外设的中断服务函数的名字都存放在startup_stm32f10x_xx.s 中,而且是由汇编语言编写,如示:在这里插入图片描述
    可知EXTI线0到EXTI线4线都是单独的中断函数名、EXTI线5到EXTI线9共用一个中断函数名、EXTI线10线到EXTI线15线共用一个中断函数名。
    我们要做的就是以相应的EXTI线的中断函数名字在stm32f10x_it.c中编写中断函数 如下:

    void EXTI0_IRQHandler(void)
    {
    	if(  EXTI_GetITStatus(KEY1_EXTI_LINE)!=RESET)
    	{
    		LED1_TOGGLE;   //LED1的亮灭状态反转
    	}
    		
    	EXTI_ClearITPendingBit(KEY1_EXTI_LINE);
    		
    }
    
    
    void EXTI15_10_IRQHandler(void)
    {
    	if(  EXTI_GetITStatus(KEY2_EXTI_LINE)!=RESET)
    	{
    		LED2_TOGGLE;   //LED2的亮灭状态反转
    	}
    		
    	EXTI_ClearITPendingBit(KEY2_EXTI_LINE);
    		
    }
    
    

    每次进入中断函数后,靠ITStatus EXTI_GetITStatus(uint32_t EXTI_Line)读取中断是否执行 ,执行完之后要利用void EXTI_ClearITPendingBit(uint32_t EXTI_Line)清除清除中断标志位,以免不断进入中断

    大功告成

    到此完整的中断系统就已经完成,主函数只需调用即可!!!
    (附上主函数及俩个头文件)
    希望可以一起交流学习
    qq:2723808286

    #include "stm32f10x.h"
    #include "bsp_led.h"
    #include "bsp_key.h"
    
    int main(void)
    { 
    	LED_GPIO_Config();
    	EXTI_Config();
    	
    	while(1) 
    	{
    	}
    }
    
    
    
    #ifndef __BSP_KEY_H
    #define __BSP_KEY_H
    
    #include "stm32f10x.h"
    
    #define KEY1_EXTI_GPIO_CLK      RCC_APB2Periph_GPIOA
    #define KEY1_EXTI_GPIO_PORT     GPIOA
    #define KEY1_EXTI_GPIO_PIN      GPIO_Pin_0
    #define KEY1_EXTI_IRQN          EXTI0_IRQn      /* 对应着引脚号 */
    #define KEY1_EXTI_LINE          EXTI_Line0      /* 中断、事件线对应引脚号 */
    #define KEY1_GPIO_PORTSOURCE    GPIO_PortSourceGPIOA
    #define KEY1_GPIO_PINSOURCE     GPIO_PinSource0
    #define  KEY1_EXTI_IRQHANDLER       EXTI0_IRQHandler
    
    #define KEY2_EXTI_GPIO_CLK      RCC_APB2Periph_GPIOC
    #define KEY2_EXTI_GPIO_PORT     GPIOC
    #define KEY2_EXTI_GPIO_PIN      GPIO_Pin_13
    #define KEY2_EXTI_IRQN          EXTI15_10_IRQn
    #define KEY2_EXTI_LINE          EXTI_Line13
    #define KEY2_GPIO_PORTSOURCE    GPIO_PortSourceGPIOC
    #define KEY2_GPIO_PINSOURCE     GPIO_PinSource13
    #define  KEY2_EXTI_IRQHANDLER       EXTI15_10_IRQHandler
    
    
    void EXTI_Config(void);
    	
    #endif
    
    
    #ifndef __BSP_LED_H
    #define __BSP_LED_H
    
    #include "stm32f10x.h"
    
    
    
    #define LED1_GPIO_CLK   RCC_APB2Periph_GPIOC   /*时钟*/
    #define LED1_GPIO_PORT  GPIOC                  /*端口*/
    #define LED1_GPIO_PIN   GPIO_Pin_2             /*引脚*/
    
    
    #define LED2_GPIO_PIN   GPIO_Pin_3
    #define LED2_GPIO_CLK   RCC_APB2Periph_GPIOC
    #define LED2_GPIO_PORT  GPIOC
    
    #define digitalTOGGLE(p,i)     {p->ODR ^=i;}
    #define LED1_TOGGLE            digitalTOGGLE(LED1_GPIO_PORT,LED1_GPIO_PIN)
    #define LED2_TOGGLE            digitalTOGGLE(LED2_GPIO_PORT,LED2_GPIO_PIN)  /* LED状态反转 */
     void LED_GPIO_Config(void);                   
    
    #endif
    
    
    
    展开全文
  • 这里写目录标题先验知识回顾控制寄存器回顾1、8086中断类型1、外部可屏蔽中断2、外部不可屏蔽中断3、除法错中断4、单步中断5、断点中断6、溢出中断7、软中断2、8086中断向量表3、8086中断响应1、外部可屏蔽中断响应2...

    博主联系方式:
    QQ:1540984562
    微信:wxid_nz49532kbh9u22 QQ交流群:892023501

    先验知识回顾

    控制寄存器回顾

    1
    PSW是Program Status Word的缩写,即程序状态字(也叫程序状态寄存器)
    CS:段代码寄存器。

    1、8086中断类型

    8086用8位二进制码表示一个中断类型,共有256个中断,可分为两大类:
    1
    中断结构:
    2

    1、外部可屏蔽中断

    由INTR引入,受到标志寄存器中的中断允许标志位IF控制。
    IF=0:CPU不响应INTR中断;
    IF=1:CPU响应INTR中断;
    INTR中断的类型码范围:8~255;

    2、外部不可屏蔽中断

    由NMI引入,不受到中断允许寄存器标志位IF控制。
    NMI信号有效,且8086现行指令执行结束,且没有DMA请求:响应NMI中断
    NMI中断类型码:2

    3、除法错中断

    在执行DIV或者IDIV指令时,除数为0或商超过寄存器能够表达的范围(商溢出):执行中断。
    中断类型号:0.
    (我寻思着,在做除法操作的时候就可以避免这种现象的存在,没有必要搞个中断啊。。。)

    4、单步中断

    受到标志位寄存器中的陷阱标志位TF控制。
    TF=1:CPU每执行完一条指令就引起一个内部中断。
    TF=0:无
    中断类型号:1
    用途:用于实现但不操作,是一种强有力的调试手段。(联系debug中相关操作)

    5、断点中断

    由INT3指令产生的内部中断。
    在程序调试过程中,需要跟踪程序走向,了解程序执行过程中的中间结果时,可以用INT3指令临时替代原有的指令,称为设置断点。
    中断类型号:3

    6、溢出中断

    受到标志寄存器中的溢出标志位OF控制。
    若上条指令执行结果使OF=1,则产生中断。
    中断类型号:4

    7、软中断

    由INTn指令产生。
    中断类型码:n

    2、8086中断向量表

    两个知识点:
    中断向量:中断指针,是中断服务程序的入口地址
    中断向量表:中断类型号与对应的中断服务函数入口地址的换算表。
    8086的中断向量表如下:
    1

    3、8086中断响应

    1、外部可屏蔽中断响应

    1、等待当前指令结束,然后进入中断响应周期。
    2、CPU获取中断类型号
    3、当前的PSW、CS、IP的内容依次压入栈中。(保存了断点的状态和断点地址,以便返回时恢复)
    4、清除PSW中的IF位和TF位。(IF=0意味着关中断,这里不包含中断嵌套)
    5、把中断服务函数的入口地址置入IP和CS
    6、完成响应,进入中断服务函数

    2、外部不可屏蔽中断响应

    中断请求在NMI端加入。
    等待当前指令执行结束.如果同时出现非屏蔽和可屏蔽中断请求,CPU优先响应非可屏蔽。
    中断类型号由硬件决定,不需要从外部获取。其他操作与可屏蔽中断相同

    3、内部中断响应

    内部中断的响应操作的共同特点:
    1、中断类型号来源于:指令码、CPU硬件,不需要从外部获取
    2、没有INTA’信号的响应周期
    3、不受到IF位的控制,但单步中断受TF位控制
    4、除单步中断之外,其他内部中断都比外部中断优先响应
    5、同样执行可屏蔽中断的3、4、5操作
    特别说明:
    中断响应时应清除TF标志位意味着什么?
    TF=1,没执行完一条指令都引起一次单步中断。如果不清除,将不停地引起中断,每次中断都执行同一条指令而不能反悔。
    所以,中断服务函数期间TF=0,等到IRET指令恢复PSW值是,才恢复TF位。

    4、8086中断返回

    无论内部外部中断,中断返回都是由中断服务函数的末尾设置IRET指令实现的。
    IRET指令的操作是:恢复断点处的地址和PSW内容:依次从堆栈中弹出保存的IP、CS、PSW值,使被中断的程序继续执行


    参考书籍:

    《微机原理与接口技术》

    展开全文
  • STM32 串口中断总结

    万次阅读 多人点赞 2017-12-25 17:03:17
    本文以USART1为例,叙述串口中断的编程过程。 1、先来讲述一下在应用串口中断时涉及到的一些库文件。 首先对于STM32外设库文件的应用编程,misc.c和stm32f10x_rcc.c是肯定要添加到。 接下来就是我们要用到的相关...

    更多精彩内容关注 微信公众号“广乙电子(dlrcclub)”

    本文以USART1为例,叙述串口中断的编程过程。

    1、先来讲述一下在应用串口中断时涉及到的一些库文件。

    首先对于STM32外设库文件的应用编程,misc.c和stm32f10x_rcc.c是肯定要添加到。

    接下来就是我们要用到的相关外设了。毫无疑问,串口文件stm32f10x_usart.c是必须的。串口通信是对通用GPIO端口引脚的功能复用,所以还需要stm32f10x_gpio.c文件。另外,因为有中断的产生,所以中断文件stm32f10x_it.c也是必要的,当然这个文件一般和main.c放在一个文件夹下(一般习惯为User文件夹),因为我们的中断响应函数是要在里面自己编写的。

    当然还有其他的基本必须文件如系统配置文件等在这地方就不说了,这个是创建一个工程应该知道的。

    2、初始化

    对于串口通信的初始化,不仅仅只是对串口的初始化(这个地方是比较烦人的,不像别的芯片那样简洁明了)。

    l 首先时钟使能配置。STM32内部的时钟有很多,感兴趣的自己看看参考手册。此处以USART1为例说明。有USART1时钟、GPIOA时钟、GPIO复用(AFIO)时钟。由于此处USART1和GPIOA、AFIO均在APB2上,所以可以一次配置完成。如下:

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_AFIO|RCC_APB2Periph_USART1 ,ENABLE);

    l 其次中断配置。主要有优先级组设定、USART1中断使能、该中断的优先级,中断初始化。程序如下:

    void NVIC_Configuration(void)

    {

      NVIC_InitTypeDef NVIC_InitStructure;

      NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);//选择分组方式0

      

      /* 使能 USART1 中断 */

      NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;

      NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;

      NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

      NVIC_Init(&NVIC_InitStructure);

    }

    l 然后GPIO复用功能配置。一般情况下我们使用原始的外设和GPIO端口引脚的映射关系,如果要改变其映射的话,请另外查看参考手册上关于GPIO重映射部分。对于GPIO的复用,其引脚的输入与输出模式都有要求,在参考手册上有详细说明。

    void GPIO_Configuration(void)

    {

      GPIO_InitTypeDef GPIO_InitStructure;

      /* 配置 USART1 Rx 作为浮空输入 */

      GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;

      GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;

      GPIO_Init(USARTy_GPIO, &GPIO_InitStructure);

      /* 配置 USART1 Tx 作为推挽输出 */

      GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;

      GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

      GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;

      GPIO_Init(USARTy_GPIO, &GPIO_InitStructure);

    }

    l 串口初始化配置。主要有串口基本参数配置(如波特率、数据位、工作方式等),串口中断使能,串口使能。

    (1) 基本参数配置

    USART_InitTypeDef USART_InitStructure;

    USART_InitStructure.USART_BaudRate = 9600;//波特率

    USART_InitStructure.USART_WordLength = USART_WordLength_8b;//数据长度

    USART_InitStructure.USART_StopBits = USART_StopBits_1;//停止位

    USART_InitStructure.USART_Parity = USART_Parity_No;//校验

    USART_InitStructure.USART_HardwareFlowControl

    =USART_HardwareFlowControl_None; //硬件流控制无

    USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //发送与接受两种方式

    USART_Init(USART1, &USART_InitStructure);//用配置的参数惊喜串口初始化

    (2) 串口中断使能

    USART_ITConfig(USARTy, USART_IT_RXNE, ENABLE);//使能接受中断,在接受移位 寄存器中有数据是产生

    USART_ITConfig(USARTy, USART_IT_TXE, ENABLE);//使能发送中断,在发送完数据 后产生。

    一般情况下,如果与PC通信的话,我们只用接受中断即可。

    (3) 串口使能

    USART_Cmd(USART1, ENABLE); //USART1使能

    好了,经过以上不走之后呢,我们就可以进行数据的收发了。

    3、发送数据

    使用函数USART_SendData(USART1, char data),一次只能发送一个字符。当然我们可以用如下函数发送字符串。

    void USART1_Puts(char * str) 

    while(*str) 

    USART_SendData(USART1, *str++);  //发送一个字符

    while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);  //等待发送完毕

    }

    当然我们也可以循环发送字符串数组

    for(i = 0; TxBuf1 != '\0'; i++) // TxBuf1为定义好的字符串数组

    {

    USART_SendData(USART2 , TxBuf1);

    while(USART_GetFlagStatus(USART2, USART_FLAG_TC)==RESET);

    }

    4、接收数据

    由于我们使用的是接受中断,所以当有数据需要接收时,会执相应的中断函数。此处我们USART1的中断函数在stm32f10x_it.c文件中。找到函数void USART1_IRQHandler(void),如果没有的话就自己加上吧,别忘了头文件中需要声明一下。当然你也可以在其他文件中写下该中断函数。当产生中断进入该函数之后,我们就可以进行自己的操作了。

    void USARTy_IRQHandler(void)

    {

      if(USART_GetITStatus(USARTy, USART_IT_RXNE) != RESET)//如果寄存器中有数据

      {

        /* Read one byte from the receive data register */

        RxBuffer1[RxCounter1++] = USART_ReceiveData(USART1);

      }

      /*************************************************************

      if(USART_GetITStatus(USARTy, USART_IT_TXE) != RESET)

      {   

            USART_SendData(USARTy, TxBuffer1[TxCounter1++]);

      }    

    //这个地方那个之所以把这个写出来主要是想说发送中断和接受中断其实是共用一个

    //中断函数的,到底是那个中断发生了呢,这就需要我们读取中断状态标志来识别了。

    *****************************************************************/

    }

    别忘了在接受完数据进行别的操作之前为了防止数据被覆盖最好先禁止一下接受中断 /* 禁止 USART1 接收中断 */

     USART_ITConfig(USART1, USART_IT_RXNE, DISABLE);

    /* 禁止 USART1 发送中断 */

    USART_ITConfig(USART1, USART_IT_TXE, DISABLE);

    5、main函数

    int main(void) //这个地方和特别,我们知道一般main函数是没有返回值的,但在STM32 //的编程中其返回类型为int。

    {

      RCC_Configuration();

      NVIC_Configuration();

      GPIO_Configuration();

      USART_InitStructure.USART_BaudRate = 9600;

      USART_InitStructure.USART_WordLength = USART_WordLength_8b;

      USART_InitStructure.USART_StopBits = USART_StopBits_1;

      USART_InitStructure.USART_Parity = USART_Parity_No;

      USART_InitStructure.USART_HardwareFlowControl= USART_HardwareFlowControl_None;

      USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;

      USART_Init(USART1, &USART_InitStructure);

      

      USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);

      //USART_ITConfig(USART1, USART_IT_TXE, ENABLE);

      USART_Cmd(USART1, ENABLE);

      while (1)//等待中断

      {

      }

    }

    当然你也可以在main()中添加一些发送指令之类的东西。

    以上内容为个人总结,转载请注明出处。若有错误,本人概不负任何责任。

    展开全文
  • 中断从硬件到内核的路由 概念 从物理学的角度看,中断是一种电信号,由硬件设备生成,并直接送入中断控制器的输入引脚上。 然后再由中断控制器向处理器发送相应的信号。处理器一经检测到此信号,便中断自己的当前...
  • 51单片机中断系统

    万次阅读 多人点赞 2018-12-11 20:04:08
    中断定义  CPU在处理某一事件A时,发生了另一事件B请求CPU迅速去处理(中断发生); CPU暂时中断当前的工作,转去处理事件B(中断响应和中断服务); 待CPU将事件B处理完毕后,再回到原来事件A被中断的地方继续...
  • 重要声明: 以下代码有粘贴 截取他人劳动成果的成分 如有雷同 不胜荣幸 如您不能容忍 请不要独自忍受@weChat:iisssssssssii 联系小民 主动删除  中断含义:  ...引起中断的原因或者说发出中断请求的
  • Arduino 定时器中断 外部中断

    万次阅读 多人点赞 2019-04-09 17:29:31
    但如果此时发生了某一件事件B请求CPU迅速去处理(中断发生),CPU暂时中断当前的工作,转去处理事件B(中断响应和中断服务),待CPU将事件B处理完毕后,再回到原来被中断的地方继续执行程序(中断返回),这一过程成...
  • 【STM32】HAL库 STM32CubeMX教程六----定时器中断

    万次阅读 多人点赞 2019-08-13 09:10:04
    是我们学习STM32最频繁使用到的外设之一,所以一定要掌握好,这节我们讲解定时器中断,本系列教程将对应外设原理,HAL库与STM32CubeMX结合在一起讲解,使您可以更快速的学会各个模块的使用 所用工具: 1、芯片:...
  • 外部中断和定时器中断

    万次阅读 多人点赞 2018-11-20 13:53:27
    1.什么是中断 2.中断有什么用 3.双重功能的P3引脚 4.8051的 中断体系 5.中断特殊寄存器 6.中断的优先级 7.中断服务程序的编写 8.外部中断实现代码 9.定时器/计数器中断工作原理 10.定时器/计数器定时值的...
  • 中断和硬中断

    千次阅读 2020-08-26 21:36:10
    中断:由与系统相连的外设(比如网卡、硬盘)自动产生的。主要是用来通知操作系统系统外设状态的变化。比如当网卡收到数据包的时候,就会发出一个中断中断: 通常是硬中断服务程序对内核的中断;2.为了满足实时...
  • 中断中断处理过程

    万次阅读 多人点赞 2019-07-24 22:00:23
    1. 中断和异常的概念区别 Intel的官方文档里将中断和异常理解为两种中断当前程序执行的不同机制。这是中断和异常的共同点。 不同点在于: 中断(interrupt)是异步的事件,典型的比如由I/O设备触发;异常...
  • 51 中断系统 外部中断0 外部中断1

    万次阅读 多人点赞 2019-06-14 22:26:11
    51单片机的中断系统结构 中断允许控制 CPU对中断系统所有中断以及某个中断源的开放和屏蔽是由中断允许寄存器IE控制的。 EX0(IE.0),外部中断0允许位; ET0(IE.1),定时/计数器T0中断允许位; EX1(IE.2),...
  • 中断和软中断

    万次阅读 多人点赞 2014-03-27 16:21:59
    本文主要内容:硬中断 / 软中断的原理和实现 内核版本:2.6.37 Author:zhangskd @ csdn blog   概述   从本质上来讲,中断是一种电信号,当设备有某种事件发生时,它就会产生中断,通过总线把电信号发送给...
  • 中断 TMOD:定时器/计数器工作方式寄存器 TCON:定时器/计数器控制寄存器 IE:中断允许控制寄存器 IP:中断优先级控制寄存器 外部中断0 外部0中断触发:(P3.2口触发;P3.2触发;P3.2触发) 若IT0=0,则为低电平触发...
  • zynq有三种中断:软中断(software interrtpts),私有外设中断(private peripheral)和共享外设中断(shared perlpherals)。区别在于私有外设中断和共享外设中断含有PL测引入的中断。*每个中断都有自己ID号。*有一个...
  • 中断向量,中断向量表 ,中断服务函数

    千次阅读 多人点赞 2019-07-29 12:31:52
    所谓中断是指CPU在正常执行程序的过程中,由于内部/外部事件的触发或由程序的预先安排,引起CPU暂时中断当前正在运行的程序,而转去执行为内部/外部事件或程序预先安排的事件的服务子程序,待中断服务子程序执行完毕...
  • 是指中断系统正在执行一个中断服务时,有另一个优先级更高的中断提出中断请求,这时会暂时终止当前正在执行的级别较低的中断源的服务程序,去处理级别更高的中断源,待处理完毕,再返回到被中断了的中断服务程序继续...
  • 单片机 中断

    万次阅读 多人点赞 2018-05-30 23:03:30
    单片机 中断一、简述 中断,即CPU在正常执行程序的过程中,遇到外部/内部的紧急事件需要处理,暂时中断(中止)当前程序的执行,而转去为事件服务,待服务完毕,再返回到暂停处(断点)继续执行原来的程序。二、中断...
  • STM32中断(外部中断和定时器中断)

    千次阅读 多人点赞 2019-05-27 17:22:00
    一、外部中断 spi,iic的中断和51单片机不一样,这些在stm32属于外设,是外部中断。 因为STM32的中断非常多,因此必须设置中断优先级 STM32有两个优先级的概念:抢占式优先级和响应式优先级(亚优先级,副优先级) ...
  • 【STM32】NVIC中断优先级管理(中断向量表)

    万次阅读 多人点赞 2018-04-08 19:55:22
    Cortex-M3内核支持256个中断,其中包含了16个内核中断(异常)和240个外部中断,并且具有256级的可编程中断设置。但是,STM32并没有使用CM3内核的全部东西,而是只用了它的一部分。STM32有84个中断,包括16个内核...
  • Linux 中断中断处理浅析

    万次阅读 多人点赞 2019-01-17 14:15:09
    1. 中断的概念 中断是指在CPU正常运行期间,由于内外部事件或由程序预先安排的事件引起的 CPU 暂时停止正在运行的程序,转而为该内部或外部事件或预先安排的事件服务的程序中去,服务完毕后再返回去继续运行被暂时...
  • 程序中断

    千次阅读 2016-08-30 17:02:28
    中断请求触发器(INTR),中断屏蔽触发器(MASK)二者成对出现。 接口中的完成触发器D,为1表示设备准备就绪。 中断源:凡是能够向CPU提出中断请求的各种因素都叫中断源。因此,有多个中断源,但是,CPU某一时刻只...
  • 中断向量 中断向量表

    千次阅读 2015-05-27 11:24:39
    1、中断标识码(中断类型号):由硬件(通常是中断控制器)产生,以标识不同的中断源。 2、中断向量:早期的微机系统中将由硬件产生的中断标识码(中断源的识别标志,可用来形成相应的中断服务程序的入口地址或存放...
  • 中断和外中断的区别

    千次阅读 2019-07-07 16:40:18
    我发现内中断和外中断其实区别不是很大,外中断不过是在内中断的前提上多了一个对端口(端口号是60H)的扫描,再来个对比。当扫描码和我预设的中断扫描码相同时,执行中断。当他们的值不同时,就跳出这个中断。 ...
  • 中断和硬中断的区别

    千次阅读 2019-06-05 14:52:47
    ②硬中断中断响应周期,CPU需要发中断回合信号(NMI不需要),软中断中断响应周期,CPU不需发中断回合信号。③硬中断中断号是由中断控制器提供的(NMI硬中断中断号系统指定为02H);软中断中断号由指令直接...
  • 中断优先级

    千次阅读 2019-05-12 16:57:34
    中断优先级 文章参考:https://blog.csdn.net/huangtonggao/article/details/6441876 结论: 1)抢占优先级越小,优先级越高;相同抢占优先级的中断不能嵌套; 2)相同抢占优先级N个中断发生时,响应优先级越小的...
  • STM32中断设置以及中断优先级设置

    万次阅读 多人点赞 2018-09-13 15:26:45
    最近,在做一个智能锁的项目,由于,今天碰到了一个关于中断的问题,因此,又回来好好啃一下中断配置的知识,俗话说:磨刀不误砍柴工。问题是什么呢?项目中我用到了一个触摸键盘TTP229,结果在测试键盘时,不能够...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 954,931
精华内容 381,972
关键字:

中断