[具身智能-588]:RS422、I2C、SPI 底层都是面向字节传输,都是主从模式,都可以 1 对多。他们各自如何区分从设备的? 如何在单字节基础上传输目标设备特定地址空间的?

RS422、I2C、SPI 底层都是面向字节传输,都是主从模式,都可以 1 对多。他们各自如何区分从设备的? 如何在单字节基础上传输目标设备特定地址空间的?如何传输目标地址空间多个数据的?如何进行帧边界定位?

RS422、I2C、SPI 四维度完整对比

统一前提:三者底层均为逐字节、串行传输主从架构、支持一主多从,但硬件拓扑、寻址机制、寄存器访问、帧分割完全不同。 覆盖 4 个核心问题:

  1. 如何区分总线上多个从设备?
  2. 如何指定访问从机内部寄存器 / 地址空间?
  3. 如何连续读写一片地址空间多字节数据
  4. 如何识别一帧数据起止(帧边界定位)?

一、I2C(同步,SCL+SDA 两线)

1. 区分多从设备:帧内置 7 位硬件从地址

每一次传输开头先发「从设备地址字节」(7 位设备地址 + 1 位读写标记 R/W)。

  • 总线所有从机同时接收字节,仅地址匹配的设备响应 ACK;地址不符直接忽略整段传输。
  • 硬件原生支持一主多从,无需额外 GPIO;标准 7 位地址最多挂载 112 台外设。

2. 访问从机特定地址空间(寄存器)

I2C 无独立指令字节,地址偏移紧跟从机寻址字节之后发送。 读 / 写流程标准时序:

  1. 写寄存器:START → 从地址 + 写位 (0) → ACK →寄存器偏移地址→ ACK →写入数据→ STOP
  2. 读寄存器:START → 从地址 + 写位 (0) → ACK →寄存器偏移→ ACK → 重复 START → 从地址 + 读位 (1) → 读取数据 → NACK → STOP 底层裸接口(如 RDK i2cdev)需要手动分两次 write/read 实现 “先发寄存器地址再读写数据”。

3. 连续传输一片地址多字节数据

绝大多数 I2C 芯片支持地址自增:发送一次起始寄存器偏移后,持续收发多个字节,硬件自动将寄存器地址 + 1。

  • 多字节:从地址→寄存器首地址→data1→data2→data3…STOP
  • 多字节:先发寄存器偏移,重复 START 读,持续读取 N 个字节,主机每字节回复 ACK,读完最后一字节发 NACK 终止。

4. 帧边界定位(区分一段完整传输)

依靠专属时序信号分割帧,不靠电平、不靠空闲计时:

  1. START 起始信号:SCL 高时 SDA 由高拉低,代表新帧开始;
  2. STOP 停止信号:SCL 高时 SDA 由低拉高,代表本帧结束、释放总线;
  3. 中间用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 组时钟脉冲,自动访问连续寄存器。

  1. 多字节写:CS 拉低 → 指令首地址 → data1 data2 data3… → CS 拉高
  2. 多字节读:CS 拉低 → 读指令 → N 个 Dummy 0x00 占位字节,同步接收 N 组寄存器数据 SPI 全双工,只读场景必须填充 dummy 字节产生时钟读取 MISO 数据。

4. 帧边界定位

完全依靠CS 片选电平划分帧,无 START/STOP 时序:

  1. CS 由高拉低 = 新帧传输开始;
  2. CS 全程保持低,持续输出 SCK 时钟,持续收发字节;
  3. CS 由低拉高 = 当前整帧传输结束; SCK 停止脉冲、CS 拉高后总线空闲。 时钟运行中严禁切换 CS,否则帧碎裂、数据错乱。

三、RS422(异步差分四线,上层承载 Modbus-RTU,工业标准)

底层物理层仅异步逐字节传输,无设备寻址、无寄存器概念;一主多从、寄存器读写、帧边界全部依赖上层 Modbus-RTU 协议实现

1. 区分多从设备:帧首 1 字节「从站地址」(应用层寻址)

物理 RS422 四线本身无寻址机制,依靠 Modbus 帧第一个字节区分设备:

  • 帧首 SlaveAddr (1~247);所有从机接收完整帧,仅匹配地址的从机应答; 硬件层面 RS422 原生点对点,实现一主多从必须限制同一时刻只有一台从机发送 TX(软件轮询管控 DE/RE 收发使能)。

2. 访问从机特定地址空间

Modbus 协议标准化四类地址空间,通过帧内两个字段指定:

  1. 功能码:区分操作类型(读线圈 / 读保持寄存器 / 写寄存器等);
  2. 起始偏移地址:2 字节,指定目标寄存器 / 开关量起始位置。 示例帧01 03 0000 0001 840A01 = 从站 1;03 = 读保持寄存器;0000 = 寄存器起始地址 0。

3. 连续传输一片地址多字节数据

Modbus 帧内置读取长度字段:2 字节,声明本次连续读写多少个寄存器 / 开关量。

  • 主机下发:起始地址 + 数量;
  • 从机应答:1 字节数据长度 + 批量寄存器原始字节; 协议天然支持批量读写,无需硬件地址自增,纯软件协议定义。

4. 帧边界定位(Modbus-RTU 规则)

依靠总线空闲时序分割完整数据帧,无硬件电平 / 时序标记:

  1. 总线空闲时长 ≥ 3.5 个字符传输时间 → 判定上一帧结束,缓存清空;
  2. 持续收到字节、总线无长时间空闲 → 持续缓存拼接帧;
  3. 收到字节后等待≥3.5 字符静默,再校验 CRC16,合法则解析报文。 底层 RS422 物理层无任何帧分隔能力,全靠上层时序规则切割报文。

四、四维汇总对比表

表格

对比维度I2CSPIRS422(Modbus-RTU)
多从设备区分传输帧内置 7 位硬件从地址独立 GPIO 硬件 CS 片选引脚上层协议帧首 1 字节从站地址
指定从机内部地址空间寻址字节后紧跟寄存器偏移传输首字节封装读写指令 + 寄存器地址Modbus 功能码 + 2 字节起始偏移地址
连续多字节读写硬件地址自增,单次会话连续收发硬件地址自增,持续时钟脉冲批量传输协议内置长度字段,批量读写标准化应答
帧边界定位专用 START/STOP 时序信号分割CS 片选高低电平区分帧起止总线 3.5 字符空闲时序切割报文

五、核心关键总结

  1. I2C:同步总线,协议硬件内置地址与时序帧标记,原生一主多从,底层自带寻址与帧分割;
  2. SPI:同步总线,无协议地址、无帧时序标记,靠硬件 CS 区分设备、划分帧,极简底层无上层协议;
  3. RS422:仅差分异步字节通道,物理层无寻址、无寄存器、无帧边界,所有多从、寄存器访问、帧分割逻辑全部由 Modbus 上层协议补充实现。