NVIC判定规则和工作原理

NVIC

一、优先级分组

STM32的优先级通过 优先级分组(Priority Grouping) 来划分。分组决定了 抢占优先级 和 子优先级 各占多少比特位。分组通过 NVIC_PriorityGroupConfig() 函数配置,例如:

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); // 常用分组

STM32支持的优先级分组如下:

优先级分组

抢占优先级

响应优先级

bit[7:4] 分配情况

备注

NVIC_PriorityGroup_0

取值:0

取值:0~15

0:4

0bit抢占优先级、4bit响应优先级

NVIC_PriorityGroup_1

取值:0~1

取值:0~7

1:3

1bit抢占优先级、3bit响应优先级

NVIC_PriorityGroup_2

取值:0~3

取值:0~3

2:2

2bit抢占优先级、2bit响应优先级

NVIC_PriorityGroup_3

取值:0~7

取值:0~1

3:1

3bit抢占优先级、1bit响应优先级

NVIC_PriorityGroup_4

取值:0~15

取值:0

4:

4bit抢占优先级、0bit响应优先级

假设选择 分组2NVIC_PriorityGroup_2):

  • 抢占优先级 占2位(取值范围:0-3)

  • 子优先级 占2位(取值范围:0-3)

二、优先级判定规则

1. 抢占优先级(Preemption Priority)

  • 决定中断是否可以 打断当前正在执行的中断

  • 数值越小,优先级越高(0为最高)。

  • 如果两个中断的抢占优先级不同,抢占优先级高的中断会立即打断低抢占优先级的中断。

2. 子优先级(Sub Priority)

  • 仅在 抢占优先级相同的中断 之间比较。

  • 数值越小,优先级越高(0为最高)。

  • 如果两个中断的抢占优先级相同,子优先级高的会先执行,但不会打断对方。

3. 自然优先级

  • 如果抢占优先级和子优先级都相同,则根据 中断向量表中的位置(自然优先级) 决定顺序,位置靠前的中断优先执行。

三、示例分析

假设配置为 分组2(抢占优先级和子优先级各占2位):

// 中断A配置
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; // 抢占优先级0(最高)
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;        // 子优先级0(最高)

// 中断B配置
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; // 抢占优先级1
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;        // 子优先级0
  • 场景1:中断A和中断B同时发生。

    • 中断A的抢占优先级更高(0 < 1),因此中断A会立即打断中断B(如果中断B正在执行)。

  • 场景2:中断A和另一个抢占优先级为0、子优先级为1的中断C同时发生。

    • 抢占优先级相同(均为0),比较子优先级。

    • 中断A的子优先级更高(0 < 1),因此中断A先执行。

四、关键注意事项

  1. 数值越小,优先级越高:无论是抢占优先级还是子优先级,数值0代表最高优先级。

  2. 分组配置全局生效:优先级分组需要在初始化时统一配置,且所有中断必须基于同一分组。

  3. 中断嵌套:抢占优先级高的中断可以嵌套在低抢占优先级的中断中,但子优先级不能嵌套。

  4. 优先级范围:根据分组不同,优先级数值不能超过其位数允许的范围(例如分组2中,优先级范围为0-3)。

五、配置步骤

     1. 设置优先级分组(通常在程序初始化时调用一次):

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);

     2. 配置具体中断的抢占优先级和子优先级:

NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;      // 中断通道
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; // 抢占优先级
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;        // 子优先级
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;           // 使能中断
NVIC_Init(&NVIC_InitStructure);

六、常见问题

  1. 为什么中断没有按预期触发?

    • 检查优先级分组是否一致。

    • 确认抢占优先级和子优先级是否超出范围。

  2. 如何实现完全嵌套中断?

    • 使用不同的抢占优先级,高抢占优先级的中断可以打断低抢占优先级的中断。

  3. 子优先级的作用是什么?

    • 仅在抢占优先级相同的情况下,决定中断的执行顺序。

    你可能感兴趣的:(嵌入式开发,单片机,嵌入式硬件)