1. 为什么嵌入式面试总绕不开UART、I2C、SPI
如果你准备过嵌入式相关岗位的面试,应该会注意到一个现象:不管是大厂还是小公司,技术面环节几乎必问三大总线协议——UART、I2C、SPI。这仨家伙简直是嵌入式领域的“钉子户”,从STM32裸机开发到Linux驱动、从FPGA逻辑到RTOS应用,到处都是它们的身影。
我做了这么多年嵌入式开发,也面试过不少人,最大的感受是:很多候选人简历上写着“熟悉UART/I2C/SPI”,但一问到具体细节就露馅了。比如I2C的应答机制,一堆人说“从机要回ACK”,再追问“如果从机不回ACK,主机该怎么办”,就答不上来了。再比如SPI的四种模式是怎么对应CPOL和CPHA的,很多人背过又忘了,本质上没搞懂时序图。
这篇文章我就把这三个协议掰开揉碎了讲清楚,不仅说是什么,还把为什么、怎么用、面试怎么答都覆盖到。内容不会太学术,更多是从工程实践和面试官考察点的角度来拆解,保证你看完之后能举一反三,而不是死记硬背。
先说说为什么这三个协议这么重要。嵌入式系统的本质就是“处理器”和“外设”之间的数据交换,而UART、I2C、SPI恰好覆盖了三种最常见的通信场景:UART用于设备间点对点通信,I2C用于连接大量低速外设,SPI用于高速数据搬运。可以说,搞懂这三样,嵌入式开发的地基就打牢了一半。
另外,这三者在面试中的角色还不一样:UART侧重考察你对“异步通信”和“时序容错”的理解,I2C侧重“总线协议”和“多设备协同”的思想,SPI则更多考察“同步时钟”和“速率匹配”的工程细节。面试官通过这几个协议,基本能判断出一个候选人对底层硬件和程序设计的真实掌握程度。
接下来我先把三张“身份卡”亮出来,让不熟悉的人有个整体印象。
2. 三张协议“身份卡”:特性对比与选型逻辑
在嵌入式系统里挑通信协议,和生活中挑选交通工具有点像。UART像是一辆出租车,随时出发、点对点直达;I2C像是一辆公交车,一条线路上挂很多站,大家共用通道但速度不快;SPI则像是专线地铁,速度快、运力足,但线路和站点(引脚)都占得多。
2.1 三大协议的物理层与引脚对比
先看最基础的物理层差异:
| 特性 | UART | I2C | SPI |
|---|---|---|---|
| 引脚数 | 2(TX、RX),加上GND | 2(SCL、SDA),加上GND | 3+N(SCLK、MOSI、MISO,每设备1根CS) |
| 通信方式 | 异步 | 同步 | 同步 |
| 时钟来源 | 双方各自约定波特率 | 主机提供SCL时钟 | 主机提供SCLK时钟 |
| 多设备支持 | 点对点为主 | 多从机(地址寻址) | 多从机(片选寻址) |
| 速率典型值 | 9600bps ~ 几Mbps | 100KHz / 400KHz / 1MHz以上 | 几十MHz |
| 数据线方向 | 单工/半双工/全双工 | 半双工 | 全双工 |
| 突出特点 | 简单、通用、抗干扰 | 引脚少、可扩展性强 | 速度快、吞吐量大 |
从这个表里能看出很多信息。UART只有两根数据线,一根发送一根接收,理论上能做全双工——因为收发路径物理分离。但实际中很多应用并不需要同时收发,典型的例子是调试串口,基本全靠主机发、终端看,偶尔敲个命令。
I2C为什么能两根线挂一堆设备?关键在于“地址”。每个I2C从设备都有一个7位或10位地址,主机发起通信时先发地址帧,符合条件的从机才会响应对应的ACK。这就是公交车的逻辑——车来了,报站名,该下车的下车、该上车的上车,其他乘客继续坐着。
SPI的区别更明显:它给每个从机单独拉了一根CS片选信号,主机要和谁通信,就把对应的CS拉低,以此选中对方。这种“专线”方案没有寻址开销,数据想怎么发就怎么发,代价就是引脚多、连线复杂。
2.2 面试官问“你怎么选型”时的标准答法
我在面试中常问一个问题:“如果要在MCU上挂三个传感器,一个温度、一个气压、一个加速度计,你会分别用哪种总线?”这不是故意刁难,而是考察实际工程思维。
合理的思路是看三点:速率需求、引脚余量、器件本身支持什么接口。比如加速度计MPU6050同时支持I2C和SPI,如果你需要以1kHz频率读取姿态数据,I2C的400KHz模式可能勉强够,但SPI会把CPU占用率降得更低;如果你只是每秒读一次温度,I2C就绰绰有余了,没必要占用SPI那几条高速引脚。
反过来,如果要接SD卡、LCD屏、Flash这类数据量大的外设,SPI几乎是标配。SD卡SPI模式下能跑到20-25MHz,而I2C很难撑起这么高的吞吐量。
至于UART,它的价值在于“通用性”和“远距离”。和PC调试、蓝牙模块、GPS模块、4G模组通信,基本都是UART的活儿。它不需要时钟线,只要双方约定好波特率就能传,所以跨板、跨设备、跨距离都方便。很多传感器模组说自己支持“串口输出”,本质上就是把内部数据打包成协议帧,通过UART发出来。
还有个容易被忽略的点——功耗。I2C因为是开漏结构,电平翻转靠上拉电阻,功耗天然低;SPI推挽输出,高速翻转时功耗相对高;UART则取决于波特率和空闲电平策略。在电池供电的IoT设备上,I2C的地位就凸显出来了。
一句话总结选型逻辑:I2C求“省”,SPI求“快”,UART求“通”。把这个思路理清了,不管面试官怎么问都能往下掰扯。
3. UART详解:异步通信的可靠性从哪来
UART(Universal Asynchronous Receiver/Transmitter,通用异步收发器)算是三大协议里最容易上手、也最容易被轻视的一个。很多人觉得串口不就是发数据吗,没啥好研究的。但面试官问到UART时,往往会在“异步”两个字上做文章。
3.1 UART的帧格式与波特率计算
UART的一个完整数据帧长这样:
空闲高电平 | 起始位(0) | 数据位(D0~D7) | 校验位(可选) | 停止位(1) | 空闲高电平关键点是起始位是一个下降沿——从高电平跳变到低电平。接收端就是靠检测这个下降沿来“对表”的。因为UART没有时钟线,收发双方只能靠约定波特率来保持同步。波特率就是每秒传输多少个码元,常见的有9600、115200、460800等。
面试题里的经典考点是波特率误差计算。比如MCU外部晶振12MHz,你要产生115200波特率,通常会用一个分频计数器。STM32的USART通过USARTDIV分频得到,具体公式是:
TX/RX波特率 = fck / (16 × USARTDIV)假如fck是72MHz,要得到115200波特率,USARTDIV应该约等于39.06。如果你配置成39,实际波特率是72M / (16 × 39) = 115384,误差约0.16%,完全没问题。但如果你非要用一个很偏的频率源去产生某个波特率,误差超过2%,在高波特率下就可能出现乱码。
这个知识点在面试中的问法通常是:“如果我把系统时钟改了,串口波特率会怎么样?”如果你能说出“时钟变了波特率跟着变,需要重新配置分频器”,说明你是真懂UART依赖时钟这个本质。
3.2 校验位、流控和断帧处理的工程细节
UART常见配置是8-N-1,意思是8位数据、无校验、1位停止位。但有些场景要加校验位,比如工业现场总线里常用偶校验。校验位只能检测单比特错误,不能纠错,真正的可靠性还得靠协议层的帧校验——比如CRC或者累加和。
另一个容易在面试中翻车的是流控。硬件流控用RTS/CTS两根线,接收端缓冲区快满了就拉低CTS,让对端暂停发送。很多人以为装上流控线就万事大吉,却没想过一个细节:流控信号卡在协议栈的哪一层?如果底层驱动没把CTS的状态反馈给发送逻辑,光接物理线根本没用。软件流控XON/XOFF则是在数据流里插入特殊字符,但二进制数据里可能恰好出现这些字符,处理起来更麻烦。
工程中还常见一个“断帧”问题。UART是字节流传输,没有天然的“消息边界”,它只保证字节与字节之间的顺序,不保证一包数据的完整性。所以做串口协议时,要么用帧头+帧长+校验,要么用帧头+尾标志+超时判断。我在实际项目里常这样处理:
收数据 -> 状态机判定帧头 -> 收集到固定长度 -> 校验 -> 解析有的新手喜欢每收到一个字节就进一次中断,然后在中断里做复杂的协议解析,这是大忌。因为中断里做的事越多,主循环响应就越慢,还容易丢字节。正确做法是先用环形缓冲区把数据收下来,再在空闲时统一解析。面试官如果问“串口中断里能不能做耗时操作”,答案显然是不能。
3.3 UART的进阶考察:DMA、FIFO和波特率自适应
很多岗位JD里写着“熟悉DMA”,UART+DMA恰恰是高频考点。为什么要用DMA?假设你要通过串口发送一个512字节的日志,CPU逐字节往外写会卡在这一块很久;如果开了DMA,CPU只需要配置好源地址、目的地址和长度,就能让DMA自己搬运数据,搬运完触发中断通知CPU。接收方向同理,尤其是高波特率下,比如1Mbps意味着每秒125KB数据,如果全指望中断,CPU资源会被吃干榨净。
DMA模式下的常见坑也不少。比如STM32的HAL库,用DMA接收时要先开启UART_Receive_DMA,并且要注意接收完成的判定方式——是空闲中断(IDLE)还是接收一半中断(HT)。实际项目里我常用“空闲中断+DMA”来判断一帧接收完毕。因为DMA本身是不知道“一帧数据发完了”的,只有总线空闲下来那一下才是判断点。
还有一个进阶点是波特率自适应。有些设备对接时不知道对方波特率,比如手机通过USB转串口连接某个模块,用户可能手动选波特率。工程上有一种方案:先发0x55(01010101),让对端通过测量两次电平跳变的间隔,反推波特率。这在很多蓝牙模块上实际用过。面试提到时可以讲“同步字+脉宽测量”的思路,能加分不少。
4. I2C详解:一根SDA上的总线博弈
I2C(Inter-Integrated Circuit)由飞利浦在1982年发明,初衷是让电视机的各个芯片之间少一些PCB走线。几十年过去,它仍然是低速外设连接的王者。OLED屏、温湿度传感器、RTC时钟、EEPROM、电量计,十有八九都是I2C接口。
4.1 开漏结构与上拉电阻:为什么I2C不能像SPI那样推挽
I2C物理层最大的特征是开漏(Open-Drain)。SDA和SCL两根线都不能主动输出高电平,只能把线拉低,高电平全靠外部上拉电阻提供。这设计是故意的——为了支持多主机仲裁和总线占用检测。
开漏的好处之一是“线与”特性。任何一个设备拉低总线,这条线就变为低;只有所有设备都不拉低,总线才恢复高。I2C主机在发送数据时如果要检测冲突,就是利用这个特性:它一边往总线上写数据,一边读总线电平,如果写的是1却读到0,说明有其他设备正在占用总线。
面试经典题“I2C上拉电阻选多大”,很多人答“4.7K”,但不理解为什么。上拉电阻太小,功耗大而且拉低时电流大;太大,总线电容导致上升沿变缓,高速模式下信号失真。具体取值要看总线电容和通信速率——标准模式100KHz用4.7K~10K,快速模式400KHz用2.2K~4.7K,高速1MHz以上可能要用1K~2.2K。
小技巧:如果你调试I2C发现波形上升沿缓得像爬坡,先怀疑上拉电阻太大或总线电容太大(挂了太多设备)。可以用示波器看到明显的“圆角”,这就是RC充电曲线。
4.2 I2C时序详解:起始、停止、应答、数据有效性
把I2C的时序拆开看,总共就几个关键动作:
- 起始条件(START):SCL高电平期间,SDA由高变低
- 停止条件(STOP):SCL高电平期间,SDA由低变高
- 数据有效:SCL高电平期间,SDA上的数据必须保持稳定;SDA变化只允许在SCL低电平期间
- 应答(ACK):第9个时钟周期,接收方把SDA拉低;NACK时保持高电平
很多人刚学I2C,觉得“起始和停止条件”不就是SDA高低电平变化吗,有什么难。但你要是自己写过软件模拟I2C,就知道这里面的坑有多深。比如你在SCL高电平期间不小心碰了一下SDA,等于是意外产生了一个START或STOP条件,总线状态就乱套了。
数据有效性这个规则尤其重要。在读I2C波形图时,要先看SCL在哪半周期,再看SDA的值。SCL高电平读到的SDA才是有效数据,SCL低电平时SDA虽然也在变,但我们不采样。这就是I2C“同步”的含义——以SCL为节拍器。
再补一个容易被忽视的点:起始条件后必须紧跟器件地址+读写位。7位地址模式下,接下来是第8位,0表示写、1表示读。然后从机在第9个时钟周期返回ACK——注意,从机不在场的表现是不回ACK,主机在第9个时钟释放SDA后检测到高电平,就知道对面没人。
4.3 读流程、写流程与寄存器寻址:EEPROM实操案例
我以EEPROM为例讲一下I2C读写的标准流程。假设设备地址是0xA0(7位地址0x50左移一位加上读写位),现在要读地址0x10处的数据。
先写地址:
START -> 发送0xA0(写) -> 等ACK -> 发送寄存器地址0x10 -> 等ACK -> STOP再读数据:
START -> 发送0xA1(读) -> 等ACK -> 主机读数据 -> 主机发NACK -> STOP注意读的时候最后那个字节要回NACK,目的是告诉从机“不要再发了,我要停”。如果最后回的是ACK,从机会继续拉高总线准备发下一个字节。
上面说的是随机读(Random Read)。如果我们希望连续读多个字节,就把NACK放在最后一字节之前——前面全部回ACK,最后一个回NACK再发STOP。这就是顺序读(Sequential Read)。
真实的EEPROM芯片规格书上还会有些特殊时序,比如EEPROM写入时需要等待内部编程时间(典型5ms),期间芯片不响应;如果写太快,主机发的下一帧会得不到ACK,你必须等待或做写轮询。STM32的HAL库中有I2C_IsDeviceReady函数,专门用来轮询设备是否空闲。面试中如果你能提到“EEPROM写周期后需要等待内部完成”,面试官会认为你真有实际经验。
4.4 面试追问:总线仲裁、时钟拉伸、多主机
I2C最迷的设计是总线仲裁(Arbitration)。多个主机同时想占用总线时,谁先拉低SDA谁就获胜,败者自动退出,而且这个过程不需要额外引脚、不需要主调度器。逻辑上就是前面提过的“线与”特性:每个主机在发送数据时都在监控SDA,一旦发现写1读0,就知道冲突,立即停止。
时钟拉伸(Clock Stretching)也是I2C协议非常独特的机制:从机可以拉低SCL迫使主机暂停。从机处理速度跟不上时,会通过这种方式“叫停”主机。这是硬件行为,但很多软件开发者根本不关注,结果用逻辑分析仪抓波形时发现SCL突然多了一段低电平,还以为是bug。其实这是从机在正常行使“让总线等我”的权利。
MCU作为I2C主机跑HAL库时,如果遇到从机拉伸时钟,主机代码会一直等在标志位上。所以线上问题排查时要清楚:不是所有“卡在等待”都是死锁,有可能是从机忙。
5. SPI详解:一主多从的高速数据通道
SPI(Serial Peripheral Interface,串行外设接口)是摩托罗拉在80年代设计的,思路比I2C更简单粗暴——直接用时钟线对数据采样。它没有地址的概念,谁干活谁就把CS拉低;数据线分开发送和接收,所以天然全双工。Flash、SD卡、LCD屏、ADC芯片、传感器,都是SPI的高频用户。
5.1 SPI四种模式:CPOL和CPHA别死记硬背
SPI面试最常见的考题是:“SPI Mode 0/Mode 1/Mode 2/Mode 3分别是什么?”然后一堆人开始背诵CPOL=0 CPHA=0,但完全不知道这俩参数控制的是什么。
CPOL(Clock Polarity,时钟极性)决定空闲时SCLK是高还是低:
- CPOL=0:空闲低电平,第一个边沿是上升沿
- CPOL=1:空闲高电平,第一个边沿是下降沿
CPHA(Clock Phase,时钟相位)决定数据在哪个边沿被采样:
- CPHA=0:第一个边沿采样(前沿采样)
- CPHA=1:第二个边沿采样(后沿采样)
一组映射关系如下:
| SPI Mode | CPOL | CPHA | SCLK空闲电平 | 数据采样边沿 |
|---|---|---|---|---|
| Mode 0 | 0 | 0 | 低 | 上升沿(第一个边沿) |
| Mode 1 | 0 | 1 | 低 | 下降沿(第二个边沿) |
| Mode 2 | 1 | 0 | 高 | 下降沿(第一个边沿) |
| Mode 3 | 1 | 1 | 高 | 上升沿(第二个边沿) |
为什么不能死记?因为不同器件的SPI时序画法不同,有的以CPOL=0为基准画,有的无时钟空闲概念,真正靠谱的方法就是看器件数据手册上的时序图。比如W25Q64这颗Flash,手册里明确写着“Data In is always latched on the rising edge of CLK, Data Out on the falling edge”,对应着Mode 0或Mode 3都可以——前者在CPOL=0模式下上升沿采样,后者在CPOL=1模式下上升沿采样但空闲电平相反。搞懂原理后就能理解为什么有的芯片两个模式都能用了。
5.2 硬件片选与软件片选:看似无关其实很关键
SPI系统中CS(片选)信号的设计很容易被轻视,但这里踩坑的人特别多。硬件片选指MCU的GPIO控制器自动控制CS引脚,比如STM32的SPI硬件NSS在某些模式下是自动拉低拉高的;软件片选就是驱动里手动拉GPIO。
软件片选的好处是灵活——任意GPIO都能当CS用,数量不受SPI外设引脚限制。但坏处也很明显:要在每次传输前手动拉低CS,传输结束后拉高。如果中间产生了GPIO操作延迟,或者被高优先级中断打断,CS信号附近就可能出现毛刺或者时长不对,可能导致从机识别错误。
还有一类典型问题是“CS拉低后立刻读数据”。有些从机从CS拉低到能输出第一个字节,需要一定的准备时间;如果你在CS刚拉低就立刻发时钟,从机的数据根本没准备好,读回来全错。经验做法是在CS拉低之后加一个极短延时(纳秒到微秒级别,看从机手册),再启动SCLK。同理,传输结束后CS拉高的时机也不能太早——最后一笔数据还没被从机正确捕获,你就把CS放了,等于白传。
5.3 SPI的DMA与高吞吐量设计:以SD卡驱动为例
SD卡是SPI应用里最典型的“重量级”场景,因为它对时序要求严、一次传输的数据量大。在嵌入式里用SPI读SD卡,最忌讳的是逐字节读写。
我来算一笔账:SD卡扇区大小512字节,MMC/SD协议里读取一个扇区是写命令(6字节)、等R1响应、读若干个0xFF、读开始令牌、再读512字节数据加2字节CRC。如果不用DMA,CPU每读一个字节都要等一个SPI移位周期,大概几百纳秒到几微秒不等,累计起来一次扇区读取会消耗好几毫秒。而在4线SDIO模式下可能不到1毫秒,这差距在音频/视频流播放时相当致命。
虽然上面说的是SDIO,但SPI读SD卡同理——必须配合DMA飞一般地搬运数据。STM32的SPI+DMA能把512字节一次搬运完,CPU只需在两个DMA传输完成的间隙做数据处理。面试中如果聊到“为什么SPI要用DMA”,就可以顺手把SD卡读写的场景拿出来举例子。
DMA传输时还有个小坑:SPI接收DMA是持续接收的,只要发了时钟就有人给你数据。如果主机要读512字节,从机实际上会先发响应、再发数据,如果你把DMA长度配成512,那么响应也被当成数据收进去了。需要把第0字节单独收掉缓冲,或者多收几字节再丢弃前导。
5.4 SPI时钟速率匹配与信号完整性
SPI能跑到多快?很多MCU的SPI外设最高支持fPCLK/2,比如STM32F4的APB2时钟84MHz时,SPI最高42MHz。有些芯片甚至能到80MHz以上,比如W25Q128JV能支持133MHz(使用Quad SPI)。但是时钟速率上限不只是芯片标称的问题,还受PCB走线长度、走线电容、连接器质量影响。
我调试过一块板子,SPI跑40MHz时读Flash偶发失败,降到20MHz就好了。从波形看,40MHz时MISO线上出现了振铃,导致采样误判。处理方案不是一直降频,而是调整SPI的采样延迟(在STM32H7系列里有SAMP bit)或者加串联匹配电阻(典型22~33Ω,靠近发送端放)。
这个例子说明:SPI高速通信面试时会延伸出一个问题——“高速信号线怎么处理”,你可以从阻抗匹配、走线短、避免交叉、加地线隔离几个角度回答。虽然嵌入式面试很少深挖SI/PI(信号完整性/电源完整性),但把基本原理讲出来肯定是加分项。
6. 面试高频追问与避坑指南:从协议到项目的深度表达
前面讲了三个协议各自的技术细节,但面试时还有一类题目更考验综合能力:“这块外设为什么用I2C,怎么排查问题?”“三个协议优先级怎么排?”这类问题没有标准答案,但考察的是你是否真的做过项目。
6.1 典型追问:设备时序紊乱、波形异常怎么排查
搞嵌入式,不怕出bug,就怕不知道怎么查bug。如果I2C读传感器偶尔返回错误数据,第一步不是翻代码,而是用逻辑分析仪抓波形。逻辑分析仪能看到SDA高低的实际时刻、ACK有没有、波形有没有毛刺。
我自己的排查路径通常是这样:
- 先确认地址是否正确。I2C的7位地址、8位地址(左移后)很多人混着用。比如手册写0x68(7位),实际发送时要左移成0xD0(写)/0xD1(读)。用逻辑分析仪一看就知道是不是这里出了问题。
- 看ACK规律。如果主机每次发送寄存器地址后都收不到ACK,可能是器件地址错了,也可能是从机忙(比如EEPROM正在写内部)。
- 看SCL频率。如果SCL频率明显高于从机支持的上限,信号根本跟不上,数据会乱。实测I2C线上电容大时,400KHz模式可能只有200KHz的实际有效读取能力。
- 要是偶尔OK偶尔失败,优先怀疑上拉电阻太大导致上升沿慢。顺便检查总线上是否有设备地址冲突。
SPI排查同理,先看CS和SCLK时序关系。如果波形正常但数据不对,考虑Mode是否配错;如果偶尔读回来是0xFF,检查MISO上有没有上拉/下拉配置干扰了浮空输入。
6.2 “工装”测试与Cotex-M系列调试技巧
面试官偶尔会问“你在产线上怎么测通信的稳定性”。这时候聊“工装”会显得有经验。我见过最朴素的工装方案是:用一块STM32或者USB转串口工具,通过UART向待测板持续发指令,待测板回传结果,上位机统计误码率和响应时间。I2C和SPI的设备则在测试架上接出测试点,让数字IO自动扫描。
调试时,JTAG/SWD是神器,但用SPI/I2C驱动外设时别开中断打断关键时序。比如SPI的CS拉低之后到CS拉高之前这段临界区,如果有高优先级中断插入,你就可能在CS有效期间被“挤”出去,时序彻底乱套。一个常见做法是在关键SPI传输过程中暂时屏蔽可屏蔽中断(PRIMASK),或者把SPI传输函数放在临界区里。
6.3 从八股到项目:怎么把协议知识讲成项目经验
很多应届生背了一堆协议细节,但面试官让讲项目时就笼统一句“用I2C读了传感器”。差在哪?差在缺少“取舍”。
面试官真正想听的是你做过什么决策、踩过什么坑、怎么权衡的。举几个话术示例:
- 那种说法:我调了2天,发现UART偶发乱码,后来发现晶振负载电容配置不对,导致系统时钟偏差了1.2%。
- 加分说法:必须先把时钟树理清楚,如果APB2和外设时钟不同步,即使软件配置对了,实际波特率也会跑偏。所以我后来把所有串口的外设时钟单独拎出来核对分频系数。
- 那种说法:我用I2C挂了4个设备,加了一个5V的电平转换芯片,然后再也扫描不到设备。
- 加分说法:如果是电平转换侧的上拉电阻没接,或者方向控制脚没配成双向,挂不上去很正常。I2C需要的是双向电平转换,不是单向缓冲器。
这些细节写出来,比任何“精通”都更有说服力。
7. 写在最后:三个协议给你的面试底气
面试这东西,七分靠功底,三分靠表达。UART、I2C、SPI作为嵌入式面试的“三座大山”,其实考验的都不是背书能力,而是你对数据传输本质的理解。UART考验的是怎样在没有时钟的情况下保证同步,I2C考验的是怎样在少量引脚下管理多设备,SPI考验的是怎样在高速场景下保证数据准确。三个问题分别对应异步、多设备、高速,覆盖了嵌入式通信的绝大多数场景,所以才会被面试官反复翻牌。
我在实际项目中总结出的习惯是:拿到一个新的模组,先看它的数据手册,重点看接口时序图和寄存器描述,不要急于写代码。比如用OLED、用Flash、用RTC,很多问题在动手前就能通过读时序图提前避免。这不是高深的能力,就是多看几遍时序图和Frame Format的耐心。
准备面试也一样,把今天我讲的这些点吃透,再找几块实际硬件跑几个Demo,你会发现那些“面试速成宝典”上的问题,比如“I2C为什么要开漏”“SPI为什么需要片选”“UART为什么叫异步”,答案其实都在你的调试经验里长出来了。
最后分享一个面试小技巧:回答协议问题时,尽量把“为什么”和“用什么工具排查”带上。面试官从来不怕你懂太多,只怕你只会背定义。UART、I2C、SPI这三个老朋友,从今天开始,你不再是“会用”,而是真正“懂”了。