想象你住在一个叫“星火”的智慧社区。社区主任(主芯片)要通知全社区:查温度、开电表、播报消息。他手里有三套通讯工具:一套社区广播站,两根线通到所有居民楼,谁家有事先喊门牌号,被喊到的人回一句“收到”;一套电话总机,四根线直通各家,总机拨通谁、谁就接起电话,两边还能同时说话;还有一套保安对讲机,只有两个人用,没有总机也没人打拍子,全靠提前约好“说话语速”。这三套系统,就是芯片世界里最常用的三种低速串行总线——I2C、SPI、UART。社区主任选哪套工具,取决于要办什么事;嵌入式工程师选哪条总线,取决于外设要传多少数据、要接几个设备、手里有多少根引脚可用。这篇文章把三套系统并排拆开看,从“两根线怎么喊话”讲到“什么时候该用哪一套”。
搞懂 I2C/SPI/UART,你就拿到了读懂 AI 硬件世界的三把钥匙——无论传感器采集、屏幕显示还是串口调试,背后都是这三套通讯语言。对 AI 从业者来说,这是从“纯软件思维”迈向“软硬一体”的关键一步。
可视化演示
\u5c55\u793aI2C/SPI/UART\u603b\u7ebf\u62d3\u6251(master\u2192slaves\u8fde\u63a5)\u3001\u4fe1\u53f7\u65f6\u5e8f(SCL/SDA\u6ce2\u5f62+SCK/MOSI/MISO)\u3001\u534f\u8bae\u6027\u80fd\u5bf9\u6bd4(\u901f\u5ea6/\u7ebf\u6570/\u53cc\u5de5/\u8bbe\u5907\u6570\u96f7\u8fbe\u56fe)\uff0c\u5207\u6362\u6a21\u5f0f\u67e5\u770b\u3002
本节配有交互动效(进入视口后自动加载,约 3KB)。
I2C/SPI/UART \u603b\u7ebf\u62d3\u6251\u5bf9\u6bd4 I2C: 2\u7ebf\u3001\u591a\u4e3b\u673a\u3001\u534a\u53cc\u5de5\u3001127\u8bbe\u5907 SPI: 4\u7ebf\u3001\u4e3b\u4ece\u3001\u5168\u53cc\u5de5\u3001\u901f\u5ea6\u6700\u9ad8 SPI(50M) > UART(1M) > I2C(400K)
总线基础概念
星火社区无论装哪套通讯系统,都要先立几条基本规矩:一次说一个字还是一次说一排字?需不需要有人拿着节拍器打拍子?两个人能不能同时开口?语速用什么单位衡量?这些规矩看似像开会纪律,其实是总线通信最底层的地基。社区主任要是没想明白“串行还是并行”“同步还是异步”,后面选哪套系统都会踩坑。
在芯片世界里,总线就是一组共享的导线加上一套传输规约。按同时传输的位数分,有串行和并行:串行总线一根数据线一次只传 1 位,好比广播员一次只能吐一个字;并行总线用多根线同时传多位,好比一排播音员同时念一排字。并行看似快,但线多、成本高、线间干扰大,频率很难做高,所以现代板卡上短距离外设几乎全用串行总线。
按有没有时钟线分,总线又分同步和异步:同步总线有一根专用时钟线“打拍子”,收发每一步都踩在拍子上;异步总线没有拍子,双方靠事先约定的速率对齐。按收发方向分,有单工(只能一个方向说)、半双工(轮流说,如 I2C)、全双工(同时说和听,如 SPI 和 UART)。衡量速率有两个词:波特率表示每秒传多少个电平符号,比特率表示每秒传多少个比特;低速串行里一个符号通常就是一个比特,两者数值相等。
回到社区,广播站是一条线一个字地喊——串行;若嫌慢,让十个播音员同时各喊一句话,就得拉十根线,还要保证不串词——这就是并行的代价。主任把“规矩”想清楚后,三套工具的优劣就很好对比了。
- R——数据速率每秒在信道上实际传送的比特数,单位 bit/s,是衡量总线快慢的最终指标。
- f_clk——时钟频率时钟线每秒振动(打拍子)的次数,单位 Hz,相当于社区广播里喊话的节奏快慢。
- n——每拍位数每个时钟周期同时传送的比特数;串行时 n = 1,并行时 n 等于数据线宽度。
三总线横向对比
三套系统并排摆在社区办公室:广播站两根线,一根拍子一根内容,便宜但语速一般;电话总机四根线,专线直通,语速飞快但要为每户拉一根响铃线;对讲机两根线,没有拍子全靠嘴皮子,而且只能两个人用。工程师选总线,看的正是这三个指标:引脚数、速率上限、拓扑(能挂几个设备)。
先看 I2C(Inter-Integrated Circuit,芯片间总线):标准模式 100 kb/s、快速模式 400 kb/s、高速模式可达 3.4 Mb/s,靠 7 位地址区分设备,半双工。再看 SPI(Serial Peripheral Interface,串行外设接口):四根线全双工,速率由 SCK 时钟决定,常用几 MHz 到几十 MHz,每增加一个从设备就要多一根片选线。最后是 UART(Universal Asynchronous Receiver/Transmitter,通用异步收发器):只有 TX/RX 两根数据线,点对点连接,速率常用 9600~115200 b/s,也可以更高。
| 总线 | 信号线 | 速率典型/上限 | 拓扑 | 方向 |
| --- | --- | --- | --- | --- |
| I2C | 2(SCL/SDA) | 100k~3.4M b/s | 多设备(地址寻址) | 半双工 |
| SPI | 3+N(SCK/MOSI/MISO/CS) | 数 MHz~数十 MHz | 多设备(片选) | 全双工 |
| UART | 2(TX/RX) | 9600~数 M b/s | 点对点 | 全双工 |
一句话总结:广播站想快得升级设备(高速模式),电话总机天生带宽足,对讲机速度完全看两人嘴皮子(波特率约定)。三兄弟没有绝对好坏,只有合不合适。
- I2C 速率区间标准模式约定 100 kb/s,快速模式 400 kb/s,高速模式 3.4 Mb/s,从低到高分三档。
- SPI 速率上限SPI 没有协议规定的固定上限,频率由主设备 SCK 决定,实际受从设备最高时钟与 PCB 布线质量限制。
- UART 速率上限常见 115200 b/s,高性能串口芯片可到数 Mb/s,但异步无时钟的特性决定了它不适合超高速。
I2C两线寻址
广播站只有一根数据线,怎么让全社区都知道“这条消息是给谁的”?答案:喊门牌号。主任开口第一句就是“地址”,各户听到后比对自家编号,是我就应答,不是我就不吱声。I2C 干的事一模一样:它只有 SCL 和 SDA 两根线,SCL 是时钟线、由主设备产生,SDA 是双向数据线,靠 7 位设备地址点名。
主设备发起通信时,先发送起始条件,然后送出“7 位地址 + 1 位读写标志”。所有从设备都听得见这句话,但只有地址匹配的那一个,会在下一个时钟周期把 SDA 拉低——这个动作叫 ACK 应答,相当于住户回一句“收到”。主设备收到 ACK 后,才继续传数据字节;如果没人应答(NACK),说明地址写错或设备不在线,主设备应当停止传输。
所有从设备的 SDA/SCL 引脚都并联在同两根线上,所以 I2C 总线两端需要接上拉电阻,保证空闲时 SDA/SCL 为高电平。同一根总线上挂多少设备,取决于地址空间和总电容(设备引脚电容、布线电容会拖慢边沿);地址相同的两个设备绝不能共存,否则一喊门牌号两家同时应答,通信当场混乱。
门牌号用 7 位编码,最多 128 个编号,其中 16 个是“物业专用”——比如“全体住户请注意”的广播地址,普通住户真正能用的编号 112 个。地址是 I2C 的灵魂,也是它“两根线挂一堆设备”的底气。
- 地址位宽 7设备地址用 7 个二进制位表示,每位可取 0 或 1,这是 I2C 寻址的基础。
- 计算组合总数7 个 0/1 位共有 2 的 7 次方种组合,算出来正好 128。
- 扣除保留地址I2C 规范把 十六进制 0x00~0x07、0x78~0x7F 等 16 个地址留给广播呼叫、10 位寻址扩展等特殊用途,普通从设备可用 112 个。
I2C时序机制
广播站不是想喊就喊的,有严格的播报流程:拿起话筒宣布“开始播报”(起始条件)、说话内容要在拍子下保持清晰(数据有效性)、放下话筒宣布“播报结束”(停止条件)、中途不能有人抢话(时钟同步)。I2C 的时序就是这几条“播音纪律”。
起始条件与停止条件都由主设备产生,而且都看 SDA 在 SCL 高电平期间的跳变:SCL 为高时 SDA 从高变低 → 起始;SCL 为高时 SDA 从低变高 → 停止。SCL 高电平期间,SDA 上的数据必须保持稳定,不能变化;数据只允许在 SCL 低电平期间翻转。这就是“数据有效性”规则——拍子落下那一刻,内容必须是准的。
一个字节的传输占 8 个 SCL 时钟,第 9 个时钟是 ACK/NACK 位,所以 1 字节实际要 9 个时钟周期。I2C 有标准模式(100 kHz)、快速模式(400 kHz)、高速模式(3.4 MHz)之分,模式越高,对 PCB 布线和上拉电阻的要求越苛刻。标准模式下,一个时钟周期 10 µs,一字节(含 ACK)要 90 µs——这就是广播站“语速”的物理来源。
广播的节奏(SCL)由主任一手掌握,大家听着拍子一字一字确认;内容(SDA)必须在拍子落下时保持纹丝不动——谁也不能在敲锣那一瞬间抢着改口,否则听众听岔了,整段播报就废了。
- 时钟周期与频率互倒SCL 每秒振动多少次就是频率,每次振动多长就是周期,两者互为倒数关系。
- 每字节九个时钟8 位数据各占一拍,第 9 拍给从设备做 ACK 应答,所以一字节总耗时为 9 个时钟周期。
- 标准模式代入取 f_SCL = 100 kHz,则每拍 10 µs,每字节 90 µs;快速模式 400 kHz 时每拍 2.5 µs,每字节 22.5 µs。
SPI四线通信
电话总机系统登场:主任想找 3 号楼住户,总机先给那一户“响铃”——片选线 CS 拉低,只有那一家电话响,其他住户不受打扰。这就是 SPI 的巧妙之处:不用喊门牌号,直接拉专线。SPI 是主从架构,一主多从,四根线各司其职:MOSI 是主发从收的数据线,MISO 是从发主收的数据线,SCK 是主设备产生的时钟,CS 是片选线、低电平有效。
片选机制是 SPI 区分设备的根本:每个从设备独占一根 CS 线,主设备想跟谁说话,就把谁的 CS 拉低,其他从设备的 CS 保持高电平,直接“静音”。因此挂 N 个从设备,总共需要 N+3 根线(SCK + MOSI + MISO + N 根 CS)。这也是 SPI 引脚多、布线麻烦的原因——每加一个设备就得多拉一根线。
SPI 是全双工:一个 SCK 周期内,MOSI 和 MISO 同时各传 1 位,两边可以边说边听,谁也不用等谁。速度上 SPI 几乎没有协议开销——没有地址、没有 ACK,数据来了就传。SPI 还有 4 种时钟模式,由时钟极性 CPOL(空闲时时钟是高还是低)和时钟相位 CPHA(在上升沿还是下降沿采样)组合而来,主从双方必须使用同一种模式才能正确通信。
电话专线一旦接通,两边可以同时说和听,谁也不用等谁;每加一户“住户”,总机就得多拉一根响铃线——这就是 SPI 引脚多的由来。用引脚换速度,用专线换简单,是 SPI 的生存哲学。
- 全双工吞吐每个 SCK 周期 MOSI 与 MISO 各传 1 位,因此单方向数据率等于时钟频率,双向合计翻倍。
- 帧时间传 n 位数据需要 n 个 SCK 周期,周期数除以频率就是总耗时。
- 对比 I2C 开销I2C 每字节多付 1 个 ACK 时钟,SPI 完全没有协议开销,同样数据量下耗时更短。
UART异步串行
保安老张和门卫老李的对讲机,没有总机、没有拍子,两人唯一的约定是“说话语速”:每秒吐几个字。老张嘴快,老李就得调快接收节奏,不然一句话听成两句话。UART 正是这个道理:它是异步串行,收发双方之间没有时钟线,全靠约定波特率(baud rate,每秒传输的比特数)来对齐节奏。
UART 只有 TX(发送)和 RX(接收)两根数据线,外加一根公共地 GND,点对点连接,全双工。空闲时 TX/RX 保持高电平;发送方开口前先拉低一个位时间,这个低电平叫起始位,相当于喊一声“喂,我要开始了”;接着从低位到高位依次发送数据位(通常 8 位);最后发送停止位(高电平,1 或 2 位),相当于“我说完了”。接收方在自己的时钟下,检测到下降沿就开始按波特率逐位采样。
一帧 UART 数据的完整结构是:1 起始位 + 数据位 + 可选校验位 + 停止位。因为起始位和停止位都要占时间,所以波特率并不等于有效数据率。接收方在每个数据位的中间点采样,能容忍一定波特率误差,典型约 ±3%~5%;一帧位数越多,累积误差越大,所以双方波特率必须尽量一致。
两人约好“每秒 115 个字”,但真正有用的内容只占八成——因为每句话都要喊一嗓子“喂”(起始位)再收个尾“完毕”(停止位)。UART 看似浪费,却换来最简单的接线和最可靠的点对点通信。
- 帧位总数 F把起始位 S、数据位 D、校验位 P、停止位 E 加起来,就是一帧占用的总位数。
- 有效数据率 R_data波特率 B 是每秒传的总位数,只有 D/F 这一部分是真正的用户数据。
- 常用配置代入1 起始 + 8 数据 + 0 校验 + 1 停止 = 10 位,115200 波特下有效速率正好 92160 bit/s。
场景选型实践
社区采购通讯设备,广播站便宜省线但慢,电话总机贵但快,对讲机简单直接。选哪套,得看场景:给每户装烟感报警器(传感器)——数据量小、数量多,广播站 I2C 正合适;给大门装监控大屏(显示屏)——数据量大、要刷得快,电话总机 SPI 才能扛住;保安之间日常联络(调试日志)——对讲机 UART 简单可靠,够用就行。
嵌入式选型没有银弹,只有“够用就好”。传感器(温湿度、加速度、气压)数据量小、更新率低,用 I2C 两根线挂多个,轮询读取即可;显示屏(TFT-LCD、OLED)一帧几百 KB,必须用 SPI 高速刷新,否则画面卡成幻灯片;调试口用 UART 最省心,接一个 USB 转串口芯片就能在电脑上看 AI 模型的推理日志,是板卡调试的“生命线”。
选型还要算一笔时间账:先把设备的净数据量除以总线的有效速率(扣掉 ACK、起始位等开销),得到一次传输的耗时;再把它放进系统的实时性预算里,看能否在规定的周期内完成。此外还要盘点引脚预算:SPI 挂 5 个从设备要 8 根线,I2C 挂 5 个只要 2 根线;功耗敏感的场景,还要考虑总线上拉电阻和时钟频率带来的动态功耗。
装烟感报警器不用拉电话专线,广播喊一声就够;但监控大屏靠广播站那点语速,画面会卡成幻灯片。场景决定系统,系统决定总线——选型不是比谁参数高,而是比谁最合适。
- 需求速率 R_need设备每秒必须送达的净数据量,比如 5 秒读一次 16 字节传感器记录,需求速率就是 25.6 b/s 量级。
- 总线有效速率 R_eff扣除 ACK、起始位、停止位等协议开销后,总线真正搬运用户数据的速率。
- 选型判据需求速率 ≤ 有效速率,同时引脚数与设备数量都在预算内,这条总线就是可用的。
AI 应用场景
AIoT 多传感器数据采集(I2C 广播站)
阶段:数据采集与感知
解决的问题:边缘 AI 盒子要同时挂温湿度、气压、光照多个传感器,传统并行方案线多难布线,逐个用 UART 又占满引脚;I2C 两根线 + 地址区分,一根总线挂 5 个传感器,MCU 轮询时从设备 ACK 应答保证每次读写可靠,这不就是社区广播站“一根线路喊多家门牌”的威力。
具体案例:智慧大棚网关用 ESP32 的 I2C 接口挂 SHT30 温湿度、BMP280 气压、BH1750 光照三个传感器,每 5 秒读一轮,数据送入边缘端做异常检测推理,超阈值时通过 4G 上报。
SPI 屏显 AI 推理结果(SPI 电话总机)
阶段:结果呈现与人机交互
解决的问题:AI 推理结果要实时显示,I2C 刷新一屏 128×64 的 OLED 要上百毫秒,刷新率高一点的屏直接卡顿;SPI 用 4 MHz 时钟推 1.8 寸 TFT,一帧 320×240×2 字节约 150 KB,约 0.3 秒内完成刷新,画面流畅得多,全双工还能边传像素边读触摸状态。
具体案例:智能门锁的人脸识别模组把识别结果与框选坐标通过 SPI 发给屏幕,用户能实时看到自己脸上的人脸框和姓名标签。
UART 调试串口(UART 对讲机)
阶段:部署调试与性能分析
解决的问题:AI 模型部署到开发板后,一旦卡死或推理变慢很难定位;UART 只需 TX/RX 两根线加一个 USB 转串口芯片,就能把推理耗时、内存占用、报错信息打成日志流,是部署阶段成本最低的“生命线”。
具体案例:在 RK3588 上部署 YOLOv5,用 115200 波特率串口每帧打印前处理/推理/后处理三段耗时,定位到 NMS 后处理是瓶颈,优化后整体帧率提升 2 倍。
Python 演示
#!/usr/bin/env python3# -*- coding: utf-8 -*-"""模拟 I2C/SPI/UART 三种串行总线的传输并对比耗时""" class I2CBus: """I2C 总线模拟: 两线 + 地址寻址 + ACK 应答""" def __init__(self, freq_hz=100000): self.freq = freq_hz self.devices = {} def register(self, addr, name): self.devices[addr] = name def transfer(self, addr, data_bits): if addr not in self.devices: raise ValueError("无此地址设备: 0x%02X" % addr) data_bytes = (data_bits + 7) // 8 total_cycles = data_bits + data_bytes return total_cycles / self.freq def uart_time(baud, n_bytes, data_bits=8, stop_bits=1): """UART 模拟: 起始位 1 + 数据位 + 停止位""" bits_per_byte = 1 + data_bits + stop_bits return n_bytes * bits_per_byte / baud def spi_time(sck_hz, data_bits): """SPI 模拟: 每个 SCK 周期传 1 位, 全双工无开销""" return data_bits / sck_hz def main(): i2c = I2CBus(100000) # 标准模式 100kHz i2c.register(0x68, "MPU6050 陀螺仪") i2c.register(0x3C, "SSD1306 显示屏") payload = 16 * 8 # 16 字节 = 128 位 t_i2c = i2c.transfer(0x68, payload) * 1e3 t_spi = spi_time(4000000, payload) * 1e3 t_uart = uart_time(115200, 16) * 1e3 print("传输 16 字节数据耗时对比:") print(" I2C 100kHz : %8.3f ms" % t_i2c) print(" SPI 4MHz : %8.3f ms" % t_spi) print(" UART 115200 : %8.3f ms" % t_uart) t_i2c_screen = i2c.transfer(0x3C, payload) * 1e3 print("\n同一总线上再读一片 SSD1306 显示屏寄存区: %.3f ms" % t_i2c_screen) print("\nI2C 总线挂载设备:") for addr, name in i2c.devices.items(): print(" 地址 0x%02X -> %s" % (addr, name)) if __name__ == "__main__": main()
total_cycles = data_bits + data_bytesI2C 每传一字节都要多付 1 个 ACK 时钟,这里把 ACK 开销加进总周期数。return total_cycles / self.freq周期数除以时钟频率得到秒数,是本文“每字节 9 个时钟”公式的代码化。bits_per_byte = 1 + data_bits + stop_bitsUART 一帧 = 1 起始位 + 数据位 + 停止位,帧结构直接写进计算。return data_bits / sck_hzSPI 每个时钟传 1 位,没有任何协议开销,代码只有一行。i2c.register(0x68, "MPU6050 陀螺仪")用 7 位地址注册从设备,模拟 I2C 总线上的“门牌号挂户”。i2c.transfer(0x3C, payload)同一个 I2C 对象上访问另一个地址的设备,演示多设备共享总线的寻址能力。
常见误区
误区I2C 标准模式有 100 kHz,而 UART 动不动就 9600 波特率,所以 I2C 肯定比 UART 快。
正解这是只记典型值、不记上限的错觉。I2C 有 100k/400k/3.4M 三档,UART 也能跑到 1 Mb/s 甚至更高。真正比的是有效吞吐:I2C 每字节多付 1 个 ACK 时钟,UART 每帧付 2~3 位帧开销,谁快谁慢要看具体配置。就像广播站和対讲机,一个按档位限速,一个看嘴皮子,不能说广播站一定快。
为何常见:初学者容易拿“I2C 的 100kHz”和“UART 的 9600”这两个最常出现的数字直接比较,忽略了协议模式与器件上限。
误区SPI 没有地址概念,所以一条 SPI 总线只能带一个从设备,挂多个就只能换 I2C。
正解SPI 区分设备靠的不是地址,而是片选线 CS。每个从设备独占一根 CS,主设备把谁的 CS 拉低就跟谁通信,其他设备自动静音。挂 N 个从设备需要 N+3 根线,一样能带一堆外设。电话总机不用喊门牌号,谁的电话响谁接——这就是“片选”替代“寻址”的思路。
为何常见:把“没有地址”直接理解成“只能一对一”,忽略了片选这个同样高效的选择机制。
误区通信要同步就得有时钟线,UART 一定也有一根时钟线,总共三根线。
正解UART 是典型的异步串行总线,只有 TX/RX 两根数据线加一根公共地 GND,没有时钟线。它的同步完全靠双方约定相同的波特率,再靠起始位的下降沿对齐采样时刻。只要波特率误差在 ±3%~5% 以内,几十位的一帧数据就能正确接收。対讲机两个人没有节拍器,照样能对话——靠的是提前约好语速。
为何常见:把“同步”这个词狭义理解为“必须有专用的时钟线”,忽略了异步通信靠约定速率实现同步的方式。
误区I2C 两根线上接上拉电阻能通就行,1k、4.7k、10k 没区别。
正解上拉电阻直接影响边沿速率和功耗。阻值太小,灌电流大、功耗高;阻值太大,RC 充放电慢、上升沿变缓,高速模式下信号直接失真。工程惯例是 100 kHz 标准模式用 4.7kΩ,400 kHz 快速模式用 2.2kΩ,还要根据总线电容微调。广播站的“喇叭音量旋钮”拧错了,不是听不见就是炸耳朵。
为何常见:I2C 硬件电路看起来简单,容易让人忽略阻值对时序的实际影响,等到高速通信出错才回头查。
误区并行 8 根线同时传 8 位,串行一根线一次传 1 位,并行肯定快 8 倍。
正解并行线多,线间串扰和时钟偏移严重,频率很难做高;串行虽然一次 1 位,但频率可以做到几百 MHz 甚至 GHz,实际吞吐反而远超并行。SPI 串行跑 80 MHz 时,有效速率比很多老式 8 位并行接口还快。让一排人同时念一排字,听起来快,但谁快了半拍就会整排乱套,最后只能把整体节奏放慢。
为何常见:用“同时传多位”的直觉判断速度,忽略了信号完整性对频率上限的硬约束。
面试题
Q1. I2C 总线使用几根信号线完成通信?
- A.一根,数据时钟复用
- B.两根,时钟加数据线← 正确答案
- C.三根,加一根使能线
- D.四根,全双工收发线
答案:B。I2C 只有 SCL 时钟线和 SDA 数据线两根信号线,半双工工作。三根线不是 I2C 标配,四根线是 SPI 的特征。这就像社区广播站只需一根拍子线加一根内容线。
Q2. SPI 中片选信号 CS 的作用是什么?
- A.提供数据传输的时钟
- B.选择当前通信的从设备← 正确答案
- C.控制总线供电的开关
- D.校验每帧数据的正确
答案:B。CS 拉低表示选中某个从设备,相当于电话总机给指定住户响铃,只有被选中的设备响应时钟和收发数据。时钟由 SCK 提供,供电和校验都与 CS 无关。
Q3. UART 通信双方没有时钟线,靠什么保证收发同步?
- A.片选信号触发每一位同步
- B.数据包长度强制双方对齐
- C.预先约定相同的波特率← 正确答案
- D.主设备周期发送同步脉冲
答案:C。UART 是异步总线,双方按预先约定的相同波特率各自计时,再靠起始位的下降沿对齐采样点。片选是 SPI 的概念,长度对齐和同步脉冲都不是 UART 的机制。就像对讲机两人先约好语速,才能听懂对方。
Q4. 关于 I2C 的 ACK 应答机制,下列说法正确的是?
- A.从设备用拉低 SDA 表示应答← 正确答案
- B.应答发生在第九个时钟周期← 正确答案
- C.应答信号由主设备主动产生
- D.应答发生在第一个时钟周期
答案:AB。I2C 的 ACK 由被寻址的从设备产生:它把 SDA 拉低,且发生在第 9 个时钟周期(8 位数据之后)。主设备不主动产生应答信号,第一个时钟周期还在传地址或数据的最高位。这就像住户被喊到后回一句“收到”,回答者是住户而不是主任。
Q5. SPI 工作在全双工模式,其含义是?
- A.同一时刻只允许单向传输
- B.收发双方可同时传输数据← 正确答案
- C.数据与时钟必须分时复用
- D.数据只能由主设备一方发出
答案:B。全双工指主从双方可以同时发送和接收,一个 SCK 周期内 MOSI 和 MISO 各传 1 位,互不干扰。单向传输是单工,分时复用是半双工,只允许主设备发也违背了 MISO 存在的意义。就像电话接通后两边可以同时说话。
Q6. 采用 7 位地址的 I2C 总线,扣除保留地址后最多可挂载多少个不同设备?
- A.一百一十二个设备← 正确答案
- B.一百二十八个设备
- C.仅六十四个可用设备
- D.二百五十六个设备
答案:A。7 位地址共 2^7 = 128 个组合,其中 16 个被规范保留给广播、10 位寻址扩展等用途,普通从设备实际可用 128 - 16 = 112 个。128 是理论总数,256 需要 8 位地址,64 则是常见误解。
Q7. 波特率 115200 的 UART 传输 1 字节(1 起始位 + 8 数据位 + 1 停止位)大约需要多久?
- A.约零点零八七毫秒← 正确答案
- B.约零点八七零毫秒
- C.约一点零四二毫秒
- D.约八点七零零毫秒
答案:A。1 字节共 10 位,每位时间 = 1/115200 ≈ 8.68 µs,10 位约 86.8 µs ≈ 0.087 ms。选项 C 的 1.042 ms 是 9600 波特下的结果,B 和 D 是数量级错误。算清楚帧开销,才能准确估计串口日志的吞吐上限。
Q8. 下列哪些总线属于同步串行总线?
- A.I2C 依靠 SCL 时钟同步← 正确答案
- B.SPI 依靠 SCK 时钟同步← 正确答案
- C.UART 完全依赖波特率
- D.RS232 也属于同步总线
答案:AB。I2C 和 SPI 都有专用时钟线(SCL/SCK),收发双方踩着同一个时钟节拍,属于同步串行总线。UART 和 RS232 没有时钟线,靠约定波特率同步,属于异步串行总线。
Q9. 关于 SPI 的时钟极性 CPOL 与相位 CPHA,下列说法正确的是?
- A.CPOL 与 CPHA 组合成四种模式← 正确答案
- B.CPOL 决定数据位的个数
- C.CPHA 决定从设备的数量
- D.主从双方必须使用同一种模式
答案:A。CPOL 决定时钟空闲电平,CPHA 决定在哪个边沿采样数据,2×2 组合出 Mode 0~3 四种模式,主从双方必须配对使用同一模式。CPOL 不影响数据位数,CPHA 与从设备数量无关。D 的说法本身正确但不是“关于 CPOL/CPHA”的最佳答案,A 才是对两者本质最准确的描述。
Q10. 某项目需挂载 5 路温湿度传感器、刷新一块 SPI 屏并输出调试日志,合理的选型是?
- A.五路传感器用 I2C 挂载← 正确答案
- B.显示屏用 SPI 高速刷新← 正确答案
- C.调试日志走 UART 串口← 正确答案
- D.传感器全部用 UART 扩展
答案:ABC。5 路传感器数据量小、更新率低,I2C 两根线加地址即可全挂上;显示屏数据量大,SPI 高吞吐负责刷新;调试日志用 UART 两根线最省心。D 用 UART 扩展 5 路传感器需要 10 根线且占满串口资源,明显不划算。这正是“广播站挂烟感、电话总机带大屏、对讲机做联络”的选型思路。