逐字节阅读 3E 帧的报文结构(二进制/ASCII)
以三菱电机手册中的实例,逐字节解读 MC 协议(SLMP)3E 帧的请求报文与响应报文中每个字节的含义。也介绍小端序的陷阱、ASCII 的差异以及 iQ-R 用的子命令。
更新
3E 帧的请求报文大致分为 3 部分:发往哪台 PLC(目标)、后面还有多少字节(长度)、要做什么(命令与数据)。本文以手册中「按字单位读取 M100〜M131」的例子,从头到尾阅读一段二进制报文。
请求报文的内容
二进制 3E 帧的请求报文按以下顺序排列。数值为访问所连接的 PLC 本身时的值。
| 项目 | 字节数 | 值 | 报文中的字节 |
|---|---|---|---|
| 副帧头 | 2 | 3E 帧请求 | 50 00 |
| 网络编号 | 1 | 本站 | 00 |
| PC 编号(请求目标站号) | 1 | 本站 | FF |
| 请求目标模块 I/O 编号 | 2 | 03FF(本站 CPU) | FF 03 |
| 请求目标模块站号 | 1 | 无多点连接 | 00 |
| 请求数据长度 | 2 | 从监视定时器到末尾的字节数 | 例 0C 00 |
| 监视定时器 | 2 | 单位 250 ms | 例 10 00(4 秒) |
| 命令 | 2 | 批量读取为 0401 | 01 04 |
| 子命令 | 2 | 字单位为 0000 | 00 00 |
| 请求数据 | 可变 | 由各命令决定 |
访问本站时,4 个目标项目(从网络编号到请求目标模块站号)固定为 00 FF FF 03 00。也有例外,例如发往多 CPU 系统的 2 号机时 I/O 编号为 03E1,但入门时记住这组值就够了。
监视定时器是等待 PLC 处理完成的上限时间。设为 0000 则一直等待到处理结束。访问本站时,手册推荐 0001〜0028(0.25〜10 秒)。
阅读实际的报文
手册的设置示例中,以字单位读取 M100〜M131 共 32 点,即 2 个字。请求报文为以下 21 个字节:
50 00 副帧头 3E 请求00 网络编号 本站FF PC 编号 本站FF 03 I/O 编号 03FF00 站号 0C 00 请求数据长度 = 12 字节10 00 监视定时器 16 × 250 ms = 4 秒01 04 命令 0401 批量读取00 00 子命令 字单位64 00 00 起始软元件 10090 软元件代码 M02 00 点数 2 个字后半部分的请求数据(64 00 00 90 02 00)是批量读取命令的内容:
64 00 00:起始软元件编号。100 的十六进制为64,用 3 个字节表示90:软元件代码。M 为9002 00:点数,2 个字
请求数据长度 0C 00 为 12 字节:监视定时器(2)+命令(2)+子命令(2)+请求数据(6)=12。
二进制是低字节在前
最容易出错的是字节顺序。在二进制报文中,2 字节以上的数值从低字节开始发送(小端序)。
- 命令
0401发送为01 04 - I/O 编号
03FF发送为FF 03 - 软元件编号 100(十六进制
000064)发送为64 00 00
响应报文
PLC 的响应如下:
D0 00 副帧头 3E 响应00 网络编号 本站FF PC 编号 本站FF 03 I/O 编号 03FF00 站号 06 00 响应数据长度 = 6 字节00 00 结束代码 正常结束34 12 M100〜M115 1234H02 00 M116〜M131 0002H响应的副帧头为 D0 00,4 个目标项目返回与请求相同的值。
响应数据长度 06 00 是从结束代码到末尾的字节数:结束代码(2)+数据(4)=6。
结束代码 00 00 表示正常结束。非 0 时为错误,其读法见错误代码一文。
读取的数据 34 12 02 00 也是每个字低字节在前,因此 M100〜M115 为 1234,M116〜M131 为 0002。
ASCII 代码的情况
用 ASCII 代码发送同样的读取时,各项目转为十六进制字符串,从高位数字开始排列。
5000 副帧头 00 网络编号 FF PC 编号 03FF I/O 编号 00 站号 0018 请求数据长度 = 24 个字符0010 监视定时器 0401 命令 0000 子命令 M* 软元件代码 000100 起始软元件 保持十进制0002 点数 D000 副帧头 00 网络编号 FF PC 编号 03FF I/O 编号 00 站号 000C 响应数据长度 = 12 个字符0000 结束代码 1234 M100〜M115 0002 M116〜M131 区别有 3 点:
- 顺序相反:命令直接写成字符串
0401 - 长度加倍:1 字节的项目用 2 个字符,2 字节的项目用 4 个字符
- 软元件的写法不同:软元件代码用
M*这样的 2 个字符符号,软元件编号用000100这样的 6 位数表示。与二进制不同,M、D 等十进制软元件保持十进制书写
请求数据长度也按字符数计算:监视定时器(4 个字符)+其后(20 个字符)=24,因此为 0018。
ASCII 便于肉眼阅读,但数据量约为二进制的 2 倍。
软元件代码与子命令
软元件代码表示软元件的种类。常用的如下:
| 软元件 | 代码 | 软元件 | 代码 |
|---|---|---|---|
| X(输入) | 9C | D(数据寄存器) | A8 |
| Y(输出) | 9D | W(链接寄存器) | B4 |
| M(内部继电器) | 90 | R(文件寄存器) | AF |
| L(锁存继电器) | 92 | ZR(文件寄存器) | B0 |
| B(链接继电器) | A0 | TN(定时器当前值) | C2 |
| SM(特殊继电器) | 91 | SD(特殊寄存器) | A9 |
访问 MELSEC iQ-R 时,也可以把子命令设为 0002(字单位)或 0003(位单位)。这种形式下软元件编号为 4 字节,软元件代码为 2 字节(D 为 A8 00)。Q/L 系列用的 0000/0001 在 iQ-R 上也可作为兼容用途使用,但长定时器等 iQ-R 新增的软元件只能用 0002/0003 指定。
一次能读取的点数有上限
批量读取(0401)一次最多读取字单位 960 点。位单位在二进制下最多 7168 点,ASCII 下最多 3584 点。需要读取更多时,请拆分请求。
4E 帧只是在开头加了序列号
4E 帧就是把 3E 帧的副帧头部分扩展为 6 字节。
54 00 副帧头 4E 请求34 12 序列号 1234H(任意)00 00 固定值 … 之后与 3E 相同 请求中附加的序列号会原样出现在响应中。发送多个请求时,可以对应哪个响应属于哪个请求。响应的副帧头为 D4 00。
下一篇介绍结束代码非 0,也就是返回错误时的读法。
出处
- MELSEC 通信协议参考手册(日文版,SH-080003)p.39〜44, 附录 7 p.471〜474
- SLMP 参考手册(日文版,SH-080931)p.17〜28, 34〜38, 44