STM32中断的种类以及使用注意事项

一、STM32 中断的种类

STM32 基于 Cortex-M 内核(如 M3/M4),其完整的中断系统包括:

  1. 内核异常(Exception)
  • 属于"系统级中断",由 CPU 内部触发。
  • 包括:
    • Reset(复位)
    • NMI(不可屏蔽中断)
    • HardFault(硬件错误)
    • MemManage、BusFault、UsageFault(内存/总线/用法错误)
    • SVCall、PendSV、SysTick(系统调用、可挂起服务、系统滴答定时器)

这些异常优先级固定,不能被普通中断打断(除 NMI 和 HardFault 等高优先级异常)。

  1. 外设中断(Interrupt)
  • 由片上外设(如 GPIO、USART、TIM、ADC、DMA、CAN 等)触发。
  • STM32F103 系列典型有 60 个可屏蔽中断通道(加上 10 个内核异常,共 70 个中断源)。
  • 每个外设可配置为产生中断(需使能 + 配置 NVIC)。

⚠️ 注意:STM32 的中断总数因型号而异(如 F1 是 70 个,F4 可达 90+ 个)。

二、常见中断应用示例

  1. 按键中断(GPIO 外部中断)
    原理:
    • 按键连接到 GPIO 引脚(如 PA0)。
    • 配置该引脚为 输入模式 + 上拉/下拉。
    • 通过 AFIO 将 GPIO 映射到 EXTI(外部中断线)。
    • 配置 EXTI 触发方式(上升沿、下降沿、双边沿)。
    • 在 NVIC 中使能对应 EXTI 中断(如 EXTI0_IRQn)。
    • 编写中断服务函数(ISR):void EXTI0_IRQHandler(void)

示例流程(HAL 库):

复制代码
// 1. 使能时钟
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_AFIO_CLK_ENABLE();

// 2. 配置 GPIO
GPIO_InitTypeDef gpio = {0};
gpio.Pin = GPIO_PIN_0;
gpio.Mode = GPIO_MODE_IT_FALLING; // 下降沿触发(按键按下)
gpio.Pull = GPIO_PULLUP;
HAL_GPIO_Init(GPIOA, &gpio);

// 3. 配置 NVIC
HAL_NVIC_SetPriority(EXTI0_IRQn, 2, 0);
HAL_NVIC_EnableIRQ(EXTI0_IRQn);

// 4. ISR
void EXTI0_IRQHandler(void) {
    HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_0); // 调用 HAL 的通用处理
}

// 5. 回调函数(用户实现)
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) {
    if (GPIO_Pin == GPIO_PIN_0) {
        // 按键处理逻辑(如翻转 LED)
        HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_13);
    }
}

✅ 注意:必须在 ISR 中 清除中断标志位(HAL 自动处理;寄存器需手动 EXTI->PR = 1DR 清除标志,并处理数据。

示例(HAL 库):

复制代码
// 使能接收中断
__HAL_UART_ENABLE_IT(&huart1, UART_IT_RXNE);

// 或使用 HAL 接收(带回调)
HAL_UART_Receive_IT(&huart1, &rx_byte, 1);

// HAL 自动调用回调
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) {
    if (huart->Instance == USART1) {
        // 处理 rx_byte
        process_data(rx_byte);
        // 重新开启单字节接收
        HAL_UART_Receive_IT(&huart1, &rx_byte, 1);
    }
}

🔔 关键点:避免在 ISR 中做耗时操作(如 printf、复杂计算),应快速处理并退出。

三、中断服务程序(ISR)注意事项

  1. 执行时间要短
  • ISR 应 尽快完成并返回,避免阻塞其他高优先级中断。
  • 不要在 ISR 中使用 delay()、printf()(除非使用 DMA 或环形缓冲)。
  1. 变量访问需加 volatile
  • 若 ISR 与主程序共享变量,必须声明为 volatile:
    volatile uint8_t flag = 0;
  1. 临界区保护
  • 主程序访问 ISR 共享资源时,应临时关闭中断:

    __disable_irq();

    // 读取/修改共享变量

    __enable_irq();

    或使用 __set_PRIMASK() 更精细控制。

  1. 中断标志必须清除
  • 否则会 反复进入 ISR(死循环)。
  • HAL 库通常自动清除;寄存器操作需手动清标志(如 USART_SR 读 DR,EXTI_PR 写 1 清零)。
  1. 优先级配置合理
  • 使用 抢占优先级(Preemption Priority) 和 子优先级(Subpriority)。
  • 高实时性任务(如电机控制)应设高抢占优先级。
  • 避免所有中断设为同一优先级(可能导致嵌套失效)。

📌 优先级分组建议:

  • 实时系统:用 NVIC_PriorityGroup_4(4 位全给抢占,无子优先级)
  • 一般应用:用 NVIC_PriorityGroup_2(2 位抢占 + 2 位响应)

四、调试技巧

  • 使用 Event Recorder 或 SEGGER SystemView 查看中断触发时序。
  • 在 ISR 开头/结尾打 GPIO 电平,用示波器测执行时间。
  • 避免在 ISR 中调用非重入函数(如 malloc、某些库函数)。

五、总结

1、中断种类 内核异常(10+) + 外设中断(60+)

2、按键中断 GPIO → EXTI → NVIC → ISR(注意消抖和清标志)

3、串口中断 USART_RXNE → ISR 读 DR → 快速处理

4、ISR 原则 短、快、清标志、volatile、关中断保护

5、优先级 抢占 > 响应,合理分组避免嵌套问题

掌握这些要点,就能安全高效地使用 STM32 中断系统了

相关推荐
_Ningye2 小时前
STM32 — 1-2 — STM32简介
stm32·单片机·嵌入式硬件
m0_555762902 小时前
高级定时器
单片机·嵌入式硬件
DLGXY2 小时前
STM32(十八)——IIC通信、MPU6050、IIC外设
stm32·单片机·嵌入式硬件
Struggle to dream3 小时前
STM32关于GPIO的模式配置详解
stm32·单片机·嵌入式硬件
上海合宙LuatOS3 小时前
LuatOS核心库API——【fatfs】支持FAT32文件系统
java·前端·网络·数据库·单片机·嵌入式硬件·物联网
xiaobobo33303 小时前
评判一下stm32的标准库函数写的怎样?
stm32·单片机·嵌入式硬件
码农三叔3 小时前
(11-4-01)完整人形机器人的设计与实现案例:机器人的站立与行走
人工智能·嵌入式硬件·机器人·人机交互·人形机器人
小武编程4 小时前
基于STM32G030系列MCU之ADC采集转电压值
stm32·单片机·嵌入式硬件
逐步前行4 小时前
STM32_烧录调试
stm32·嵌入式硬件·mongodb