中断和事件的区别:
中断是需要CPU参与的,执行中断服务程序。通过自定义中断服务程序,可用来实现特定的功能,通常需要手动清除标志位。
事件(标志位)完全是由硬件自动处理的,不需要CPU参与。事件用来在外设之间通知,比如定时器信号触发ADC采样转换,会自动清除标志位。

STM32 单核心,每个中断源对应着一个中断号。
分为内核中断和外部中断:
内核中断:不可屏蔽中断,无法通过软件进行控制
外部中断:可屏蔽中断,可以通过软件进行控制
中断
NVIC 管理器
嵌套向量中断控制器
NVIC 是 CPU的一个外设,。
作用:
动态优先级配置:
中断使能:
总中断
单独中断:
中断向量表自动跳转:
中断状态管理:
只需要关心前两个就行了,我们需要配置的。
STM32、GD32、ESP32 的芯片设计者,为每个外设分配了一个唯一的中断号。
中断号是让 NVIC 知道是哪个中断源,通过软件设置 NVIC,可以决定中断的优先级、是否开启中断。
中断优先级
F0 系列的 NVIC 只有 2 位,可配置0~3,不区分抢占和响应优先级,没有分组的概念。
对于 Cortex-M 内核,数字越小,优先级越高。
NVIC_InitTypeDef nvic_struct;
nvic_struct.NVIC_IRQChannel = EXTI2_3_IRQn;
nvic_struct.NVIC_IRQChannelPriority = 0x00;
nvic_struct.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&nvic_struct);F1标准库:
优先级分组
默认的分组不清楚,但是,开发中必须显式的设置优先级分组,最常用的就是分组2。
F0 标准库:
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);中断开关
全局中断开
__enable_irq();
__set_PRIMASK(0);关
__disable_irq();
__set_PRIMASK(1);stm32_hal_cortex.c 是对 core_cm3 的进一步封装
外部中断
引脚与外部中断线的映射
外部中断配置
F0 标准库:
void EXTI2_Config(void)
{
EXTI_InitTypeDef exti_struct = {0};
NVIC_InitTypeDef nvic_struct = {0};
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOB, EXTI_PinSource2);
exti_struct.EXTI_Line = EXTI_Line2;
exti_struct.EXTI_Mode = EXTI_Mode_Interrupt;
exti_struct.EXTI_Trigger = EXTI_Trigger_Rising;
exti_struct.EXTI_LineCmd = ENABLE;
EXTI_Init(&exti_struct);
nvic_struct.NVIC_IRQChannel = EXTI2_3_IRQn;
nvic_struct.NVIC_IRQChannelPriority = 0x00;
nvic_struct.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&nvic_struct);
}
void EXTI2_3_IRQHandler(void)
{
if(EXTI_GetITStatus(EXTI_Line2) != RESET)
{
// 处理逻辑
EXTI_ClearITPendingBit(EXTI_Line2);
}
}
//F0 标准库没有专门的反初始化函数,下面这个函数最后两步没测试过
void EXTI2_Deinit(void)
{
EXTI_InitTypeDef exti_struct = {0};
NVIC_InitTypeDef nvic_struct = {0};
// 禁用 EXTI2 外部中断
exti_struct.EXTI_Line = EXTI_Line2;
exti_struct.EXTI_Mode = EXTI_Mode_Interrupt;
exti_struct.EXTI_Trigger = EXTI_Trigger_Rising;
exti_struct.EXTI_LineCmd = DISABLE;
EXTI_Init(&exti_struct);
// 禁用 EXTI2_3 中断,如何只 禁用2的,保留3的?
nvic_struct.NVIC_IRQChannel = EXTI2_3_IRQn;
nvic_struct.NVIC_IRQChannelPriority = 0x00;
nvic_struct.NVIC_IRQChannelCmd = DISABLE;
NVIC_Init(&nvic_struct);
// 清除 EXTI2 的挂起标志
EXTI->PR = EXTI_Line2;
// 恢复 SYSCFG 映射为默认
SYSCFG->EXTICR[0] &= ~(SYSCFG_EXTICR1_EXTI2); // EXTI2 映射到 PA2(默认)
}
系统异常向量中断
NMI_Handler:
处理关键硬件异常(如时钟失效)
HardFault_Handler:
访问非法地址:数组越界、野指针、访问未映射寄存器
硬件错误,CPU 无法处理
SVC_Handler 和 PendSV_Handler 在 RTOS 中用到,裸机用不到。
SysTick_Handler:
HAL 库中作为时基
RTOS 作为时基
标准库好像不用这个??不确定
必须声明这5个异常处理函数,否则编译器/链接器会报错。