中断(NVIC)

中断(NVIC)

1. 基本概念

  • NVIC = Nested Vectored Interrupt Controller,嵌套向量中断控制器,Cortex-M4 内核外设。

  • F407 有 10 个系统异常 (复位、NMI、HardFault、SysTick 等)+ 82 个外部中断(USART、SPI、EXTI...)。

  • 中断号在 IRQn_Type 枚举里:负数 = 系统异常,0 以上 = 外部中断。

2. 优先级

F407 只用 4 位优先级(0~15),数字越小越优先。

作用 能否打断
抢占优先级 高的打断低的(中断嵌套) 能
子优先级 抢占相同时决定谁先响应 不能

优先级分组(4 位怎么切)

由 HAL_NVIC_SetPriorityGrouping() 设置,CubeMX 默认 Group_4(4 位全给抢占)。

分组 抢占位 子优先级位 抢占范围 子优先级范围
Group_0 0 4 无 0~15
Group_1 1 3 0~1 0~7
Group_2 2 2 0~3 0~3
Group_3 3 1 0~7 0~1
Group_4(默认) 4 0 0~15 0

3. 配中断就 3 步

复制代码
 HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4);  // ① 分组(默认,一般不用调)
 HAL_NVIC_SetPriority(USART1_IRQn, 2, 0);              // ② 设优先级:抢占2,子0
 HAL_NVIC_EnableIRQ(USART1_IRQn);                      // ③ 开 NVIC 门

两层门都要开:

层 谁管 作用
NVIC 层 HAL_NVIC_EnableIRQ() CPU 允许响应这个中断
外设层 HAL_UART_Receive_IT() / 外设自己的使能位 外设事件发生时触发中断

4. 中断服务函数(ISR)

在 stm32f4xx_it.c 里,函数名必须和启动文件向量表里的完全一致。

复制代码
 void USART1_IRQHandler(void)
 {
     HAL_UART_IRQHandler(&huart1);   // CubeMX 已生成,不用自己读寄存器
 }
  • 名字写错 → 跳到启动文件里的空死循环,中断失效。

  • HAL_UART_IRQHandler() 帮你判断中断类型、清标志、调回调。

5. 回调机制(以串口接收为例)

复制代码
 串口收到一个字节
   → CPU 跳 USART1_IRQHandler()           CubeMX 已写
   → HAL_UART_IRQHandler()                HAL 已写
   → 判断是接收完成
   → HAL_UART_RxCpltCallback()             你重写,HAL 自动调

你要做的就两件事

复制代码
 // ① main 里开接收中断
 uint8_t rx_byte;
 HAL_UART_Receive_IT(&huart1, &rx_byte, 1);
 ​
 // ② 重写回调
 void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
 {
     if (huart->Instance == USART1) {
         // rx_byte 就是收到的字节
         HAL_UART_Receive_IT(&huart1, &rx_byte, 1);  // 重新开,等下一个
     }
 }

单次模式:收完一个字节外设中断自动关闭,不重新调 Receive_IT() 就收不到下一个。

6. 函数分类总结

类型 例子 谁调
CubeMX 生成 USART1_IRQHandler() 中断来了 CPU 自动跳
HAL 库自带 HAL_UART_IRQHandler() ISR 里调
HAL 库自带,你调 HAL_NVIC_SetPriority() / EnableIRQ() / HAL_UART_Receive_IT() main 里调
HAL 空壳,你重写 HAL_UART_RxCpltCallback() HAL 自动调

7. CubeMX 里配中断

  • 优先级分组 :左侧 System Core → NVIC → Priority Group 选 4 bits(默认Group_4,4位全给抢占,一般不用改)

  • 开中断:在每个外设自己的NVIC Settings里勾对应中断(如USART1页面勾USART1 global interrupt),不是在System Core→NVIC里统一开

  • 优先级数值:勾完中断后在同一页面填Preemption Priority和Sub Priority,数字越小越优先

  • HAL_Init()里已设好分组 :HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4),一般不用手动调

相关推荐
糖糖单片机设计1 小时前
基于STM32的空气污染检测与报警系统设计与实现
stm32·单片机·嵌入式硬件
盛世宏博北京2 小时前
工业环境稳定采集:配电室 IP 温湿度变送器 TCP/UDP 通信部署指南
单片机·tcp/ip·udp
comyccccc2 小时前
自制多路输出DCDC电源板,3.3V-12V可调 学习笔记
单片机·嵌入式硬件·硬件工程
Zwawa2 小时前
把 AO 接回来:黑线和白底之间到底差了多少
c语言·单片机·嵌入式
Yiran_G2 小时前
BLE终端数据积压如何处理?缓存队列、断连补传与流量调度设计
嵌入式硬件·物联网
硅基手札3 小时前
【串口技术系列文档 07】UART控制器寄存器详解
驱动开发·stm32·单片机·嵌入式硬件·mcu·计算机外设
甜甜的大香瓜3 小时前
【MT32F006】MT32F006之TM1621C驱动LCD
单片机
硅基手札3 小时前
【串口技术系列文档 09】FIFO管理与流控
驱动开发·stm32·单片机·嵌入式硬件·mcu·计算机外设
硅基手札3 小时前
【串口技术系列文档 08】中断驱动vs轮询vs DMA
驱动开发·stm32·单片机·嵌入式硬件·mcu·计算机外设