1. 轮询(Polling)基础概念

1.1 什么是轮询?

轮询,说白了就是CPU主动去“问”外设:“你准备好了没?”。一遍没准备好,就再问一遍,直到外设说“好了,快来拿数据”。

我刚开始做嵌入式开发时,觉得轮询挺傻的——CPU啥也不干,就在那儿死等。但后来我发现,很多场景下轮询反而是最简单、最可靠的办法。

从技术角度讲,轮询是一种同步通信机制。主控器(通常是MCU)在一个循环里反复读取某个状态寄存器或信号引脚。这个循环可以一直跑,也可以隔一段时间跑一次。关键点在于:CPU主动发起访问,外设被动响应。

轮询的核心特征

  • CPU主动查询外设状态
  • 查询频率由软件控制
  • 响应时间取决于轮询间隔
  • 无需额外硬件中断支持

你想想看,这和中断方式正好相反。中断是外设主动通知CPU:“我有事找你”。而轮询是CPU一遍遍去问:“你有事吗?你有事吗?”。

1.2 轮询的工作模型

// 典型的轮询循环
while (1) {
    status = read_register(DEVICE_STATUS_REG);
    
    if (status & DATA_READY) {
        data = read_register(DEVICE_DATA_REG);
        process_data(data);
    }
    
    // 可选的延时控制
    delay_ms(10);
}

上面这段代码,是我在实际项目中最常用的轮询框架。注意那个延时——没有它,CPU会跑满速,功耗扛不住。我记得有一次调试,忘了加延时,结果CPU功耗直接飙到标称值的两倍,开发板烫得不敢摸。

1.3 轮询在嵌入式系统中的应用场景

什么时候用轮询?这个问题我遇到过很多次。不是所有场景都适合轮询,但下面这几类情况,我个人认为轮询是最佳选择。

应用场景 典型设备 轮询优势
低速外设访问 键盘、开关、LED 实现简单,延迟可接受
短距离简单通信 SPI传感器、I2C EEPROM 协议简单,时序可控
实时性要求低的任务 温度采集、状态监控 代码量小,易维护
系统初始化阶段 PLL锁定检测、ADC校准 不需要中断支持
中断资源紧张时 低成本MCU 节省中断向量表空间

低速外设访问:像按键扫描这种,你按一下可能要持续几十毫秒。轮询周期设在5-10ms,完全够用。我用STM32做门禁系统时,就是用轮询扫描矩阵键盘,没什么问题。

短距离简单通信:SPI和I2C这种同步协议,天生适合轮询。你发一个时钟,读一个数据,节奏自己控制。我曾经用轮询方式驱动一个SPI接口的加速度计,工作得很好。

系统初始化阶段:上电后MCU还没配好中断控制器,这时候只能用轮询。我记得调试一块FPGA&MCU混合板时,PLL锁定状态就是靠轮询等到的。

一个实用的判断标准

外设事件发生的间隔大于10ms,用轮询完全OK。如果间隔小于1ms,或者对延迟有严格要求,建议用中断。

1.4 轮询的优缺点

没有银弹。轮询有它的好,也有它的坑。我踩过的坑不少,跟你们分享一下。

优点

  • 代码逻辑简单,容易理解
  • 调试方便,执行路径可控
  • 不依赖外部中断资源
  • 时序确定性强(中断的响应时间会有抖动)

缺点

  • CPU利用率低,空转浪费算力
  • 响应延迟受轮询周期限制
  • 多任务场景下优先级管理困难
  • 功耗高(除非加入休眠机制)

避坑指南:轮询超时

我曾经掉进过一个坑:用一个轮询循环等一个外部ADC转换完成。理想情况是2ms完成,但现场环境温度变化后,ADC转换时间飘到了5ms。我的轮询超时设的是3ms,结果程序一直报错。后来我加了动态超时重试机制才解决。

记住:轮询一定要设超时保护,不然外设死了,你的系统也跟着死。

1.5 轮询与中断的对比

为了让概念更清楚,我把轮询和中断做了个对比。这张表我在内部培训时经常用,很多人看完就明白了。

特性 轮询 中断
触发方式 CPU主动查询 外设主动通知
CPU占用 持续占用(或周期占用) 事件触发时才占用
响应延迟 取决于轮询间隔 取决于中断优先级(通常更短)
代码复杂度 低 中高(需要ISR、上下文保存)
适用频率 低频事件(<100Hz) 高频或随机事件
资源需求 无额外硬件需求 需要中断控制器、向量表
调试难度 容易 较难(ISR内断点影响时序)

看到这张表,你应该能明白为什么很多低成本MCU项目还是用轮询。省资源、好调试,对工程师来说太重要了。

1.6 轮询的核心知识图谱

下面这张图是我自己画的轮询知识结构图,把本章的核心内容串起来了。你可以把它当成一个思维导图看。

轮询(Polling)核心知识体系 轮询基础概念 工作原理 应用场景 优缺点 与中断对比 CPU主动查询 循环检查状态 低速外设 简单通信协议 初始化阶段 CPU利用率低 实现简单 同步 vs 异步 资源开销对比 轮询是嵌入式系统中最基础的同步通信机制 理解它是后续解决超时问题的前提

看完这张图,你应该对轮询有了整体认识。它不是什么高深的概念,但基础打牢了,后面讲超时问题调试才会顺手。

1.7 小结

这一章我带着你过了轮询的基本概念。总结起来就三句话:

  • 轮询就是CPU主动去问外设的状态
  • 适合低速、简单、确定性强的场景
  • 一定要做超时保护,这是底线

记住这些,后面我们开始讲轮询超时的问题和调试技巧。嗯,先把基础稳住,后面才有底气。