STM32的中断优先级详解

中断优先级设置步骤:

  • 系统运行后先设置中断优先级分组。在主函数调用函数:

void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup);

  • 整个系统执行过程中,只设置一次中断分组。

  • 针对每个中断,设置对应的抢占优先级和响应优先级:

void NVIC_Init(NVIC_InitTypeDef* NVIC_InitStruct);//配置过程

NVIC_InitTypeDef   NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;//串口1中断,此处可改为任何有中断功能的模块定时器,外部中断等,后面有例子参考
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1 ;// 抢占优先级为1
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;// 子优先级位2
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//IRQ通道使能
NVIC_Init(&NVIC_InitStructure); //根据上面指定的参数初始化NVIC寄存器

  • 如果需要挂起/解挂,查看中断当前激活状态,分别调用相关函数即可。

  • 优先级分组只是给抢占优先级与响应优先级在中断优先级寄存器中高四位分配各个优先级数字所占的位数,在程序中只能设定一次。

  • 每写一个关于中断优先级的程序必须包含下列两个函数: (1)void NVIC_PriorityGroup();//写在主程序中;

  • (2)NVIC_Init(); //写在初始化配置中


默认情况下,如何不设置中断优先级分组,则中断优先级分组默认为0,即0位抢占优先级,4位响应优先级,则无任何抢占优先级,所以无论中断的优先级设多少,都没有抢占中断的功能,所以,如果想要一个中断打断另一个中断,必须设置中断优先级分组为1,2,3,4.

如设置优先级分组为2

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);

Cortex-M3允许具有较少中断源时使用较少的寄存器位指定中断源的优先级,因此STM32把指定中断优先级的寄存器位减少到4位,这4个寄存器位的分组方式如下:

第0组:所有4位用于指定响应优先级

第1组:最高1位用于指定抢占式优先级,最低3位用于指定响应优先级

第2组:最高2位用于指定抢占式优先级,最低2位用于指定响应优先级

第3组:最高3位用于指定抢占式优先级,最低1位用于指定响应优先级

第4组:所有4位用于指定抢占式优先级

可以通过调用STM32的固件库中的函数NVIC_PriorityGroupConfig()选择使用哪种优先级分组方式,这个函数的参数有下列5种:

NVIC_PriorityGroup_0=> 选择第0组

NVIC_PriorityGroup_1=> 选择第1组

NVIC_PriorityGroup_2=> 选择第2组

NVIC_PriorityGroup_3=> 选择第3组

NVIC_PriorityGroup_4=> 选择第4组  

如 选择使用优先级分组第1组 NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);//高一位就有0,1,四个抢占优先;低三位就是0,1,2,3,4,5,6,7,八个响应优先级

具体例子如下

{

假设NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1)

// 使能EXTI0中断

NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQChannel;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; // 指定抢占式优先级别1

NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; // 指定响应优先级别0
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

NVIC_Init(&NVIC_InitStructure);

// 使能EXTI9_5中断
NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQChannel;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; // 指定抢占式优先级别0
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; // 指定响应优先级别1
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

NVIC_Init(&NVIC_InitStructure);

//TIM3中断

      NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;  //TIM3中断
      NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;  //先占优先级0级
       NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;  //从优先级3级

     NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能

   NVIC_Init(&NVIC_InitStructure);  //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器

TIM_Cmd(TIM3, ENABLE);  //使能TIMx外设

}

在上例子中,优先抢占优先级,其数字越低,优先级越高。相同下比较响应优先级,其数字越低,优先级越高。

要注意的几点是:

1)如果指定的抢占式优先级别或响应优先级别超出了选定的优先级分组所限定的范围,将可能得到意想不到的结果;

2)抢占式优先级别相同的中断源之间没有嵌套关系;

3)如果某个中断源被指定为某个抢占式优先级别,又没有其它中断源处于同一个抢占式优先级别,则可以为这个中断源指定任意有效的响应优先级别。



猜你喜欢

转载自blog.csdn.net/qq_31530791/article/details/80651069