stm32入门篇--中断的初步认识及其优先级和分组

摘要:

本文主要是为了记录自己对中断从不懂到皮毛到能够使用的过程,内容通俗易懂,主要为刚接触stm32的群众提供帮助少走弯路,对中断的配置有个大概的认知,文章图片主要来自网上或其它相关博文。

先理解一些关键词:

1.抢占优先级--PreemptionPriority 

2.响应优先级--SubPriority

3.中断分组--NVIC_PriorityGroup_0(第0组)

4.中断通道--IRQChannel

什么是中断:

1.有某个指定的事件发生将产生相关的中断(一个信号),从而并跳转到对应的中断处理程序中(一般自己写)。

2.事件可以触发中断,也可能不触发中断,有可能被更优先的中断屏蔽(优先级问题),

3.通俗点讲事件就是一个触发信号(脉冲),而中断则是一个固定的电平信号,从而开启指定的中断处理程序(就像点灯)

4.NVIC-中断向量控制器 (通过修改里面的参数来配置中断)

 需要引入misc.c固件库文件,内含NVIC的外设驱动 ,代替原来的stm32f10x.nvic.c(旧版本,现在很少见)。外部中断是:stm32f10x_exti.c(如果插入固件库后程序没错但各种报错未定义undefine)的可以参考USART配置博文)

我们回到中断优先级

首先,先理解抢占优先级响应优先级

1--顾名思义,抢占就是当多个中断同时存在(不一定是同时发生)时,抢占优先级别高的先抢得先机(先发生中断),所以它可以打断正在响应的低抢占优先级的中断(因此可以实现中断嵌套)。

2--但是,不能打断同抢占等级的中断,只能乖乖排队。

3--那么,若是抢占等级相同而又同时触发呢?这时候才看响应优先级,哪个优先级高,哪个先响应

4--总结:多个中断发生时,先看抢占优先级高低,抢占等级相同的看触发先后时间,先后顺序一样(同时)的看响应等级。

通俗的讲:     抢占 响应 (数值越小,等级越高)

那么,中断分组又是什么情况:

先上图,大家大概思考一下

stm32入门篇--中断的初步认识及其优先级和分组_第1张图片

(感觉这是解释得最直观的一张图)

中断寄存器中有用于指定优先级的4个bits。这4个bits用于分配preemption抢占优先级sub响应优先级

而分组方式则是规定这个4个bits的使能格式,即分组不同,数值的作用不同,从而实现中断的多样化,充分利用4个bits的空间。

类似于编码器的用法。

选择0组:可以配置0-15等级的响应优先级

选择2组:可以配置0-3等级的抢占优先级  和  0-3等级的响应优先级

.........

所以,分组与优先级无关,定义了优先级的配置格式,中断优先级取决于抢占优先级和响应优先级的参数

深入研究中断寄存器的可参考:【1】STM32 NVIC

(代码详解)

 /*选择第0组中断方式配置*/
void TIM2_NVIC_Configuration(void)
{
    NVIC_InitTypeDef NVIC_InitStructure; 			//定义结构体
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);  //  选择使用第0组中断向量格式  初始化分组方式													
    NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;	//中断通道--定时器TIM2通道  
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;  //抢占优先级--无抢占优先级配置
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;	//响应优先级 可配置0-15
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);//初始化参数	

	NVIC_InitStructure.NVIC_IRQChannel = EXTI1_IRQn; //使能外部中断所在的通道 当时的IO口是PB1
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //抢占优先级--无抢占优先级配
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2; //响应优先级 可配置0-15
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能外部中断通道 
	NVIC_Init(&NVIC_InitStructure); //初始化参数
}

/*选择第2组中断方式配置*/
void TIM2_NVIC_Configuration(void)
{
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);  //选择第1组中断向量格式 初始化分组方式
	NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;	//中断通道--定时器TIM2通道  
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;  //抢占优先级--可配置0-3等级
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;	//响应优先级 可配置0-3等级
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);//初始化参数	

	NVIC_InitStructure.NVIC_IRQChannel = EXTI1_IRQn; //使能外部中断所在的通道 当时的IO口是PB1
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //抢占优先级 可配置0-3等级 
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; //响应优先级 可配置0-3等级
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能外部中断通道 
	NVIC_Init(&NVIC_InitStructure); 
}

至于中断通道--IRQChannel--则需要自己在固件库搜索,以下是常用的一些中断通道

GPIO引脚 中断标志位 中断处理函数
PA0~PG0 EXTI0 EXTI0_IRQHandler
PA1~PG1 EXTI1 EXTI1_IRQHandler
PA2~PG2 EXTI2 EXTI2_IRQHandler
PA3~PG3 EXTI3 EXTI3_IRQHandler
PA4~PG4 EXTI4 EXTI4_IRQHandler
PA5~PG5 EXTI5 EXTI9_5_IRQHandler
PA6~PG6 EXTI6  
PA7~PG7 EXTI7  
PA8~PG8 EXTI8  
PA9~PG9 EXTI9  
PA10~PG10 EXTI10 EXTI15_10_IRQHandler
PA11~PG11 EXTI11  
PA12~PG12 EXTI12  
PA13~PG13 EXTI13  
PA14~PG14 EXTI14  
PA15~PG15 EXTI15  

 参考:【2】STM32 GPIO外部中断总结

stm32入门篇--中断的初步认识及其优先级和分组_第2张图片

参考:【3】STM32的NVIC和中断的总结

 

到此为止应该对stm32中断原理有个初步的了解并能简单地设置一些简单地中断了。

提醒: 添加中断(外部中断)处理的库文件,设置中断后同时要编写 中断的Handler处理函数,类似上一篇博文的USART2的Handler函数,实际也是一个串口中断 。

若有错误,请指正~

内容粗糙,望能助人。

参考:

【1】STM32 NVIC

【2】STM32 GPIO外部中断总结

【3】STM32的NVIC和中断的总结

 

 

你可能感兴趣的:(stm32)