[具身智能-588]:RS422、I2C、SPI 底层都是面向字节传输,都是主从模式,都可以 1 对多。他们各自如何区分从设备的? 如何在单字节基础上传输目标设备特定地址空间的?
📅 2026/7/21 5:42:19
👁️ 阅读次数
📝 编程学习
RS422、I2C、SPI 底层都是面向字节传输,都是主从模式,都可以 1 对多。他们各自如何区分从设备的? 如何在单字节基础上传输目标设备特定地址空间的?如何传输目标地址空间多个数据的?如何进行帧边界定位?
RS422、I2C、SPI 四维度完整对比
统一前提:三者底层均为逐字节、串行传输、主从架构、支持一主多从,但硬件拓扑、寻址机制、寄存器访问、帧分割完全不同。 覆盖 4 个核心问题:
- 如何区分总线上多个从设备?
- 如何指定访问从机内部寄存器 / 地址空间?
- 如何连续读写一片地址空间多字节数据?
- 如何识别一帧数据起止(帧边界定位)?
一、I2C(同步,SCL+SDA 两线)
1. 区分多从设备:帧内置 7 位硬件从地址
每一次传输开头先发「从设备地址字节」(7 位设备地址 + 1 位读写标记 R/W)。
- 总线所有从机同时接收字节,仅地址匹配的设备响应 ACK;地址不符直接忽略整段传输。
- 硬件原生支持一主多从,无需额外 GPIO;标准 7 位地址最多挂载 112 台外设。
2. 访问从机特定地址空间(寄存器)
I2C 无独立指令字节,地址偏移紧跟从机寻址字节之后发送。 读 / 写流程标准时序:
- 写寄存器:START → 从地址 + 写位 (0) → ACK →寄存器偏移地址→ ACK →写入数据→ STOP
- 读寄存器:START → 从地址 + 写位 (0) → ACK →寄存器偏移→ ACK → 重复 START → 从地址 + 读位 (1) → 读取数据 → NACK → STOP 底层裸接口(如 RDK i2cdev)需要手动分两次 write/read 实现 “先发寄存器地址再读写数据”。
3. 连续传输一片地址多字节数据
绝大多数 I2C 芯片支持地址自增:发送一次起始寄存器偏移后,持续收发多个字节,硬件自动将寄存器地址 + 1。
- 多字节写:从地址→寄存器首地址→data1→data2→data3…STOP
- 多字节读:先发寄存器偏移,重复 START 读,持续读取 N 个字节,主机每字节回复 ACK,读完最后一字节发 NACK 终止。
4. 帧边界定位(区分一段完整传输)
依靠专属时序信号分割帧,不靠电平、不靠空闲计时:
- START 起始信号:SCL 高时 SDA 由高拉低,代表新帧开始;
- STOP 停止信号:SCL 高时 SDA 由低拉高,代表本帧结束、释放总线;
- 中间用Repeated START实现同一设备下切换读写方向,不结束整段会话。 总线空闲 = SDA/SCL 均被上拉至高电平。
二、SPI(同步,SCK/MOSI/MISO/CS)
1. 区分多从设备:独立硬件 CS 片选引脚(无总线地址)
SPI 协议本身没有设备地址字段,靠硬件 GPIO 电平区分从机:
- 每个从设备独占一路 CS 信号线;
- 同一时刻仅拉低 1 路 CS,其余 CS 保持高;CS 高时从机 MISO 输出高阻,不干扰总线。 缺点:设备越多占用 GPIO 越多;本质不是总线并联拓扑,是多路分时点对点。
2. 访问从机特定地址空间(寄存器)
寄存器偏移封装在MOSI 首字节指令中(行业通用规范): 首字节 Bit7 为读写标志,低 7 位是寄存器地址:
- Bit7=1:读指令;Bit7=0:写指令。 例:读 0x12 寄存器 → 发送 0x80 | 0x12 = 0x92。
3. 连续传输一片地址多字节数据
芯片内置地址自增逻辑:发送一次首地址指令后,持续输出 N 组时钟脉冲,自动访问连续寄存器。
- 多字节写:CS 拉低 → 指令首地址 → data1 data2 data3… → CS 拉高
- 多字节读:CS 拉低 → 读指令 → N 个 Dummy 0x00 占位字节,同步接收 N 组寄存器数据 SPI 全双工,只读场景必须填充 dummy 字节产生时钟读取 MISO 数据。
4. 帧边界定位
完全依靠CS 片选电平划分帧,无 START/STOP 时序:
- CS 由高拉低 = 新帧传输开始;
- CS 全程保持低,持续输出 SCK 时钟,持续收发字节;
- CS 由低拉高 = 当前整帧传输结束; SCK 停止脉冲、CS 拉高后总线空闲。 时钟运行中严禁切换 CS,否则帧碎裂、数据错乱。
三、RS422(异步差分四线,上层承载 Modbus-RTU,工业标准)
底层物理层仅异步逐字节传输,无设备寻址、无寄存器概念;一主多从、寄存器读写、帧边界全部依赖上层 Modbus-RTU 协议实现。
1. 区分多从设备:帧首 1 字节「从站地址」(应用层寻址)
物理 RS422 四线本身无寻址机制,依靠 Modbus 帧第一个字节区分设备:
- 帧首 SlaveAddr (1~247);所有从机接收完整帧,仅匹配地址的从机应答; 硬件层面 RS422 原生点对点,实现一主多从必须限制同一时刻只有一台从机发送 TX(软件轮询管控 DE/RE 收发使能)。
2. 访问从机特定地址空间
Modbus 协议标准化四类地址空间,通过帧内两个字段指定:
- 功能码:区分操作类型(读线圈 / 读保持寄存器 / 写寄存器等);
- 起始偏移地址:2 字节,指定目标寄存器 / 开关量起始位置。 示例帧
01 03 0000 0001 840A01 = 从站 1;03 = 读保持寄存器;0000 = 寄存器起始地址 0。
3. 连续传输一片地址多字节数据
Modbus 帧内置读取长度字段:2 字节,声明本次连续读写多少个寄存器 / 开关量。
- 主机下发:起始地址 + 数量;
- 从机应答:1 字节数据长度 + 批量寄存器原始字节; 协议天然支持批量读写,无需硬件地址自增,纯软件协议定义。
4. 帧边界定位(Modbus-RTU 规则)
依靠总线空闲时序分割完整数据帧,无硬件电平 / 时序标记:
- 总线空闲时长 ≥ 3.5 个字符传输时间 → 判定上一帧结束,缓存清空;
- 持续收到字节、总线无长时间空闲 → 持续缓存拼接帧;
- 收到字节后等待≥3.5 字符静默,再校验 CRC16,合法则解析报文。 底层 RS422 物理层无任何帧分隔能力,全靠上层时序规则切割报文。
四、四维汇总对比表
表格
| 对比维度 | I2C | SPI | RS422(Modbus-RTU) |
|---|---|---|---|
| 多从设备区分 | 传输帧内置 7 位硬件从地址 | 独立 GPIO 硬件 CS 片选引脚 | 上层协议帧首 1 字节从站地址 |
| 指定从机内部地址空间 | 寻址字节后紧跟寄存器偏移 | 传输首字节封装读写指令 + 寄存器地址 | Modbus 功能码 + 2 字节起始偏移地址 |
| 连续多字节读写 | 硬件地址自增,单次会话连续收发 | 硬件地址自增,持续时钟脉冲批量传输 | 协议内置长度字段,批量读写标准化应答 |
| 帧边界定位 | 专用 START/STOP 时序信号分割 | CS 片选高低电平区分帧起止 | 总线 3.5 字符空闲时序切割报文 |
五、核心关键总结
- I2C:同步总线,协议硬件内置地址与时序帧标记,原生一主多从,底层自带寻址与帧分割;
- SPI:同步总线,无协议地址、无帧时序标记,靠硬件 CS 区分设备、划分帧,极简底层无上层协议;
- RS422:仅差分异步字节通道,物理层无寻址、无寄存器、无帧边界,所有多从、寄存器访问、帧分割逻辑全部由 Modbus 上层协议补充实现。
编程学习
技术分享
实战经验