中断(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),一般不用手动调

相关推荐
路上有只喵20 小时前
认识元器件 · 单片机(MCU/MPU/SOC) · 实战篇5
单片机·嵌入式硬件·fpga开发
恒锐丰科技林技术员20 小时前
CL5012A 升压型双节锂电池充电芯片方案解析
经验分享·嵌入式硬件·硬件工程
小向是个Der1 天前
嵌入式进阶——MCU上电后的动作
c语言·单片机·mcu·学习·链接脚本
Kuakewei8881 天前
PW6606快充协议诱骗芯片:纯硬件电阻配置五档电压方案
嵌入式硬件
车软学堂1 天前
从测试转开发,到底要补什么
网络·人工智能·python·功能测试·单片机·车载系统·自动化
LCG米1 天前
STM32 ADC多通道DMA定时器触发实测:TRGO触发链、采样率精确控制与乒乓缓冲落地
stm32·单片机·嵌入式·adc
iCxhust1 天前
SEGGER 的 J-Scope
单片机·嵌入式硬件
路上有只喵1 天前
认识元器件 · 单片机(MCU/MPU/SOC) · 实战篇2
单片机·嵌入式硬件
单片机仿真设计1 天前
Proteus仿真51单片机的智能温控风扇调速系统设计(仿真图+程序)
单片机·嵌入式硬件·proteus
youcans_1 天前
【嵌入式软件AI编程】22. STM32 基础实验:GPIO外部中断
stm32·单片机·嵌入式硬件·ai编程·claude