Cortex-M4 内核自带 NVIC,支持 256 个中断。F407 用了 82 个:
NVIC 中断优先级:
| 优先级分组 | 抢占优先级位数 | 子优先级位数 | 常用范围 |
|---|---|---|---|
| 0 | 0 bit | 4 bit | 0 |
| 1 | 1 bit | 3 bit | 0~1 |
| 2 | 2 bit | 2 bit | 0~3 |
| 3 | 3 bit | 1 bit | 0~7 |
| 4 | 4 bit | 0 bit | 0~15 |

EXTI(External Interrupt)负责把 IO 电平变化转换为 NVIC 中断。
| 线路 | 来源 |
|---|---|
| EXTI0~EXTI15 | GPIOx_Pin0~15 |
| EXTI16 | PVD 输出 |
| EXTI17 | RTC 闹钟 |
| EXTI18 | USB OTG_FS 唤醒 |
| EXTI21 | RTC Tamper / TimeStamp |
| EXTI22 | RTC Wakeup |
每条 EXTI 只能连接到一个 GPIO 的一个 pin,例如 EXTI0 可绑 PA0/PB0/.../PI0 中任意一个。
使用 KEY0/KEY1/KEY_UP 接 PE4/PE3/PA0 作外部中断触发。LED0/LED1 接 PF9/PF10 作中断响应。
HAL_NVIC_EnableIRQ(EXTI4_IRQn); HAL_NVIC_SetPriority(EXTI4_IRQn, 2, 0); 设置优先级;HAL_GPIO_Init 的 Mode 设为 GPIO_MODE_IT_FALLING(下降沿触发);EXTI4_IRQHandler → 调 HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_4) → 回调 HAL_GPIO_EXTI_Callback。void EXTI4_IRQHandler(void) {
HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_4);
}
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) {
delay_ms(20);
if (GPIO_Pin == GPIO_PIN_4) { // KEY0
if (KEY0 == 0) LED0_TOGGLE();
}
}

按 KEY0 → LED0 翻转;KEY_UP → LED1 翻转。CPU 平时可做其他事,按下时才被「唤醒」。
g_key0_pressed = 1; 在 main 里循环检查再处理。