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

相关推荐
悠哉悠哉愿意7 天前
【单片机学习笔记】串口、超声波、NE555的同时使用
笔记·单片机·学习
Lester_11017 天前
STM32霍尔传感器输入口设置为复用功能输入口时,还能用GPIO函数直接读取IO的状态吗
stm32·单片机·嵌入式硬件·电机控制
LCG元7 天前
低功耗显示方案:STM32L0驱动OLED,动态波形绘制与优化
stm32·嵌入式硬件·信息可视化
三佛科技-187366133977 天前
120W小体积碳化硅电源方案(LP8841SC极简方案12V10A/24V5A输出)
单片机·嵌入式硬件
z20348315207 天前
STM32F103系列单片机定时器介绍(二)
stm32·单片机·嵌入式硬件
古译汉书7 天前
【IoT死磕系列】Day 7:只传8字节怎么控机械臂?学习工业控制 CANopen 的“对象字典”(附企业级源码)
数据结构·stm32·物联网·http
Alaso_shuang7 天前
STM32 核心输入、输出模式
stm32·单片机·嵌入式硬件
脚后跟7 天前
AI助力嵌入式物联网项目全栈开发
嵌入式硬件·物联网·ai编程
2501_918126917 天前
stm32死锁是怎么实现的
stm32·单片机·嵌入式硬件·学习·个人开发
z20348315207 天前
STM32F103系列单片机定时器介绍(一)
stm32·单片机