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 中断系统了

相关推荐
是翔仔呐16 小时前
第2章 按键输入与消抖!掌握I/O口输入核心,实现单片机人机交互
c语言·单片机·嵌入式硬件·gitee
hoiii18716 小时前
PID控制四轴飞行器系统设计(单片机主控)
单片机·嵌入式硬件
恶魔泡泡糖16 小时前
stm32核心板子使用验证与串口下载
stm32·单片机·嵌入式硬件
wsoz16 小时前
串口仿真协议(RFCOMM)
单片机·嵌入式·蓝牙协议栈·rfcomm
会编程的小孩16 小时前
指针应用 单片机
单片机·嵌入式硬件
HalvmånEver16 小时前
Linux:基于 UDP Socket 的实战项目 --简单双向通信程序
linux·单片机·udp
FreakStudio1 天前
不用装软件!这款MicroPython浏览器 IDE :让你在手机上也能调试树莓派 Pico
python·单片机·嵌入式·电子diy·tinyml
yuan199971 天前
STM32远程升级系统(Bootloader + 上位机)
stm32·单片机·嵌入式硬件
Heartache boy1 天前
野火STM32_HAL库版课程笔记-ADC多通道采集热敏、光敏、反射传感器(轮询)
笔记·stm32·单片机
AI+程序员在路上1 天前
嵌入式软件技术大全
linux·开发语言·arm开发·单片机