先搞懂它是什么
- 中断(Interrupt):外设/硬件“插队”通知 CPU 的机制。CPU 正在干活时,按键按下、串口来数据等事件会打断它,先处理事件再回来继续——相当于“电话响了先接电话”。
- 定时器(Timer):一个按固定节拍数数的“秒表”,数到设定值就触发事件(中断/回调),用于延时、定时轮询、生成 PWM 等。
- 两者配合:定时器到点产生中断,是嵌入式里“每隔一段时间做一件事”的标准姿势。
层层拆解原理
1. 中断的处理流程
要点:
- 中断向量表:一张“哪个中断 → 哪个处理函数”的映射表,事件发生时硬件查表跳转。
- 保存/恢复现场:处理前把当前状态存起来,处理完原样恢复,主程序“无感”。
- 清中断标志:处理完必须清掉触发标志,否则会反复进入中断(死循环式误触发)。
2. 中断优先级与嵌套
多个中断同时发生时,硬件按优先级决定先处理谁;高优先级可以打断低优先级(嵌套)。设计原则:
- 中断里只做“短小”的事(置标志、存数据、清标志),重活放到主循环/任务里做。
- 不要在中断里做耗时操作(打印长日志、延时),否则会拖垮实时性。
- 中断里访问的共享变量,主程序访问时要注意原子性(如关中断或使用 RTOS 的临界区保护)。
3. 定时器的组成与工作方式
一个硬件定时器通常包含:
- 计数源时钟:来自系统时钟经过分频后的节拍。
- 预分频器:把节拍再分频,控制计数速度(决定“每秒数几个数”)。
- 计数器:从初值向上/向下数。
- 比较/重装载值:数到该值时触发中断(或自动重装、翻转输出)。
两种典型模式:
| 模式 | 行为 | 典型用途 |
|---|---|---|
| 单次定时 | 数到值触发一次,停止 | 延时、超时判断 |
| 周期定时 | 数到值触发后自动重装,循环 | 周期性采样、心跳、PWM 生成 |
4. 与延时、PWM、捕获的关系
- 软件延时 vs 定时器:
while空转延时浪费 CPU 且不精确;定时器让 CPU 去干别的,到点再回来。 - PWM:本质是定时器周期翻转输出电平,调节高电平占比就是调占空比。
- 输入捕获:测量外部脉冲宽度/频率,靠定时器记录边沿时刻。
结合 SDK 看实现
- 相关例程页:EXTI 外部中断、TIMER 定时器、MTimer 机器定时器、PWM
SDK 里定时器中断的套路是“初始化 → 注册回调 → 启动”:
c
struct bflb_device_s *timer = bflb_device_get_by_name("timer0");
/* 注册定时器中断回调:到期执行 timer_isr */
bflb_timer_attach_irq(timer, timer_isr);
bflb_timer_init(timer, TIMER_PRESCALER_256, TIMER_COUNTER_INCREASE, 0xffffffff);
bflb_timer_set_compvalue(timer, 1000000); /* 计数到 1000000 触发 */
bflb_timer_start(timer);外部中断(EXTI)则是把 GPIO 配置成中断输入并绑定回调,按键按下时由硬件触发,无需轮询。
常见考点 / 面试题
为什么中断服务函数里不能做耗时操作?
中断会打断主流程,耗时过长会阻塞其他中断和主任务,破坏实时性;应只做置标志/存数据/清标志等短小操作。
中断处理完为什么要清中断标志?
不清标志硬件会认为事件仍然存在,立即再次触发中断,造成反复进入中断,主程序永远无法继续。
软件延时和定时器延时有什么区别?
软件延时让 CPU 空转等待,浪费算力且受优化影响;定时器由硬件计数,CPU 可去执行其他任务,到点再中断回来,更准确也更高效。
PWM 的占空比和周期分别由谁决定?
周期由计数频率与重装载值决定,占空比由比较值决定:计数到比较值时输出翻转/拉低,所以改比较值就是改占空比。
什么是中断优先级反转/优先级的问题?
这里主要指 RTOS 场景的优先级反转(低优先级任务持有锁导致高优先级任务等待),属于“任务优先级”而非“中断优先级”;中断本身只谈硬件优先级,高优先级可打断低优先级(嵌套)。
遇到问题?
如有其他问题,请到统一的提问与讨论区:Ai-Thinker Discussions

