什么是中断?中断的流程是什么样?:
一种处理系统内发生非寻常的或非预期的急需处理事件机制,叫做中断。
在MCU执行程序期间,系统内发生任何非寻常的或非预期的急需处理事件,使得CPU暂时中断当前正在执行的程序而转去执行相应的时间处理程序。待处理完毕后又返回原来被中断处继续执行过程。几乎所有的计算机系统都具备这种机制。
STM32中断分类:
CPU内核中断和核外外设中断,其中内核中断,在官方手册上,内核中断叫异常(exception)和核外外设中断才叫中断(interrupt),其实是一回事。
补充:
所有的中断用一个表管理起来,编号 为 0~15 的称为内核异常(需要说明的是,16个编号的内核中断,但是STM32,本身的内核中断是11个,还有5个是保留的没用的),而 16 以上的则称为核外中断(外,相对内核而言,对于不同系列的STM32,大致的编号和数量相同,但是对于高级的,比如互联型系列等,因为偏上外设要多一些,所以中断的数量也会多一些),这个表就称为中断向量表。 这个中断向量表,这个中断向量表,本质上可以理解成一个4个字节类型Int的数组,每一个元素就是放的是对应编号的中断处理程序的入口地址,数组编号其实相当于中断编号。这个中断向量表,放在程序最开头位置(根据STM32存储映射,起始地址的512K区域,根据boot0和boot1分别映射到系统程序、SRAM和flash,映射到flash和SRAM的时候,起始地址从0x00000000开始放的就是这个中断向量表)。
在ST公司提供的启动文件中为每一个中断默认定义了一个中断处理函数,如果我们自己重新写中断处理函数,会屏蔽掉默认的这个函数。
中断管理机制:
STM32有多个中断,当这些中断同时发生时,需要有执行先后等关系,管理这些引入了一个专门的中断管理机制叫NVIC(内嵌向量中断控制器),相关硬件在CPU内部。控制着中断的相关功能(其中包括中断源、抢占优先级、响应优先级、中断的使能与失能),具体的配置方法后面会提到。
固件库中NVIC相关的结构体:
填充这4个成员,进行初始化。
中断源
取值都在枚举类型IRQn_Type中,在stm32f10x.h
stm32里面的优先级
在stm32中,一个中断的优先级由两部分决定,一个是抢占式优先级,还有一个是响应优先级。两个优先级组成了一个4位的控制字。
如图:
那么我们就会问,这有四位,那两个优先级各占多少位。就像图中所展示的,抢占式优先级(黄色)可以沾满四位,也可以一位都不占,如果占满四位,则抢占式优先级共有0-15这些等级,占满2位,就有0-3这些等级。同理响应优先级也是这样。分配他们各占多少位的函数为:
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);后面这个数字代表的是抢占式优先级的位数
抢占式优先级和响应优先级分析
这两个优先级中,抢占式优先级占主导地位,抢占式优先级高的中断会优先打断主程序或者另外一个中断程序。
如果两个中断的抢占式优先级一样高,当两个中断同时发生时,响应优先级高的先发生,完了再发生另一个。但是要注意,响应优先级高的中断不会打断低的中断,也就是当一个高响应优先级的中断来时,如果正在执行一个低的中断,他不会打断他,而是等待低的执行完在执行。也就是说只有高抢占式优先级可以阻断。
基于标准固件库V3.50中断编程的应用:
1.需要全局配置中断分组。
比如:NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
2.对于某个具体的中断源,配置其相应的NVIC。填写结构体,调用
以串口为例
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3 ;//ÇÀÕ¼ÓÅÏȼ¶3
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //×ÓÓÅÏȼ¶3
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQͨµÀʹÄÜ
NVIC_Init(&NVIC_InitStructure); //¸ù¾ÝÖ¸¶¨µÄ²ÎÊý³õʼ»¯VIC¼Ä´æÆ&pide;
3.产生中断的,引发中断,进入中断处理函数的时间配置。
通常是XXX__ITConfig 其中XXX代表某个具体的外设
4.中断处理函数:
中断处理函数不能随便填写,必须要一个固定的函数名字,具体某个偏上外设对应的中断处理函数,需要到,启动文件
这个文件里去找。
5.在进入相应中断处理函数后
首先需要需要判断XXX_GetITStatus 是不是我们前面对应设置的中断事件
6.在处理完了相应的中断函数后调用,有一个类似 _ClearIT 函数清除相应的标志位