中断还是轮询?嵌入式外设驱动的最佳实践!

描述

刚入门做嵌入式开发时,很多人经常纠结:

  • 用定时器采集传感器数据,是直接 while 循环里轮询标志位,还是写个中断函数?
  • 串口收发数据时,是用 while(!(USART_SR&RXNE)) 这种老老实实轮询,还是开个中断来接收?
  • 项目调试时发现,轮询方式代码好像更直观,但 CPU 占用高得吓人;而中断看起来更“智能”,但又怕响应不及时。

这种困惑可以说是嵌入式开发的经典问题。今天,我们就来系统梳理一下 中断 vs 轮询 的区别、优缺点和应用场景,让你写项目时不再纠结。


 

一、轮询的本质:CPU 一直在问“好了没?”

所谓轮询,就是 CPU 主动不断查询外设状态寄存器。

例子:

如果我们要检测一个按键输入,代码可能是:

  1. while(1){
  2. if(GPIOx->IDR & PIN_MASK){
  3. // 按键按下,执行操作
  4. }
  5. }

特点:

  • 简单、直观,好写好调试;
  • 但 CPU 一直在跑循环,占用率极高;
  • 一旦有多个任务,就容易顾此失彼。

二、中断的本质:外设主动“通知 CPU”

中断的思路是,CPU 不再傻傻问“好了没”,而是外设自己准备好数据时,主动打断 CPU 的当前任务,让 CPU 去执行中断服务程序。

例子:

  1. void EXTI0_IRQHandler(void){
  2. if(EXTI->PR &(1<<0)){
  3.         EXTI->PR |=(1<<0);// 清中断标志
  4. // 按键按下,执行操作
  5. }
  6. }

特点:

  • CPU 不用浪费时间等待;
  • 响应更实时;
  • 但中断嵌套过多时,容易造成优先级冲突和响应延迟。

三、效率对比:什么时候轮询更好,什么时候中断更好?

1. 轮询的优势场景

  • 任务非常简单:比如检测一个 LED 状态,CPU 没有别的事干。
  • 高频率、低延迟需求:有些场合下,轮询比中断更快,因为不需要保存/恢复上下文。比如极简 bit-banging 通信。
  • 调试阶段:初学时,轮询逻辑更直观,不容易出错。

2. 中断的优势场景

  • 多任务并行:比如 ADC 连续采样、UART 通信、外部输入信号,这些外设无法预知何时到来,中断能让 CPU 高效切换。
  • 低功耗应用:MCU 可以进入休眠状态,等中断唤醒,而不是一直空跑。
  • 实时响应需求:外设状态一旦变化,立刻触发 ISR,避免轮询的延迟。

四、实战案例

案例 1:串口接收

  • 轮询方式:CPU 在循环中不断检测 RXNE 标志,CPU 占用率高,接收速率高时容易漏数据。
  • 中断方式:每来一个字节触发一次中断,CPU 只在需要时处理,效率更高。

【配图建议:串口数据流对比图,轮询方式 CPU 一直忙,中断方式 CPU 空闲→数据来才处理】

案例 2:按键输入

  • 轮询方式:需要在主循环不断检测 GPIO 状态,不适合低功耗。
  • 中断方式:用外部中断(EXTI)检测电平变化,CPU 平时休眠,按键按下时自动唤醒,非常适合电池供电设备。

案例 3:高速采样任务

  • 有时候轮询反而比中断更稳,比如 1MHz 的采样时钟,如果用中断,每秒中断 100 万次,CPU 可能直接崩溃;
  • 此时更合适的方案是 DMA + 定时器触发 ADC,比单纯中断/轮询都高效。

五、开发者常见误区

误区 3:中断一定比轮询好错。中断也有开销,尤其是上下文保存和恢复。低延迟场景下,简单轮询反而更快。
误区 2:轮询就是“落后”的方式错。对于某些短小的逻辑,轮询更容易实现,也不会带来复杂的中断优先级问题。

误区 3:所有任务都用中断处理错。中断太多会导致优先级冲突,难以维护。复杂系统一般会用 中断 + RTOS 任务 配合,而不是全靠 ISR。


六、总结:怎么选?

  • 项目小、逻辑简单 → 用轮询就行,别折腾太复杂;
  • 多任务并行、功耗敏感 → 中断更合适;
  • 高频采样、大数据吞吐 → DMA + 定时器触发,才是终极方案;
  • 调试阶段 → 可以先用轮询,逻辑清楚后再改成中断。

一句话总结:中断不是万能的,轮询也不是落后的,两者都有存在价值。关键是根据项目场景来选。


 

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分