Skip to content

https://blog.csdn.net/u010249597/article/details/135047842

在 STM32 微控制器中,中断的管理和优先级控制是由嵌套向量中断控制器(NVIC, Nested Vectored Interrupt Controller)负责完成的。以下是关于中断判断、执行顺序以及嵌套的详细解释:


1. STM32 是如何判断中断的?

STM32 的中断信号由外设模块或外部事件触发。NVIC 的主要职责是监视所有中断请求信号,并根据优先级和当前系统状态决定是否响应中断。

中断判断的主要流程:

  1. 中断请求信号触发

    • STM32 的外设或外部引脚(如定时器、串口、GPIO 中断)会触发中断请求信号。
    • 触发信号会设置对应的中断挂起标志位。
  2. NVIC 检查中断挂起标志

    • NVIC 检查当前有哪些中断挂起标志(Pending 位)被置位。
    • 同时,NVIC 会判断哪个中断是最高优先级的。
  3. 中断屏蔽判断

    • NVIC 检查全局中断使能状态(Cortex-M 内核的 PRIMASK 寄存器)。
    • 如果中断已被屏蔽(全局或本地屏蔽),则不会响应中断。
    • 如果中断未屏蔽,NVIC 将响应该中断。
  4. 响应中断

    • NVIC 将启动中断服务程序(ISR, Interrupt Service Routine),并在启动前保存当前的 CPU 状态。
    • CPU 跳转到对应的中断向量表地址,并执行该中断的 ISR。

2. STM32 是如何确定执行哪个中断的?

NVIC 通过优先级机制来决定执行哪个中断。STM32 中的中断优先级分为 抢占优先级子优先级

中断优先级的分类:

  • 抢占优先级(Preemption Priority):

    • 决定了当前中断是否可以被更高优先级的中断打断。
    • 数值越小,优先级越高。
  • 子优先级(Subpriority):

    • 在抢占优先级相同时,用于决定多个中断的响应顺序。
    • 数值越小,优先级越高。

NVIC 的优先级配置:

  • NVIC 的优先级划分由 STM32 的 AIRCR 寄存器中的 PRIGROUP 字段决定。
  • PRIGROUP 决定了抢占优先级和子优先级的比特位分配。
    • 例如,PRIGROUP = 3 表示抢占优先级占 4 位,子优先级占 0 位。
    • 具体优先级分配可以参考 STM32 的参考手册。

决定执行哪个中断的流程:

  1. NVIC 检查所有挂起的中断。
  2. 根据抢占优先级(Preemption Priority)选择最高优先级的中断。
  3. 如果多个中断的抢占优先级相同,则根据子优先级(Subpriority)选择优先级最高的中断。

3. 什么是中断嵌套?

中断嵌套是指在一个中断服务程序(ISR)执行的过程中,另一个优先级更高的中断被触发并打断当前中断的执行。

中断嵌套的条件:

  1. 新中断的抢占优先级高于当前正在执行的中断。
  2. 新中断未被屏蔽(全局或本地屏蔽)。
  3. 当前中断允许被打断(即未设置禁止嵌套的标志)。

中断嵌套的执行流程:

  1. 当前中断正在执行时,NVIC 发现有更高级别的中断请求。
  2. NVIC 暂停当前中断,将 CPU 状态保存到堆栈中。
  3. CPU 跳转到更高级别中断的中断服务程序(ISR)。
  4. 更高级别的中断服务程序执行完成后,恢复被打断的中断并继续执行。

中断嵌套的优点和注意事项:

  • 优点:提高系统的响应速度,允许高优先级的中断优先处理紧急任务。
  • 注意事项
    • 嵌套过多会增加堆栈使用量,可能导致堆栈溢出。
    • 在中断服务程序中避免长时间操作,以免影响其他中断的响应。

4. 如何确定中断执行顺序?

中断执行顺序由 NVIC 的优先级机制决定。以下是总结步骤:

  1. 优先级比较

    • NVIC 首先比较挂起中断的抢占优先级,数值越小,优先级越高。
    • 如果抢占优先级相同,则比较子优先级,数值越小,优先级越高。
  2. 顺序示例

    • 假设有三个中断:
      • 中断 A:抢占优先级 = 0,子优先级 = 1
      • 中断 B:抢占优先级 = 1,子优先级 = 0
      • 中断 C:抢占优先级 = 0,子优先级 = 0
    • 执行顺序为:中断 C → 中断 A → 中断 B(根据抢占优先级和子优先级)。
  3. 嵌套执行

    • 如果中断 C 正在执行时,中断 A 或中断 B 被触发,则中断 C 不会被打断。
    • 如果中断 B 正在执行时,中断 C 被触发,则中断 B 会被打断,中断 C 先执行。

5. 配置中断优先级的代码示例

以下是配置 STM32 中断优先级的示例代码:

c
#include "stm32f10x.h"

void NVIC_Configuration(void) {
    NVIC_InitTypeDef NVIC_InitStructure;

    // 配置中断优先级组(抢占优先级 2 位,子优先级 2 位)
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);

    // 配置中断1(抢占优先级 = 1,子优先级 = 0)
    NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;  // 定时器2中断
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;  // 使能中断
    NVIC_Init(&NVIC_InitStructure);

    // 配置中断2(抢占优先级 = 0,子优先级 = 1)
    NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;  // USART1中断
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
    NVIC_Init(&NVIC_InitStructure);
}

总结

  1. 如何判断中断

    • NVIC 检查挂起标志,判断是否有中断请求。
    • 判断中断是否被屏蔽。
  2. 如何确定执行哪个中断

    • 根据抢占优先级和子优先级选择最高优先级的中断。
  3. 中断嵌套

    • 发生在一个中断服务程序正在执行时,更高优先级的中断打断当前中断。
  4. 执行顺序

    • 优先级由抢占优先级和子优先级共同决定。