STM32 开发 - 中断案例(中断概述、STM32 的中断、NVIC 嵌套向量中断控制器、外部中断配置寄存器组、EXTI 外部中断控制器、实例实操)

发布于:2025-06-13 ⋅ 阅读:(13) ⋅ 点赞:(0)

一、中断概述

  1. 中断:在主程序运行过程中,出现了特定事件,使得 CPU 暂停当前正在运行的程序,转而去处理这个事件,等这个事件处理完成之后,CPU 再回到刚才被打断的位置继续处理

  2. 中断源:打断 CPU 执行的特定事件

  3. 断点:被中断源打断的位置

  4. 执行中断处理程序:处理特定事件的过程

  5. 中断嵌套:在执行中断程序的时候,这个时候有可能被另外一个中断源给中断,CPU 转而去执行另外一个中断源的中断处理程序

  6. 中断优先级:优先级高的可以打断优先级低的,优先级低的无法打断优先级高的

  7. 外部中断源与内部中断源:中断源可以是外部的,也可以是内部的


二、STM32 的中断

  1. Cortex-M3 内核支持 256 个中断,其中包含了 16 个内核中断和 240 个外部中断,并且具有 256 级的可编程中断设置

  2. 一般情况下,芯片厂商会对 Cortex-M3 的中断进行裁剪

  3. STM32 有 84 个中断,包括 16 个内核中断和 68 个可屏蔽中断,具有 16 级可编程的中断优先级

  4. STM32F103 系列有 70 个中断,有 10 个内核中断和 60 个可编程的外部中断


三、NVIC 嵌套向量中断控制器

1、概述
  1. NVIC(Nested Vectored Interrupt Controller)嵌套向量中断控制器,是用于管理中断的核心模块

  2. NVIC 可以高效处理多优先级中断,支持低延迟响应

  3. NVIC 管理着包括内核异常,外部中断等所有中断,由 NVIC 决定哪个中断的处理程序交给 CPU 来执行

  4. 每一个外部中断都可以被使能或者禁止,并且可以被设置为挂起状态或者清除状态

  5. 处理器的中断可以是电平形式的,也可以是脉冲形式的,这样 NVIC 就可以处理任何中断源

  6. 16 个 IO 的中断与 PVD(电源电压检测),RTC(实时时钟),USB,以太网检测这 20 个外部中断会通过 EXTI 来控制,然后交给 NVIC,其他中断都是直接交给 NVIC 来处理

2、中断优先级
  • NVIC 为了方便管理中断,可以通过软件给每个中断设置优先级,NVIC 用 4 个位来控制优先级,值小的优先级高,把优先级分为两种:抢占优先级与响应优先级
  1. 优先级值越小,优先级越高

  2. 如果不设置优先级,则默认优先级为 0

  3. 先比较抢占优先级,抢占优先级高的可以打断抢占优先级低的

  4. 若抢占优先级一样,再比较响应优先级,但是响应优先级不会导致中断嵌套

  5. 若抢占优先级一样的同时挂起,则优先处理响应抢占优先级高的

  6. 若挂起的优先级(抢占和响应)都一样,则查找中断向量表,值小的先响应

  • NVIC 对优先级分了 5 组,在程序中先对中断进行分组,而且分组只能分一次,若多次分,只有最后一次生效
分组 抢占优先级 响应优先级
0 0 位取值范围:0 4 位取值范围:0 ~ 15
1 1 位取值范围:0 ~ 1 3 位取值范围:0 ~ 7
2 2 位取值范围:0 ~ 3 2 位取值范围:0 ~ 3
3 3 位取值范围:0 ~ 7 1 位取值范围:0 ~ 1
4 4 位取值范围:0 ~ 15 0 位取值范围:0

四、外部中断配置寄存器组

typedef struct
{
  __IO uint32_t EVCR;
  __IO uint32_t MAPR;
  __IO uint32_t EXTICR[4];
  uint32_t RESERVED0;
  __IO uint32_t MAPR2;  
} AFIO_TypeDef;
  1. 其中,EXTICR[4] 是外部中断配置寄存器组

  2. 它由 4 个 32 位寄存器组成,每个寄存器控制 4 个外部中断线的配置

  3. 外部中断配置寄存器组用于将 GPIO 引脚连接到对应的 EXTI 中断线

