资讯动态

嵌入式面试高频考点:UART、I2C、SPI三剑客全解析

发布时间:2026/10/18 17:05:45 来源:尧图企业网站定制
做嵌入式开发这些年从单片机裸机到 Linux 驱动再到物联网终端跟人聊过、也模拟面过不少候选人发现一个规律不管简历上写的是哪个方向只要问到通信接口UART、I2C、SPI 这三个协议几乎是必考题。它们被戏称为“串行三剑客”覆盖了板卡内部器件互联、芯片间通信、传感器数据采集这些最常见的场景。面试官问这些表面上是在考察你懂不懂协议本身实际想看的是你有没有真正拿示波器看过波形、有没有在调试中处理过数据错乱和总线卡死这类现场问题。这篇文章就把这三个协议的面试高频考点整理成一份完整的复习地图从帧格式、时序细节、仲裁机制到实际调试中的典型坑一次讲透。适合正在准备嵌入式软硬件岗位面试的同学也适合刚入行想系统梳理串行通信基础、想把手头代码和芯片手册真正对应起来的工程师。1. 为什么面试官死磕这三个协议1.1 串行通信的江湖地位你很难找到一块 MCU 开发板能绕开这三套协议。单片机内置的外设清单里标配几乎永远是几路 UART、一路 I2C、一两个 SPI 控制器外设芯片这边各类传感器、存储器、屏幕驱动、网络芯片的接口也基本扎堆在这三个协议里。串行通信的核心就是“一条线一个 bit 一个 bit 地传”相比并行总线省引脚、省 PCB 面积、抗干扰设计也更灵活代价是要靠协议来协商起始、结束、数据位和校验。UART、I2C、SPI 恰恰代表了三种完全不同的同步思路UART 靠双方约定波特率自己从引脚电平里恢复时钟属于典型的异步通信I2C 和 SPI 都靠主机输出时钟信号从机被动跟随属于同步通信。但 I2C 只有两根线数据还得在时钟的低电平期间变化SPI 直接拉出独立的时钟加双数据线主从之间可以双向同时传。这三个协议刚好串起了“时序、电平、仲裁、速率、可靠性”这几大嵌入式基本功所以面试官爱从它们下手。1.2 三剑客各有各的脾气UART点对点异步串口收发各占一根线全双工跑起来一支 TX 一支 RX。没有专门的时钟线全靠收发双方提前约定波特率。I2C两线制半双工总线一条串行数据线 SDA、一条串行时钟线 SCL属于开漏结构多个设备直接挂同一根总线上通过地址区分谁跟谁说话。SPI典型四线制同步全双工总线主机负责提供时钟和片选从机被选中后就在时钟边沿收发数据通信速度可以拉得很高。明白这三者“一个异步、一个两线制多主总线、一个四线制高速交换”后面所有细节都围绕着这几个根本差异展开。面试题问得再刁钻最后落脚点也逃不出这些性质的衍生问题比如“I2C 为什么要上拉”“SPI 为什么不用地址”“UART 波特率误差多少算超标”。2. UART 考点全拆解异步时序里的高频陷阱2.1 帧格式与时序一张图记牢UART 的帧结构是所有协议里最经典的。默认空闲时 TX 线保持高电平要发送一字节数据时先拉低一个位时间这是起始位接着按 LSB 在前、MSB 在后的顺序输出数据位数据位之后是可选的校验位最后至少拉高一到两个位时间的停止位。一个典型 8N18 数据位、无校验、1 停止位的字节格式按时间顺序展开就是空闲(高) | 起始(0) | D0 | D1 | D2 | D3 | D4 | D5 | D6 | D7 | 停止(1) | 空闲(高)面试里经常出现“画一下 UART 发送 0x55 的波形”这种题。0x55 的二进制是 01010101按 LSB 先发数据位就是 1、0、1、0、1、0、1、0配合起始位和停止位时序就是高低交替的方波这也是为什么调试时很多人拿 0x55 做测试数据——波形规则肉眼就能判断电平翻转是否正常。UART 只有起始位和停止位做对齐没有独立的时钟线所以收发双方必须把波特率配置得足够一致。常见的 9600、115200 都是标称速率实际由时钟源分频得到两个设备即使都写 115200因为晶振误差和分频取整的原因真正的波特率也会有一点偏差。接收端通常用波特率时钟的 16 倍频去采样在每个 bit 中间做多次采样取多数表决这样可以容忍一定误差一般收发两端波特率误差合计控制在 2%~3% 以内比较稳妥。超过这个范围就容易出现“数据偶发错位、每几个字节里跳出一个乱码”的典型症状。2.2 物理层、流控与常见扩展基础的 UART 是 TTL 电平适合板内短距离通信。工业现场常把 TTL 串口转成 RS-232 或者 RS-485前者的电平摆幅更大、距离能到十几米后者使用差分信号配 120Ω 终端匹配电阻能拉到几百米甚至上公里而且 RS-485 是半双工共线结构多个节点靠地址轮询来通信所以 MCU 的 UART 外设往往支持 9 位数据模式其中第 9 位用来标记地址帧配合收发切换的使能脚实现多机通信。流控方面要分清两种硬件流控用 RTS/CTS 两根脚接收缓冲区快满时拉低 RTS 通知对端暂停软件流控 XON/XOFF 在数据里插控制字符应用层处理麻烦且容易和普通数据冲突。我在实际项目里更倾向硬件流控只要线没接错基本不用管但很多人第一次做透传模块时把 RTS/CTS 悬空对端等流控信号导致卡住调试半天才发现是线序问题。2.3 高频考点清单面试官针对 UART 最常问这几类问题按我的经验挨个归纳一下UART 是同步还是异步为什么答异步没有共享时钟线接收端用本地采样时钟恢复数据依赖起始位对齐。1 秒能传多少字节比如 115200、8N1每个字节 10 个 bit 时间理想情况下每秒约 11520 字节。要注意这个“约”因为开头结尾还有起始停止位开销。校验位的用途和局限。奇偶校验只能发现奇数个 bit 翻转无法纠错一来一回在协议栈里加校验才是常态。波特率不匹配会有什么现象数据整体错位、帧错误、乱码。9 位数据模式是干嘛用的RS-485 多机通信的地址标记。2.4 实调经验与避坑实际调板子时我最推荐的排查顺序是先发连续 0x55用示波器看 TX 脚有没有方波再用逻辑分析仪抓一帧数起始位、数据位、停止位是否和配置一致。如果波形正常但对端收到的数据不对优先怀疑波特率误差和线路电平转换电路方向。接线类模块 TX/RX 交叉是最常见低级错误逻辑分析仪一抓就原形毕露。还要注意部分 MCU 的 UART 外设内部有 FIFO发送 API 写完寄存器并不代表数据已经出引脚尤其 DMA 模式下要等发送完成标志位再关外设。我在项目里就遇到过 sleep 前关掉串口、结果最后一个字节被截断的事就是这个原因。3. I2C 考点全拆解两根线上的多主江湖3.1 物理层为什么必须开漏加外部上拉I2C 让人最容易懵的地方就在物理层。SDA 和 SCL 都是开漏结构芯片内部不主动输出高电平只能拉低或释放高电平全靠外部上拉电阻提供。这样设计的最大好处是多个设备可以同时挂在这两根线上任何设备想拉低就拉低不会出现一个设备输出高、另一个设备输出低导致的短路灌流。总线上的电平逻辑可以理解成“线与”任何一个设备拉低总线就是低想表达高电平的设备只需要不管它。上拉电阻的取值直接影响上升沿时间和通信速率。阻值太小灌电流大、功耗高甚至拉伤端口阻值太大总线电容充电太慢高速模式下波形爬坡不到位会造成时序不合格。I2C 标准里规定上升时间实际工程上常用 4.7kΩ 配 100kHz、2.2kΩ 配 400kHz具体要结合总线上挂的设备数量和走线长度估算总线电容。有经验的面试官会追问“上拉电阻怎么算”这时可以答出 RC 充电时间常数、查器件手册的总线电容参数、再按目标频率反算阻值这个思路比死记某个数值有价值得多。3.2 时序细节起始、停止、ACK、重复起始I2C 的时序规约是面试里最容易被抠细节的部分必须掌握这几个动作起始条件 STARTSCL 为高时SDA 发生高到低跳变。停止条件 STOPSCL 为高时SDA 发生低到高跳变。数据位规则SDA 只能在 SCL 为低电平期间变化SCL 为高时 SDA 必须稳定。应答 ACK/NACK每收完一个字节接收方在第 9 个 SCL 周期的 SDA 上拉低表示 ACK保持高表示 NACK。重复起始 REPEATED START不拉停止直接在一个操作中间再次发出起始条件用于读 EEPROM、传感器切换寄存器地址等场景。这段用文字描述很绕但用波形画出来就非常直观起始: SCL ____/‾‾‾‾‾‾‾‾ SDA ____/‾‾‾‾‾‾‾‾ 先SDA从高变低SCL保持高 停止: SCL ‾‾‾‾‾‾‾‾\____ SDA ‾‾‾‾‾‾‾‾\____ SDA从低变高SCL保持高 字节: SDA 稳定期只在SCL低电平时改变SCL高时取值面试题常出“为什么读寄存器要先发设备地址再发寄存器地址中间不加 STOP”答案就是重复起始保证了总线占用不释放避免其他主机插入操作提高读操作的事务完整性。3.3 仲裁与时钟拉伸I2C 支持多主机同一条总线这是它的独门绝技。当两个主机同时发起传输各自输出自己的 SDA 电平总线开漏结构和线与特性会让其中一个发现“我想发高电平但总线上是低电平”说明自己失去了仲裁立刻停止发送等对方操作完再重试整个过程不破坏数据传输。背后的原理就是 SDA 的电平比较谁先想拉高却发现拉不上去谁就输。时钟拉伸则是从机端的能力从机处理不过来时可以在第 9 个时钟周期把 SCL 拉低不动主机检测到 SCL 一直低就知道从机在“喊暂停”等从机处理完再释放 SCL时钟自然恢复继续。主机的 I2C 控制器必须支持超时判断否则从机因为故障一直拉低 SCL整条总线就会卡死。这个点我见过不少面试官设计成场景题“总线 SDA 一直为高、SCL 一直在翻转这个系统大概是什么问题”答案里如果带着排除时钟拉伸和仲裁冲突的思路基本能过。3.4 读操作时序EEPROM 读怎么写才不出乱码I2C 读写操作是纯考手写能力的题。以常见的 EEPROM 读取为例标准流程是发出 START发送设备地址字节与写标志如 0xA0等待从机 ACK发送要读取的存储地址等待 ACK发送 REPEATED START发送设备地址字节与读标志如 0xA1读回数据最后一个字节回 NACK 表示结束发送 STOP。这里最容易写错的点是第 8 步。很多人习惯统一对每个字节都回 ACK结果最后多读一个字节才结束或者主机一直发 ACK 把从机数据读不完正确做法是连续读取时除了最后一个字节都回 ACK最后一字节回 NACK 再拉 STOP。逻辑分析仪上能明显看到最后一个字节后 SDA 不再被拉低。3.5 调试经验总线卡死怎么救I2C 调试的最大噩梦是总线被某设备拉低导致通信完全瘫痪。最常见原因是某个从机上电时序不对先抢占了 SDA 低电平或者从机在等待主机时钟时主机提前放弃从机一直保持 SDA 低。现场急救手段是给 SCL 连打 9 个以上的脉冲让从机完成当前字节的周期然后发一个 STOP 条件恢复空闲态这是原始但有效的“总线解锁”操作。另一个经验是初始化外设时别急着配置成多主机模式能单主机就单主机先把时序跑通再加复杂度。写驱动时每次传输前检查总线忙标志必要时加入启动前的超时重试我从那之后就没再遇到过一上电就卡死的情况。4. SPI 考点全拆解四线高速全双工的优雅和陷阱4.1 物理层与基本拓扑SPI 的物理层比 I2C 好懂因为它把同步要素拆得很清楚主机输出时钟 SCLK主机输出数据线 MOSIMaster Out Slave In从机输出数据线 MISOMaster In Slave Out每个从机还有一条片选线 SS/CS低电平有效。典型拓扑是一主多从从机不共享片选主机几条 CS 线拉出来即可也可以把从机串成菊花链前一个的 MISO 接到后一个的 MOSI减少主机引脚但层级多、延迟大用得少。因为没有地址概念SPI 天然是“片选即点名”哪个从机的 CS 被拉低哪个就跟主机对话。从机在 CS 未被选中时MISO 一般处于高阻态避免多个从机同时驱动数据线相互打架。面试题“为什么 SPI 从机的 MISO 要求高阻输出”这是标准答案。SPI 是全双工主机发一个 bit 的同时就能收到从机一个 bit。这个特性经常出成一个心机题“主机发出一个字节的同时收到了什么”答案是同时收到从机的一个字节数据交换是同步双向的。4.2 CPOL、CPHA 与四种模式SPI 最容易把人绕晕的就是四种工作模式核心是 CPOL时钟极性和 CPHA时钟相位。CPOL 决定空闲时 SCLK 的电平CPOL0 时空闲低CPOL1 时空闲高CPHA 决定数据采样点是第一个跳变沿还是第二个跳变沿CPHA0 时在第一个边沿采样CPHA1 时在第二个边沿采样。组合起来就是模式0: CPOL0, CPHA0 空闲低第一个边沿(上升沿)采样 模式1: CPOL0, CPHA1 空闲低第二个边沿(下降沿)采样 模式2: CPOL1, CPHA0 空闲高第一个边沿(下降沿)采样 模式3: CPOL1, CPHA1 空闲高第二个边沿(上升沿)采样实际项目里模式 0 用得最多大多数 Flash、SD 卡、传感器默认就是模式 0/模式 3 中之一。面试里常给一张时序图让你判断这是模式几判断方法就是先看空闲电平对应 CPOL再看数据在哪条边沿被采样对应 CPHA先定极性再数边沿不会有错。最坑的地方是主从模式配置不一致主从两边一个用模式 0 一个用模式 3数据总是错位抓波形又看不出来明显异常因为边沿都对上了只是采样的时刻不对。我调 WiFi 模块 SPI 通信时遇到过这个问题最后是对着芯片手册的时序图逐个边沿核对才发现采样沿差了一个相位。4.3 数据传输与速率上限SPI 没有 ACK 机制主从之间没有任何应答信号。主机发完一帧根本不知道从机是否成功接收所有可靠性都得靠协议上层自己解决比如帧尾加校验、应答字段、超时重传。答这道题时顺便把“为什么 SPI 比 I2C 简单但容错弱”讲清楚面试官会认可你对协议本质的理解。SPI 速率上限由从机支持能力、PCB 走线、负载电容和主机时钟源共同决定。上百兆比特率的 SPI 在板级短走线场景并不罕见很多存储芯片的读取时钟可以跑到几十兆甚至上百兆。不过一提高速波形质量就成了问题反射、串扰、边沿变缓都会在高速抓拍时变成随机误码。所以高速 SPI 设计时要注意串阻匹配、少打过孔、从机尽量靠近主机调试时先降低分频把通信跑通再逐步提高时钟找极限。4.4 高频考点清单简述 SPI 四种模式能画出时序图最好。SPI 和 I2C 的时钟线有什么区别I2C 时钟从机也能拉低时钟拉伸SPI 时钟完全由主机掌控。SPI 为什么不用仲裁单主机结构由片选决定通信对象多个从机之间通过片选互斥没有电平竞争的仲裁需求。从机如何知道什么时候发送数据靠 CS 拉低和时钟边沿在使能期每个边沿同步移位。如果从机 RX 没有及时读数据会怎样FIFO 溢出导致丢数据SPI 没有流控机制驱动层必须保证时序。4.5 调试经验波形对却读不对先查哪几处SPI 调试第一步永远是抓 SCLK 和 CS确认时钟确实在翻转、片选确实拉低。第二步抓一个完整字节数边沿核对模式号。第三步看 MISO如果 MISO 一直是高或一直是低多半是片选没选对或从机没上电如果波形有翻转但数值不对优先怀疑线序、复用引脚配置、以及从机进入掉电模式。代码层面还有一个容易忽略的坑很多 MCU 的 SPI 发送接口“发送完成”标志指的是移位寄存器发完不代表从机已经采样完毕如果紧接着切换片选或模式可能在最后一个边沿上少了一个时钟周期的“尾巴”最后一字节丢位。稳妥做法是确认 SPI 忙标志清掉后再操作片选。5. 三协议横向对比与选型答题逻辑5.1 一张表看清性格差异面试到了对比题先别急着背参数我把它们放到一张表里作为答题的骨架维度UARTI2CSPI时钟来源无双方自定波特率主机时钟从机可拉伸主机时钟典型线数2~4TX/RX/流控2SDA/SCL3~4SCLK/MOSI/MISO/CS双工模式全双工典型半双工全双工多设备能力点对点多主多从需地址一主多从片选区分应答机制无内建 ACK每字节 ACK无速率范围低到中低到中默认 100k/400k 级别可拉很高抗干扰/复杂度中等开漏弱上拉实现复杂实现简单信号质量要求高5.2 面试选型题的三个切入角度如果面试官问“三个协议你怎么选”我的答题思路永远是先抛约束条件再讲协议特性匹配分三层展开第一层看速率需求。传感器读数每秒就更新几十次I2C 足够音频流、刷屏这种连续大批量数据SPI 更合适远程低速透传和数据记录就得靠 UART 转出到 RS-485 等物理层。第二层看拓扑结构。多设备且允许半双工I2C 只用两根线就能串一长串芯片省引脚优势明显设备少但要求双向同时传SPI 结构简洁性能好严格点对点、对实时性不敏感的老式模块UART 通用性和生态最好。第三层看可靠性和流控细节。I2C 有 ACK 和时钟拉伸天然能做慢速设备的流控SPI 没这些适合主从都能保证时序的场景UART 需要收发双方预先协商简单但协议层错误检测要靠自己加。答题时能把这三个层次说清楚比单纯报参数更能体现工程判断力。6. 面试实战高频题速查与避坑经验6.1 高频题速查表我整理了一张自用的速查表按“问题—答点—展开方向”列出来平时复习按这个过一遍效率较高高频问题核心答点加分展开方向UART 和 I2C 区别是什么一异步一同步一线对一数据一总线结合波特率误差与时钟拉伸展开I2C 数据线为什么要上拉开漏线与结构外部高电平来源上拉阻值对上升时间的影响什么是重复起始避免总线释放的二次起始结合 EEPROM 随机读流程讲什么是时钟拉伸从机拉低 SCL 暂停主机控制器超时要开否则总线卡死仲裁怎么发生多主机同时发SDA 电平角逐与 CSMA 机制对比强调无损仲裁SPI 模式怎么确定先看空闲电平再看采样沿用示波器抓波形实测最靠谱SPI 为什么不带 ACK协议简单、速率优先上层自定义校验与重传三个协议怎么选速率、拓扑、可靠性和引脚成本综合权衡结合具体器件举例6.2 独家避坑清单最后分享几个我在面试和技术支持里反复见到的坑提前避掉能少走一周弯路。写 I2C 驱动时起始条件一定不能让主机同时拉低 SDA 和 SCL标准是先 SDA 后 SCL有些控制器库函数封装得不好直接造成非法起始从机不认。I2C 读多字节时倒数第二个字节之后就该准备 NACK 语义等最后一个字节再回 NACK顺序反了会多收数据。UART 板间通信一定要共地飞线调试时两根信号线一根电源线一根地线是基本功板间电平参考点不同波形上看起来是好的数据就是乱。SPI 高速模式下如果发现偶发误码先在 SCLK 上串一个几十欧姆的电阻别一上来就调分频或改模式往往就是反射在作怪。所有串口打印调试信息务必加缓冲区满保护和阻塞发送标志判断DMA 模式下调用发送 API 后不是立刻完成的提前关串口会截断尾巴。面试被问到“你调过最棘手的通信问题”时别只讲现象把“抓到波形—对手册—怀疑时序—修改—验证”这套完整 debug 路径说出来比背十个协议概念都有说服力。我个人在实际干活里最大的体会是协议这东西背十遍不如拿逻辑分析仪抓一次真实波形。UART 的起始位跳变、I2C 的 ACK 脉冲、SPI 的边沿采样每一个细节都在波形上写得很明白。面试前如果有条件拿一块开发板把这三个协议各写一遍收发程序再故意制造波特率不匹配、SPI 模式错位、I2C 无上拉这三种故障看波形比什么速成资料都管用。考试过了之后这些波形记忆还会在真正的项目调试中继续帮你省时间。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