单片机中断执行流程
中断执行流程
一、中断触发阶段
1. 中断源触发
- 硬件事件:
GPIO
输入、定时器溢出、ADC
转换完成等。 - 软件事件:软件中断指令(如
SWI - SoftWare Interrupt
)。
2. 中断请求(IRQ
)发送
- 外设将中断标志位置1,并向
NVIC
(嵌套向量中断控制器)发送请求。 NVIC
根据优先级决定是否立即响应。
二、中断响应阶段
1. 处理器上下文保存
- 自动压栈(硬件完成):
- 当前程序计数器(
PC
)、程序状态寄存器(xPSR
)、通用寄存器(R0-R3, R12, LR
)依次压入当前堆栈(MSP/PSP
)。 - 若中断嵌套发生,自动切换到主堆栈(
MSP
)。
- 当前程序计数器(
- LR值更新:
LR
被设置为特殊值(如0xFFFFFFF1
),标记中断返回模式。
2. 中断向量表查找
处理器根据中断号(
IRQn
)计算向量表偏移:1
中断服务函数地址 = VTOR(向量表基址) + 4 * (IRQn + 16)
- 例如:
IRQn=10
,其地址 =0x8000000 + 4 * (10 + 16) = 0x8000068
- 例如:
3. 跳转到中断服务函数(ISR
)
- 处理器从向量表中读取
ISR
地址,并跳转执行。
注:
ISR
不能返回一个值。ISR
不能传递参数。在许多处理器/编译器中,浮点一般都是不可重入的。有些处理器/编译器需要让额外的寄存器入栈。有些处理器/编译器就不允许在ISR中做浮点运算。此外,
ISR
应该是短而有效率的,在ISR
中做浮点运算是不明智的。与第三点一脉相承,
printf()
经常有重入和性能上的问题,所以一般不使用printf()
。
三、中断处理阶段
1. ISR
执行流程
1 | void TIM1_IRQHandler(void) { |
2. 关键注意事项
- 快速响应:
ISR
应尽量简短,避免长时间阻塞。 - 共享资源保护:若需访问全局变量,使用临界区(关中断)或原子操作。
四、中断返回阶段
1. 上下文恢复
- 出栈操作(硬件自动完成):
- 从堆栈中依次恢复
R0-R3, R12, LR, PC, xPSR
。
- 从堆栈中依次恢复
- LR值检查:若
LR=0xFFFFFFF1
,表示返回线程模式并使用MSP
。
2. 返回原程序
- 处理器恢复之前的
PC
和xPSR
,继续执行被中断的代码。
五、完整流程示意图
1 | ┌───────────────────────┐ |
中断嵌套与优先级
1. 优先级规则
- 抢占优先级:高优先级可打断低优先级。
- 子优先级:相同抢占优先级时,按子优先级顺序执行。
2. 嵌套中断流程
1 | 低优先级ISR执行中 |
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 龙猫知识库!