寄存器 地址偏移 管理的中断线
EXTICR[0] 0x08 EXTI0 ~ EXTI3
EXTICR[1] 0x0C EXTI4 ~ EXTI7
EXTICR[2] 0x10 EXTI8 ~ EXTI11
EXTICR[3] 0x14 EXTI12 ~ EXTI15
  • 例如,EXTICR[0] 就是控制 EXTI0 ~ EXTI3 这 4 个外部中断线的配置
位域 功能 对应 GPIO 端口
EXTI3[15:11] 选择 EXTI3 的 GPIO 端口(PA3 ~ PI3) 0000: PA3
0001: PB3
0010: PC3
0011: PD3
0100: PE3
0101: PF3
0110: PG3
0111: PH3
1000: PI3
EXTI2[11:8] 选择 EXTI2 的 GPIO 端口(PA2 ~ PI2) 0000: PA2
0001: PB2
0010: PC2
0011: PD2
0100: PE2
0101: PF2
0110: PG2
0111: PH2
1000: PI2
EXTI1[7:4] 选择 EXTI1 的 GPIO 端口(PA1 ~ PI1) 0000: PA1
0001: PB1
0010: PC1
0011: PD1
0100: PE1
0101: PF1
0110: PG1
0111: PH1
1000: PI1
EXTI0[3:0] 选择 EXTI0 的 GPIO 端口(PA0 ~ PI0) 0000: PA0
0001: PB0
0010: PC0
0011: PD0
0100: PE0
0101: PF0
0110: PG0
0111: PH0
1000: PI0

五、EXTI 外部中断控制器

基本介绍
  1. EXTI,全称 External Interrupt/Event Controller,即外部中断控制器

  2. EXTI 是 STM32 中用于管理外部中断和事件的模块,它负责检测 GPIO 引脚、外设或软件触发的中断 / 事件请求,并将其传递给 NVIC 或直接触发事件响应

typedef struct
{
  __IO uint32_t IMR;
  __IO uint32_t EMR;
  __IO uint32_t RTSR;
  __IO uint32_t FTSR;
  __IO uint32_t SWIER;
  __IO uint32_t PR;
} EXTI_TypeDef;
寄存器 地址偏移 功能
IMR 0x00 中断屏蔽寄存器
EMR 0x04 事件屏蔽寄存器
RTSR 0x08 上升沿触发选择寄存器
FTSR 0x0C 下降沿触发选择寄存器
SWIER 0x10 软件中断事件寄存器
PR 0x14 中断挂起寄存器
IMR
  • IMR 全称 Interrupt Mask Register,即中断屏蔽寄存器

  • IMR 控制是否允许外部中断线产生中断请求,即屏蔽或使能

位域 说明
[31:20] 保留,必须始终保持为复位状态(0)
[19:0] 线 x 上的中断屏蔽
0:屏蔽来自线 x 上的中断请求
1:开放来自线 x 上的中断请求
注:位 19 只适用于互联型产品,对于其它产品为保留位
EMR
  • EMR 全称 Event Mask Register,即事件屏蔽寄存器

  • EMR 控制是否允许外部中断线产生事件请求,即屏蔽或使能

位域 说明
[31:20] 保留,必须始终保持为复位状态(0)
[19:0] 线 x 上的事件屏蔽
0:屏蔽来自线 x 上的事件请求
1:开放来自线 x 上的事件请求
注:位 19 只适用于互联型产品,对于其它产品为保留位
RTSR
  • RTSR 全称 Rising Trigger Selection Register,即上升沿触发选择寄存器

  • RTSR 配置外部中断 / 事件的触发条件为信号上升沿,即从低电平跳变到高电平

位域 说明
[31:19] 保留,必须始终保持为复位状态(0)
注:位 19 只适用于互联型产品,对于其它产品为保留位
[18:0] 线 x 上的上升沿触发选择
0:禁止来自线 x 上的上升沿触发
1:开放来自线 x 上的上升沿触发
FTSR
  • FTSR 全称 Falling Trigger Selection Register,即下降沿触发选择寄存器

  • FTSR 配置外部中断 / 事件的触发条件为信号下降沿,即从低电平跳变到高电平

