4. SECS-I数据帧结构:Block结构、Length字节、Header字节、Data字节、CheckSum计算
SECS-I 协议在 RS-232 串行链路上传输数据时,将上层 SECS-II 消息封装为固定格式的数据帧(Block)。理解数据帧的每个字段是进行物理层调试和故障排查的基础。本节将详细拆解 Block 结构,并逐一说明 Length、Header、Data 及 CheckSum 的计算与验证方法。
4.1 数据帧(Block)整体结构
一个完整的 SECS-I 数据帧由 4 个主要部分组成:Length 字节、Header 字节、Data 字节(可选)和 CheckSum 字节。其中 Header 固定为 10 个字节,Data 长度由 Length 字段决定,CheckSum 为 2 个字节。
4.2 Length 字节
Length 是数据帧的第一个字节,用于指示整个 Block 的总长度(包括 Length 字节本身)。其取值范围为 13 ~ 254(最小值 13 = 1 Length + 10 Header + 2 CheckSum,无 Data)。
| 场景 | Length 值 | Data 长度 | 说明 |
|---|---|---|---|
| 最小帧(无数据) | 13 | 0 | 仅包含 Length + Header + CheckSum |
| 典型帧 | 13 + N | N | N 为 Data 字节数(1 ≤ N ≤ 242) |
| 最大帧 | 254 | 242 | Data 填满剩余空间 |
4.3 Header 字节(10 字节)
Header 是数据帧的控制核心,固定 10 个字节,承载了 SECS-I 通信的关键参数。其结构如下表所示:
| 字节偏移 | 字段名称 | 长度 | 描述 |
|---|---|---|---|
| 0 | Device ID (High) | 1 Byte | 设备 ID 高字节(Bit 15 为 R-bit) |
| 1 | Device ID (Low) | 1 Byte | 设备 ID 低字节 |
| 2 | Message ID (High) | 1 Byte | 消息 ID 高字节 |
| 3 | Message ID (Low) | 1 Byte | 消息 ID 低字节 |
| 4 | Block Number (High) | 1 Byte | 块号高字节 |
| 5 | Block Number (Low) | 1 Byte | 块号低字节 |
| 6 | System Bytes (High) | 1 Byte | 系统字节高字节 |
| 7 | System Bytes (Mid-High) | 1 Byte | 系统字节中高字节 |
| 8 | System Bytes (Mid-Low) | 1 Byte | 系统字节中低字节 |
| 9 | System Bytes (Low) | 1 Byte | 系统字节低字节 |
4.4 Data 字节
Data 字节承载 SECS-II 消息的实际内容,其长度由 Length 字段减去 13 计算得出。Data 部分可以为空(长度为 0),此时 Block 仅用于传输控制信息(如分离请求)。
- 最大长度: 242 字节(当 Length=254 时)。
- 多块消息: 如果 SECS-II 消息超过 242 字节,必须拆分为多个 Block 传输,通过 Header 中的 Block Number 和 E-bit(结束位)进行重组。
- 数据内容: 直接透传 SECS-II 的原始字节流,不做任何转义或编码。
4.5 CheckSum 计算
CheckSum 用于验证数据帧在传输过程中是否发生错误。SECS-I 采用 16 位 CRC-CCITT 校验算法,覆盖从 Length 字节到 Data 最后一个字节的所有内容(不含 CheckSum 自身)。
算法参数:
- 多项式:
0x1021(x¹⁶ + x¹² + x⁵ + 1) - 初始值:
0xFFFF - 结果异或值:
0x0000(即直接输出 CRC 结果) - 输入输出反转:无反转
计算步骤:
- 将 Length、Header、Data 的所有字节按顺序拼接为一个字节数组。
- 以
0xFFFF为初始 CRC 寄存器值。 - 对每个字节,按 CRC-CCITT 标准逐位计算(左移、异或多项式)。
- 计算完成后,将 16 位 CRC 结果拆分为高字节和低字节,依次放入 CheckSum 字段。
验证方法: 接收方对收到的 Length + Header + Data 进行同样的 CRC 计算,将结果与收到的 CheckSum 比较。如果一致,则数据完整;否则丢弃该 Block 并请求重传。
4.6 完整数据帧示例
以下是一个完整的 SECS-I 数据帧十六进制示例,包含 Length、Header、Data 和 CheckSum:
// 示例:发送一条短消息(无 Data)
Length: 0x0D (13)
Header: 0x81 0x00 0x00 0x01 0x00 0x01 0x00 0x00 0x00 0x01
Data: (无)
CheckSum: 0x3A 0x5C
// 示例:发送一条带 4 字节 Data 的消息
Length: 0x11 (17)
Header: 0x81 0x00 0x00 0x02 0x00 0x01 0x00 0x00 0x00 0x02
Data: 0x01 0x02 0x03 0x04
CheckSum: 0x8F 0xE1
4.7 常见问题与排查
| 问题现象 | 可能原因 | 排查方法 |
|---|---|---|
| CheckSum 持续错误 | 波特率不匹配、字节丢失、电气噪声 | 检查串口参数,使用示波器观察信号质量 |
| Length 字段异常 | 帧头同步丢失、接收缓冲区溢出 | 增加超时重同步机制,检查流控制设置 |
| Header 解析失败 | Device ID 不匹配、消息 ID 冲突 | 核对通信双方配置,检查 System Bytes 唯一性 |
| 多块消息重组失败 | Block Number 乱序、E-bit 设置错误 | 检查 Block Number 连续性,确认最后一块 E-bit=1 |