1. 单片机中断原理概述
中断是单片机系统中最为核心的机制之一,它允许处理器在执行主程序时,能够及时响应外部或内部的紧急事件。想象一下,你正在书房专心写作,突然门铃响了——这时你会先做个书签标记当前页面(保存现场),去处理访客(执行中断服务程序),待访客离开后再回到书桌前继续写作(恢复现场)。单片机中断的工作机制与此高度相似。
在8051、STM32等主流单片机架构中,中断系统通常包含以下关键组件:
- 中断源:产生中断请求的信号来源,如定时器溢出、外部引脚电平变化、串口数据到达等
- 中断控制器:管理多个中断源的优先级和触发条件
- 中断向量表:存储各中断服务程序入口地址的特殊内存区域
- 现场保护机制:自动保存程序计数器(PC)和关键寄存器值的硬件逻辑
提示:不同架构单片机的中断实现差异较大。例如51系列采用固定优先级,而Cortex-M系列支持动态优先级调整和尾链优化等高级特性。
2. 中断处理全流程解析
2.1 中断触发条件
中断触发主要分为电平触发和边沿触发两种模式:
- 电平触发:当INT引脚保持低/高电平超过指定时间后触发(如51单片机外部中断)
- 边沿触发:检测INT引脚上升沿或下降沿时触发(如STM32的EXTI中断)
以温度监控系统为例:
c复制// STM32 HAL库配置下降沿触发
GPIO_InitStruct.Pin = GPIO_PIN_0;
GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
2.2 中断响应过程
当中断触发时,硬件自动执行以下操作:
- 完成当前指令执行
- 将PC值压入堆栈(51单片机需手动保存ACC/PSW等寄存器)
- 从中断向量表加载ISR入口地址
- 跳转到ISR执行
典型51单片机中断服务函数框架:
assembly复制ORG 0003h ; INT0中断向量
LJMP ISR_INT0
ISR_INT0:
PUSH ACC
PUSH PSW
; 中断处理代码
POP PSW
POP ACC
RETI
2.3 中断优先级机制
优先级处理存在三种典型方案:
| 类型 | 代表MCU | 特点 |
|---|---|---|
| 固定优先级 | 8051 | 中断源优先级固定不可调(INT0 > T0 > INT1 > T1 > 串口) |
| 可编程优先级 | STM32 | 通过NVIC寄存器动态配置优先级(0-15级),支持抢占和嵌套 |
| 轮询方式 | 简易MCU | 按固定顺序检查中断标志位,无硬件优先级 |
注意:在RTOS环境中(如FreeRTOS),需特别注意临界区保护和中断延迟问题。建议将时间敏感中断设为最高优先级。
3. 关键外设中断实战配置
3.1 定时器中断精讲
以STM32定时器2更新中断为例,完整配置流程:
- 时钟使能
c复制__HAL_RCC_TIM2_CLK_ENABLE();
- 时基配置(1ms周期)
c复制TIM_HandleTypeDef htim2;
htim2.Instance = TIM2;
htim2.Init.Prescaler = 7200 - 1; // 72MHz/7200 = 10kHz
htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
htim2.Init.Period = 10 - 1; // 10kHz/10 = 1kHz (1ms)
HAL_TIM_Base_Init(&htim2);
- 中断使能
c复制HAL_NVIC_SetPriority(TIM2_IRQn, 1, 0);
HAL_NVIC_EnableIRQ(TIM2_IRQn);
HAL_TIM_Base_Start_IT(&htim2);
3.2 外部中断避坑指南
常见问题及解决方案:
-
按键抖动问题
- 硬件方案:并联104电容
- 软件方案:中断后延时10ms再检测电平
c复制void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) { if(GPIO_Pin == KEY_Pin) { HAL_Delay(10); if(HAL_GPIO_ReadPin(KEY_GPIO_Port, KEY_Pin) == GPIO_PIN_RESET) { // 有效按键处理 } } } -
中断无响应排查步骤
- 确认GPIO时钟已使能
- 检查NVIC优先级配置是否冲突
- 验证中断线映射是否正确(如PB0对应EXTI0,PC0也对应EXTI0)
4. 高级中断应用技巧
4.1 DMA与中断协同工作
在ADC多通道采样场景中,典型配置流程:
- 配置ADC为连续转换模式
- 设置DMA循环模式搬运数据
- 使能DMA传输完成中断
c复制// STM32CubeMX生成配置示例
hdma_adc.Init.Mode = DMA_CIRCULAR;
hdma_adc.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_adc.Init.MemInc = DMA_MINC_ENABLE;
HAL_DMA_Init(&hdma_adc);
__HAL_LINKDMA(&hadc, DMA_Handle, hdma_adc);
HAL_ADC_Start_DMA(&hadc, (uint32_t*)adc_buffer, BUFFER_SIZE);
4.2 低功耗模式下的中断唤醒
在STOP模式下,只有特定中断能唤醒MCU:
- 外部中断(EXTI)
- RTC闹钟
- 特定通信接口中断(如USART的IDLE中断)
配置要点:
c复制// 进入STOP模式前
HAL_PWR_EnableWakeUpPin(PWR_WAKEUP_PIN1);
__HAL_RCC_PWR_CLK_ENABLE();
// 唤醒后需要重新初始化时钟
SystemClock_Config();
5. 中断调试与性能优化
5.1 逻辑分析仪实测技巧
使用Saleae逻辑分析仪捕获中断时序:
- 连接MCU的GPIO测试点
- 在ISR开始和结束位置添加电平翻转代码
c复制void EXTI0_IRQHandler(void) {
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, GPIO_PIN_SET); // 标记进入
// 中断处理代码
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, GPIO_PIN_RESET); // 标记退出
}
通过脉冲宽度可精确测量中断响应时间和执行时间。
5.2 中断负载评估方法
计算中断最大允许频率:
code复制最大中断频率 = 1 / (中断服务程序执行时间 + 现场保护/恢复时间)
例如:ISR执行需要20μs,现场处理需5μs,则最高频率≈40kHz。超过此频率会导致系统瘫痪。
在STM32CubeMX中,可通过"Interrupt"标签页直观查看各中断的预估CPU占用率。