位域 说明
[31:19] 保留,必须始终保持为复位状态(0)
注:位 19 只适用于互联型产品,对于其它产品为保留位
[18:0] 线 x 上的下降沿触发选择
0:禁止来自线 x 上的下降沿触发
1:开放来自线 x 上的下降沿触发
SWIER
  • SWIER 全称 Software Interrupt Event Register,即软件中断事件寄存器

  • SWIER 通过软件写入模拟外部中断 / 事件的触发,即无需实际电平变化

位域 说明
[31:19] 保留,必须始终保持为复位状态(0)
注:位 19 只适用于互联型产品,对于其它产品为保留位
[18:0] 线 x 上的软件中断 / 事件
当该位为 0 时,写 1 将设置 PR 中相应的挂起位,如果在 IMR 和 EMR 中允许产生该中断 / 事件,则此时将产生一个中断 / 事件
通过清除 PR 的对应位,即写 1 到 PR,可以间接清除该位为 0
PR
  • PR 全称 Pending Register,即中断挂起寄存器

  • OR 标志请求是否已触发且未处理(挂起状态)

位域 说明
[31:19] 保留,必须始终保持为复位状态(0)
注:位 19 只适用于互联型产品,对于其它产品为保留位
[18:0] 线 x 上的挂起位
0:没有发生触发请求
1:发生了选择的触发请求
当在外部中断线上发生了选择的边沿事件,该位被置 1,在该位中写入 1 可以清除它,也可以通过改变边沿检测的极性清除

六、实例实操

  • 使用按钮 PE4 作为按键输入,通过外部中断控制 LED 灯 PB5
#include "stm32f10x.h"

int main()
{
	
	// RCC APB2 使能
    RCC->APB2ENR |= RCC_APB2ENR_IOPBEN; // 使能 GPIOB 时钟
    RCC->APB2ENR |= RCC_APB2ENR_IOPEEN; // 使能 GPIOE 时钟
    RCC->APB2ENR |= RCC_APB2ENR_AFIOEN; // 使能 AFIO 时钟(用于外部中断配置)

    // 清除 PB5 配置
    GPIOB->CRL &= ~(GPIO_CRL_MODE5 | GPIO_CRL_CNF5);

    // 清除 PE4 配置
    GPIOE->CRL &= ~(GPIO_CRL_MODE4 | GPIO_CRL_CNF4);

    // 设置 PB5 为推挽输出模式,最大速度为 50MH
    GPIOB->CRL |= GPIO_CRL_MODE5_0 | GPIO_CRL_MODE5_1;

    // 设置 PE4 为输入模式,上拉
    GPIOE->CRL |= GPIO_CRL_CNF4_0;
    GPIOE->ODR |= GPIO_ODR_ODR4;

    // 点亮 PB5
    GPIOB->ODR &= ~GPIO_ODR_ODR5;

    // 清除 EXTI4 配置
    AFIO->EXTICR[1] &= ~AFIO_EXTICR2_EXTI4; // 清除 EXTI4 的连接
    EXTI->IMR &= ~EXTI_IMR_MR4; // 禁用EXTI4中断屏蔽
    EXTI->FTSR &= ~EXTI_FTSR_TR4; // 禁用EXTI4下降沿触发

    // 设置 EXTI4 配置
    AFIO->EXTICR[1] |= AFIO_EXTICR2_EXTI4_PE; // 将 PE4 连接到 EXTI4
    EXTI->IMR |= EXTI_IMR_MR4; // 使能 EXTI4 中断屏蔽
    EXTI->FTSR |= EXTI_FTSR_TR4; // 使能 EXTI4 下降沿触发

    // 设置 EXTI4 中断优先级为15
    NVIC_SetPriority(EXTI4_IRQn, 0x0F);

    // 使能 EXTI4 中断通道
    NVIC_EnableIRQ(EXTI4_IRQn);

    while (1)
        ;
}

void EXTI4_IRQHandler(void)
{
    // 检查中断标志
    if (EXTI->PR & EXTI_PR_PR4)
    {
        EXTI->PR = EXTI_PR_PR4;

        // 软件消抖
        for (volatile uint32_t i = 0; i < 720000; i++)
            ;

        // 翻转 PB5
        GPIOB->ODR ^= GPIO_ODR_ODR5;
    }
}

网站公告

今日签到

点亮在社区的每一天
去签到