一、中断
由于某个事件的发生,CPU暂停当前正在执行的程序,转而执行处理事件的一个程序。该程序执行完成后,CPU接着执行被暂停的程序。这个过程称为中断。(我正在捉泥鳅,但是我妈喊我回家吃饭,我必须回家吃饭,回家途中,发现泥鳅没带,回去把泥鳅带回家,然后吃完饭继续捉泥鳅!!!)
中断是CPU处理外部突发事件的一个重要技术。引起中断的原因或者说发出中断请求的来源叫做中断源。根据中断源的不同,可以分为硬件中断和软件中断两大类,有了中断,系统可以更好更快的利用有限的系统资源解决系统响应速度和运行效率的一种控制技术。它的作用就是可以使你的电脑系统运行更快更平稳。
一方面,有了中断功能,系统就可以使CPU和外设同时工作,使系统可以及时的响应外部事件。而且有了中断功能,CPU可以允许多个外设同时工作。这样就大大提高了CPU的利用率,也提高了数据输入、输出速度。另一方面,有了中断功能,就可以使CPU及时处理各种软硬件故障。计算机在运行过程中,往往会出现事先预料不到的情况或出现一些故障,如电源掉电,存储出错,运算溢出等等。计算机可以利用中断处理系统自行处理,而不必停机或报告工作人员。
1、硬件中断根据来源的位置分为:
内部中断(不可屏蔽中断):少数,中断源在CPU的内部,如突然掉电,奇偶校验错、除数为0、运算溢出、单步中断(软件调试时可以使用,每执行一条指令,就中断一次)等
外部中断(可屏蔽中断):多数,中断源在CPU的外部,一般是指由计算机外设发出的中断请求,如键盘中断、打印机中断、定时器中断。可以使用中断控制器屏蔽外部设备的中断。
2、是否可屏蔽分为:
可屏蔽中断
不可屏蔽中断
3、中断来源:
软件中断
硬件中断
二、中断与事件
概念:
事件:是表示检测到某一动作(电平边缘)触发事件发生了,由硬件自动完成的触发到产生结果的通道解决(响应速度快)。
中断:有某个事件发生并产生中断,并跳转到对应的中断处理程序中,需要CPU接入(响应速度慢)。
区别:
中断有可能被更优先的中断屏蔽,事件不会;事件本质上就是一个触发信号,是用来触发特定的外设模块或核心本身(唤醒);事件只是一个触发信号(脉冲),而中断则是一个固定的电平信号;事件是中断的触发源,事件可以触发中断,也可以不触发,开放了对应的中断屏蔽位,则事件可以触发相应的中断。事件还是其它一些操作的触发源,比如DMA(Direct Memory Access,直接存储器存取),还有TIM中影子寄存器的传递与更新。
简言之,中断一定要有中断服务函数,中断必须要CPU介入,但是事件却没有对应的函数。事件可以在不需要CPU干预的情况下,执行某些操作,事件机制提供了一个完全由硬件自动完成的触发到产生结果的通道,不要软件的参与,降低了CPU的负荷,节省了中断资源,提高了响应速度(硬件总快于软件),是利用硬件来提升CPU芯片处理事件能力的一个有效方法;
三、实验内容
实验中按下按键0触发中断线4,抢占优先级2,子优先级为2,中断反应函数EXTI4_IRQHandler(),控制LED0和LED1的状态取反
1、初始化IO口为输入 KEY_Init();
2、开启AFIO时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
3、设置IO口与中断线的映射关系 GPIO_EXTILineConfig(GPIO_PortSourceGPIOE, GPIO_PinSource4);
4、初始化线上中断,设置触发条件等 EXTI_Init(&KST_EXTI_Structure);
5、配置中断分组(NVIC),并使能中断 NVIC_Init(&KST_NVIC_Structure);
6、编写中断服务函数 EXTI4_IRQHandler();
7、清除中断服务函数 EXTI_ClearITPendingBit(EXTI_Line4);
1 #include "exti.h" 2 #include "key.h" 3 #include "led.h" 4 #include "beep.h" 5 #include "delay.h" 6 #include "usart.h" 7 8 9 void EXTIX_Init(void) 10 { 11 EXTI_InitTypeDef KST_EXTI_Structure; 12 NVIC_InitTypeDef KST_NVIC_Structure; 13 14 KEY_Init(); //按键初始化 15 16 RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); //使能IO口复用时钟 17 18 GPIO_EXTILineConfig(GPIO_PortSourceGPIOE, GPIO_PinSource4); //设置IO口与中断线的映射关系 19 20 KST_EXTI_Structure.EXTI_Line = EXTI_Line4; //配置中断线4 21 KST_EXTI_Structure.EXTI_LineCmd = ENABLE; //使能 22 KST_EXTI_Structure.EXTI_Mode = EXTI_Mode_Interrupt; //外部中断 23 KST_EXTI_Structure.EXTI_Trigger = EXTI_Trigger_Falling; //下降沿触发 24 EXTI_Init(&KST_EXTI_Structure); //初始化线上中断,设置触发条件 25 26 KST_NVIC_Structure.NVIC_IRQChannel = EXTI4_IRQn; 27 KST_NVIC_Structure.NVIC_IRQChannelCmd = ENABLE;//IRQ通道使能 28 KST_NVIC_Structure.NVIC_IRQChannelPreemptionPriority = 2;//抢占优先级2 29 KST_NVIC_Structure.NVIC_IRQChannelSubPriority = 2; //子优先级2 30 NVIC_Init(&KST_NVIC_Structure); //中断优先级初始化 31 32 } 33 34 void EXTI4_IRQHandler(void) 35 { 36 delay_ms(10); 37 if(KEY0==0) 38 { 39 LED0 = !LED0; 40 LED1 = !LED1; 41 } 42 EXTI_ClearITPendingBit(EXTI_Line4); //手动清除中断线4的标志位 43 }
主函数
1 #include "sys.h" 2 #include "exti.h" 3 #include "beep.h" 4 #include "key.h" 5 #include "delay.h" 6 #include "led.h" 7 #include "usart.h" 8 9 int main() 10 { 11 delay_init(); 12 LED_Init(); //LED初始化 13 KEY_Init(); //按键初始化 14 BEEP_Init(); //蜂鸣器初始化 15 EXTIX_Init(); //外部中断初始化 16 uart_init(115200); //串口初始化 17 LED0 = 0; 18 NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级 19 while(1) 20 { 21 printf("OK\r\n"); 22 delay_ms(1000); 23 } 24 25 } 26 27