中断介绍
1:在单片机系统中,如果遇到需要紧急处理的突发事件时,CPU需要迅速的作出反应,暂停正在运行的程序来处理突发事件,这时就需要中断
2:中断是指单片机正在执行程序的时,发生突发事件从而打断当前程序,转而去处理这一事件,当处理完成后再回到原来被打断出继续执行原程序的过程
异常
异常是导致程序流更改的事件。当发生异常时,处理器暂停当前正在执行的任务,并执行程序中称为异常处理程序的一部分。异常处理程序的执行完成后,处理器将恢复正常的程序执行。在ARM体系结构中,中断是一种异常类型。中断通常由外设或外部输入产生,在某些情况下,它们可以由软件触发。中断的异常处理程序也称为中断服务例程(ISR)
每个异常源都有一个异常编号。异常编号1至15为系统异常,异常编号16及以上为中断。Cortex-M3和Cortex-M4处理器中的NVIC设计可支持多达240个中断输入。然而,在实践中,设计中实现的中断输入数量要少得多,通常在16到100之间。通过这种方式,设计的硅尺寸可以减小,这也降低了功耗。
在stm32中存在一个嵌套矢量中断控制器(NVIC)
NVIC是Cortex-M处理器的一部分。它是可编程的,其寄存器位于内存映射的系统控制空间(SCS)中
NVIC处理异常和中断配置、优先级和中断屏蔽。NVIC具有以下功能:
?灵活的异常和中断管理
?嵌套异常/中断支持
?矢量化异常/中断条目
?中断屏蔽
异常类型
1:系统异常
2:中断
3:中断控制
重置后,将禁用所有中断,并将优先级值设置为0。在使用任何中断之前,您需要:
设置所需中断的优先级(此步骤是可选的)
在触发中断的外围设备中启用中断生成控制
在NVIC中启用中断
在大多数典型的应用程序中,这就是您需要做的全部工作。当中断触发时,相应的中断服务例程(ISR)将执行(您可能需要清除处理程序内外围设备的中断请求)。ISR的名称可以在启动代码的矢量表中找到,启动代码也是由微控制器供应商提供的。ISR的名称需要与向量表中使用的名称匹配,以便链接器可以将ISR的起始地址正确地放入向量表中。
中断资源介绍
在介绍资源时我们先了解一下EXTI
EXTI 控制器的主要特性:
每个中断/事件线上都具有独立的触发和屏蔽
每个中断线都具有专用的状态位
支持多达23个软件事件/中断请求
检测脉冲宽度低于APB2 时钟宽度的外部信号
从图中看出和外部中断有关的寄存器有:上升沿触发选择、下降沿触发选择、软件中断事件寄存器、中断屏蔽寄存器、挂起请求寄存器、事件屏蔽寄存器和NVIC中断控制寄存器等。此外就是对输入线的理解了。
在stm32f4系列中具有140个GPIO 通过以下方式连接到16个外部中断\事件线上
例如:PA0占用了EXTI0则PB0·PG0则不可使用
另外还有七根线的连接
简单介绍了一下EXTI后我们需要了解在这么多中断时加入同时发生中断我们应该先执行哪一个中断,下面我们介绍一下NVIC控制器
NVIC 控制器是控制中断优先级的
中断优先级的一个意义:出现多个中断同时触发,但是不能同时处理,所以先后顺序之分,要根据实际上的运行环境优先处理重要的中断。
1.概述
STM32 对中断优先级进行分组,共 5 组,组 0~4,这些分组是用于指定当前M4支持多少个抢占优先级和多少个响应优先级。同时,对每个中断设置一个抢占优先级和一个响应优先级。函数原型如下
/** * @brief Configures the priority grouping: pre-emption priority and subpriority. * @param NVIC_PriorityGroup: specifies the priority grouping bits length. * This parameter can be one of the following values: * @arg NVIC_PriorityGroup_0: 0 bits for pre-emption priority //不支持抢占优先级 * 4 bits for subpriority //支持16个响应优先级 * @arg NVIC_PriorityGroup_1: 1 bits for pre-emption priority //支持2个抢占优先级 * 3 bits for subpriority //支持8个响应优先级 * @arg NVIC_PriorityGroup_2: 2 bits for pre-emption priority //支持4个抢占优先级 * 2 bits for subpriority //支持4个响应优先级 * @arg NVIC_PriorityGroup_3: 3 bits for pre-emption priority //支持8个抢占优先级 * 1 bits for subpriority //支持2个响应优先级 * @arg NVIC_PriorityGroup_4: 4 bits for pre-emption priority //支持16个抢占优先级 * 0 bits for subpriority //不支持响应优先级 * @note When the NVIC_PriorityGroup_0 is selected, IRQ pre-emption is no more possible. * The pending IRQ priority will be managed only by the subpriority. * @retval None */ void NVIC_PriorityGroupConfig(uint32_t, NVIC_PriorityGroup)
只要开机初始化一次之后中断优先级分组就确定了
NVIC结构体原型
NVIC_InitStructure.NVIC_IRQ = IRQn;//中断线
NVIC_InitStructure.NVIC_IRQPreemptPriority =pri;//抢占优先级
NVIC_InitStructure.NVIC_IRQSubPriority = pri1;//响应优先级
NVIC_InitStructure.NVIC_IRQEnable = ENABLE;//中断使能
NVIC_Init(&NVIC_InitStructure);//中断初始化
关于抢占优先级与响应优先级的差别
抢占优先级相同的中断,高响应优先级不可以打断低响应优先级的中断。
抢占优先级相同的中断,当两个中断同时发生的情况下,哪个响应优先级高,哪个先执行。
4)抢占优先级相同且响应优先级相同的中断,假如同时发生,会按照硬件内部固定的优先级执行,如下图。
5)无论是抢占优先级还是响应优先级,优先级数值越小,就代表优先级越高。
四、中断服务函数
中断服务函数要简单、高效完成,以下的delay函数是为了方便观察中断现象,在实际项目开发过程,是不会这么做的。
常用代码贴文
void exit0_Init(void)//中断初始化函数
{
//使能端口D按键检测端口,端口A的输出
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0;//输出端口设置
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN;//端口的模式
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_100MHz;//端口响应速度
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP ;//设置上下拉店主
GPIO_Init(GPIOD,&GPIO_InitStructure);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);//激活系统时钟
SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOD, EXTI_PinSource0);//将PD0连接到中断EXIT0
//外部中断配置
EXTI_InitStructure.EXTI_Line = EXTI_Line0;//外部中断0
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;//
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;//触发方式
EXTI_InitStructure.EXTI_LineCmd = ENABLE;//是能
EXTI_Init(&EXTI_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;//打开外部中断0的请求
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x0F;//抢占优先级
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0F;//响应优先级
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//终端请求使能
NVIC_Init(&NVIC_InitStructure);
}