【STM32】基础知识 第十三课 中断
- 概述
- 中断是什么
- 中断的作用 & 意义
- STM32 中断体系
- NVIC
- 中断向量表
- STM32 中断优先级基本概念
- STM32 外部中断器 (EXTI)
- EXTI 简介
- EXTI 配置
- AFIO
- AFIO 与中断
- 案例
概述
今天小白我将带领大家详细介绍 STM32 单片机中的中断处理机制, 包括中断的基本概念, 配置和使用方法. 中断在嵌入式系统中扮演着重要角色, 使系统能够快速响应外部事件, 提高系统的实时性和效率.
中断是什么
中断 (Interrupt) 是单片机和其他嵌入式系统中的一种重要机制, 用于在发生特定事件时通知处理器. 中断使得可以由外部事件 (如按键按下, 定时器溢出等) 触发, 也可以由软件生成.
中断的作用 & 意义
- 提高实时性: 中断允许单片机在特定事件发生时立即响应, 而无需持续轮询状态. 这大大提高了系统的实时性, 确保及时处理外部事件和设备请求
- 降低资源占用, 通过使用中断, 单片机可以在需要时才处理指定任务, 而不是持续检查设备和输入状态, 这降低了系统资源的占用. 使单片机能够更有效地执行其他任务
- 简化程序结构: 中断使得开发者能够将事件处理逻辑分离, 编写简单, 清晰的代码. 这有助于提高程序的可维护性和可读性
- 支持多任务处理: 中断机制使得单片机能够在同一事件处理多个任务. 通过合理分配中断优先级, 可以确保紧急任务优先执行, 提高系统的整体效率
- 动态事件响应:中断可以根据事件发生的条件动态地执行不同的处理函数. 这使得系统能够根据实际需求灵活地响应时间, 提高系统的适应性和鲁棒性
- 省电优势: 当没有外部事件发生时, 单片机可以进入低功耗模式, 降低功耗. 当时间发生时, 中断机制能够立即唤醒单片机进行处理. 这在许多低功耗应用场景中具有显著优势
- 平衡性能和功耗:通过合理配置中断, 开发者可以在系统性能和功耗之间实现平衡. 这对于需要在有限资源下实现高性能运算的嵌入式系统尤为重要
STM32 中断体系
STM32 单片机基于 ARM Cortex-M 内核, 具有高度可配置的中断控制器 (NVIC, Nested Vectored Interrupt Controller). NVIC 支持多达 240 个中断源. 包括外部中断 (如 GPIO 中断, 定时器中断, 通信接口中断等.
STM32 信号 | 内核中断 | 外部中断 | 中断优先级 |
---|---|---|---|
STM32F103xx | 10 | 60 | 16 |
STM32F407xx | 10 | 82 | 16 |
STM32F429xx | 10 | 91 | 16 |
STM32F750xx | 10 | 98 | 16 |
STM32F767xx | 10 | 110 | 16 |
STM32H743xx | 10 | 150 | 16 |
STM32H750xx | 10 | 150 | 16 |
NVIC
NVIC (Nested Vectored Interrupt Controller), 嵌套向量中断控制器. NVIC 是 ARM Cortex-M 系列单片机中的一种高级中断控制器.
NVIC 的一些基本概念:
- 中断向量: 在 NVIC 中, 每个中断源都与一个中断向量相关联. 中断向量是一个指向中断处理函数的指针, 当对应的中断事件发生时, 处理器会根据中断向量跳转到相应的重案处理函数执行
- 中断优先级: NVIC 支持为每个中断源设置优先级, 优先级搞的中断将优先于优先级低的中断执行. 我们可以根据任务的紧急程度来安排中断的执行顺序, 提高系统的实时性和效率
- 嵌套中断处理器: NVIC 支持嵌套中断处理器, 即在处理一个中断时, 如果发生了优先级更高的中断, 处理器会暂停当前中断处理, 先去处理优先级更高的中断. 这有助于确保紧急任务能够及时处理
- 电源管理, NVIC 具有一定的电源管理功能. 可以在没有中断发生时使处理器进入低功耗模式, 节省能源. 当中断事件发生时, NVIC 将唤醒处理器进行处理
中断向量表
中断向量表 (Interrupt Vector Table) 是一种数据结构, 用于存储中断处理函数的地址信息. 在单片机中, 每个中断源都与中断向量表中的一个条目相关联. 当中断事件发生时, 单片机控制器会根据中断向量表中的信息转跳到相应的中断处理函数执行.
中断向量表的相关概念:
- 向量条目: 中断向量表中的每个条目都包含一个指向中断处理函数的指针. 不同的中断源对应不同的条目, 其顺序通常由硬件决定
- 表的起始地址: 中断向量表通常位于固定的内存地址. 例如在 ARM Cortex-M 系列微控制器中, 中断向量表的启示地址为 0x0000 0000. 我们需要根据具体的单片机和编译器设置中断向量表的位置
- 异常处理和中断处理: 在 ARM Cortex-M 单片机中, 中断向量表包括异常向量和中断向量. 异常向量处理诸如复位, 非法指令等异常情况, 通常位于中断向量表的前部. 中断向量则处理来自外部设备或内部模块的中断事件
- 中断向量表的初始化: 在系统启动时, 单片机会初始化中断向量表, 将中断处理函数的地址加载到对应的向量条目中. 这通常由启动代码 (Bootloader) 或编译器生成的初始化代码完成
- 动态修改: 在某些情况下, 我们可能需要在运行时动态修改中断向量表. 例如, 在使用实时操作系统 (RTOS) 时, 开发者可能需要修改中断处理函数以实现任务切换. 这需要特殊的编程技巧和对单片机内存结构的深入了解
NVIC 相关寄存器介绍:
NVIC 相关寄存器 | 位数 | 寄存器个数 | 备注 |
---|---|---|---|
中断使能寄存器 (ISER) | 32 | 8 | 每个位控制一个中断 |
中断失能寄存器 (ICER) | 32 | 8 | 每个位控制一个中断 |
应用程序中断及复位控制器 (AIRCR) | 32 | 1 | 位[10:8] 控制优先级分组 |
中断优先级寄存器 (IPR) | 8 | 240 | 8 个位对应一个中断, 而 STM32 只使用高 4 位 |
STM32 中断优先级基本概念
- 抢占优先级 (pre): 高抢占优先级可以打断正在执行的低抢占优先级中断
- 响应优先级 (sub): 当抢占优先级相同时, 响应优先级高的先执行, 但是不能互相打断
- 抢占和响应都相同的情况下, 自然优先级越高的, 先执行
- 自然优先级: 中断向量表的优先级
- 数值越小, 表示优先级越高
例子:
编号 | 自然优先级 | 对应外设 | 抢占 | 响应 |
---|---|---|---|---|
3 | 10 | RTC | 2 | 1 |
6 | 13 | EXIT0 | 3 | 0 |
7 | 14 | EXIT | 2 | 0 |
-1 | 6 | Systick | 3 | 0 |
STM32 外部中断器 (EXTI)
在单片机中, 外部中断 (EXTI, External Interrupt/Event Controller) 是一种重要的硬件属性. EXTI 使单片机能够对外部事件做出快速响应.
EXTI 简介
在 STM32 单片机中, EXTI 是一种特殊的中断来源, 可以通过外部引脚触发, 或者通过软件生成. 每个 EXTI 线路都可以独立配置为上升沿触发, 下降沿触发或者双边沿触发. 此外, EXTI 还支持事件生成, 既不产生中断, 但能触发 DMA 请求.
中断和事件:
- 中断: 要进入 NVIC, 有相应的中断服务函数, 需要 CPU 处理
- 事件: 不进入 NVIC, 仅用于内部硬件自动控制的, 如: TIM, DMA
EXTI 配置
配置 STM32 的 EXTI 通常需要以下步骤:
- 配置 PGIO 引脚: 首先, 我们需要将 GPIO 引脚配置为输入, 并选择合适的上拉 / 下拉设置
- 配置 EXTI 线路: 然后, 我们需要选择 GPIO 引脚对应的 EXTI 线路, 并设置触发条件 (上升沿, 下降沿或双边沿)
- 配置 NVIC: 为了处理 EXTI 中断, 我们需要, 我们需要在 NVIC 中启动对应的中断, 并设置优先级
- 编写中断处理函数: 最后, 我们需要编写对应的中断处理函数, 并在该函数中清除中断标志
EXTI 的 HAL 库设置步骤:
- 使能 GPIO 时钟, 使用 __HAL_RCC_GPIOx_CLK_ENABLE
- GPIO/AFIO(SYSCFG)/EXTI, 使用 HAL_GPIO_Init, 一步到位
- 设置中断分组, 使用 HAL_NVIC_SetPriorityGrouping, 此函数仅需设置一次
- 设置中断优先级: HAL_NVIC_SetPriority
- 使能中断, 使用 HAL_NVIC_EnableRQ
- 设计中断服务函数, 编写 EXTIx_IRQHandler, 中断服务函数 清空中断标识
AFIO
在 STM32 单片机中, AFIO (Alternate Function I/O) 模块是一个重要的硬件模块, 负责管理 STM32 的多功能引脚.
AFIO 与中断
在 STM32 单片机中, AFIO (Alternate Function I/O) 模块不仅负责管理多功能引脚, 也负责配置外部中断线 EXTI (External Interrupt/Event Controller) 的源. 举个例子, 每个外部中断线可以由多个 GPIO 引脚之一触发, 选择哪个 GPIO 引脚取决于 AFIO 模块的配置.
STM32 的外部中断源与 GPIO 引脚的关联是固定的. 例如 EXTI0 可以由任何一组 Px0 引脚触发. AFIO 模块的 EXTI 配置寄存器 (AAFIO_EXTICR)决定了具体由哪一个 GPIO 引脚触发对应的中断.
案例
#include "./stm32f1xx_it.h"
#include "./SYSTEM/sys/sys.h"
#include "./SYSTEM/usart/usart.h"
#include "./SYSTEM/delay/delay.h"
#include "./BSP/LED/led.h"
#include "./BSP/BEEP/beep.h"
#include "./BSP/EXTI/exti.h"
int main(void)
{
HAL_Init(); /* 初始化HAL库 */
sys_stm32_clock_init(RCC_PLL_MUL9); /* 设置时钟, 72Mhz */
delay_init(72); /* 延时初始化 */
usart_init(115200); /* 串口初始化为115200 */
led_init(); /* 初始化LED */
beep_init(); /* 初始化蜂鸣器 */
extix_init(); /* 初始化外部中断输入 */
LED0(0); /* 先点亮红灯 */
while (1)
{
printf("OK\r\n");
delay_ms(1000);
}
}