文章
博客 网店

 STM32中断优先级详解


一.STM32中断类型:
三个固定优先级的系统异常,Reset,NMI,Hard fault,其优先级分别为-3,-2,-1.不可设置。几乎任何时候都可以抢占比它优先级低的中断。
七个可设置优先级的系统异常,分别是 Memory manage fault、Bus fault、usage fault、SVCall、调试监视器、PendSV、SysTick。
36个外部中断,其中断优先级可设置
注:(1)所有可设置中断的复位后默认优先级都是0
(2)优先级设定值越小优先级越高

二.STM32中断优先级分抢占优先级和响应优先级,抢占优先级高的中断可以在抢占优先级低的中断执行时嵌套发生,也就是说抢占优先级相同的中断不会相互嵌套发生。在抢占优先级相同的多个中断同时发生时响应优先级高的中断先响应,如果响应优先级也相同则按中断序号顺序相应。
STM32的这两种优先级只用寄存器的4个位来配置,那么抢占优先级和响应优先级分别占用这4位中的几个位呢?这个由分组来决定;

分组配置0:4位全部用于响应优先级的配置
分组配置1:高1 位用于抢占,低3位用于响应
分组配置2:高2位用于抢占,低2位用于响应
分组配置3:高3位用于抢占,低1位用于响应
分组配置4:4位全部用于抢占优先级的配置

程序中应首先设置中断优先级的分组策略,可使用库函数NVIC_PriorityGroupConfig(u32 NVIC_PriorityGroup)
函数需要传递分组配置值,分组配置值的符号定义分别如下:
分组配置  抢占优先级取值范围  响应优先级取值范围
NVIC_PriorityGroup_0   0  0~15
NVIC_PriorityGroup_1  0~1  0~7
NVIC_PriorityGroup_2  0~3  0~3
NVIC_PriorityGroup_3   0~7  0~1
NVIC_PriorityGroup_4   0~15  0


以GPIO中断为例,下面是具体配置方法:

1.在程序入口处,对中断优先级分组配置
  
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);   //分组配置


2.GPIO中断初始化

  GPIO_InitTypeDef GPIO_InitStructure;
  EXTI_InitTypeDef EXTI_InitStructure;        
  NVIC_InitTypeDef NVIC_InitStructure;  

  //中断引脚初始化
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;       //输入,上拉打开(根据需要)
  GPIO_Init(GPIOA, &GPIO_InitStructure);                //初始化
  
  //使能GPIO中断功能
  EXTI_ClearITPendingBit(EXTI_Line2);//清除中断标志
  GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource2);//管脚选择
  EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;//事件选择
  EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;//触发模式:下降沿触发
  EXTI_InitStructure.EXTI_Line = EXTI_Line2; //线路选择
  EXTI_InitStructure.EXTI_LineCmd = ENABLE;//中断使能
  EXTI_Init(&EXTI_InitStructure);//初始化
  
  //中断控制器配置
  NVIC_InitStructure.NVIC_IRQChannel = EXTI2_IRQn;       //通道
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;//抢占优先级
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;   //响应优先级
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;      //启动
  NVIC_Init(&NVIC_InitStructure);              //初始化


3.中断处理函数

//中断处理函数
void EXTI2_IRQHandler(void)
{
  //…  … 用户代码

EXTI_ClearITPendingBit(EXTI_Line2);  //清除中断标志  
}


芯艺工作室    蒙ICP备06005492号
Copyright© 2004-2023 ChipArt Studio All Rights Reserved