三菱FX5U系列PLC(FX5U-32M/64M/80M)是三菱电机面向中端市场的主力机型,在国内制造业特别是长三角、珠三角的中小型设备厂商中应用广泛。围绕"三菱PLC上位机通讯开发"这一高频需求,本文系统讲解MC协议、SLMP协议、MX Component三种通讯方式的原理、对比和代码实现,结合赢式科技16年三菱PLC项目经验,给出FX5U上位机开发的完整方案。
一、三菱PLC上位机通讯的3种方式对比
三菱PLC的上位机通讯方式相对西门子要复杂一些,主要因为三菱的协议体系经历了多代演进:
| 方式 | 协议类型 | 授权 | 性能 | 适用场景 |
|---|---|---|---|---|
| MC协议(MELSEC) | 三菱专有 | 免费 | 高 | 老旧FX系列、Q系列 |
| SLMP协议 | MC协议现代化版 | 免费 | 高 | FX5U、iQ-R、iQ-F新机型 |
| MX Component | ActiveX组件 | 需购买 | 中 | 快速原型、Windows单机 |
| OPC Server | 标准化 | 需购买 | 中 | MES对接、多品牌 |
| Modbus TCP | 通用标准 | 免费 | 中 | 跨品牌混合采集 |
核心结论:FX5U优先用SLMP协议(免费、性能高、官方推荐);老旧FX3U改造用MC协议;快速原型可用MX Component(但有授权费);跨品牌多设备场景用Modbus TCP或OPC Server。
二、SLMP协议深度解析:报文结构与地址映射
SLMP(Seamless Message Protocol)是三菱推出的现代化通讯协议,支持二进制和ASCII两种帧格式。二进制格式效率更高,是FX5U的首选。
2.1 SLMP二进制帧结构
┌──────────────────────────────────────────────────────┐
│ SLMP Request Frame (二进制格式) │
├──────────────────────────────────────────────────────┤
│ 子头部 (11 bytes) │
│ ┌──────┬──────┬──────┬──────┬──────┬──────┬──────┐ │
│ │帧类型│保留 │网络号 │PC号 │请求目 │请求目 │请求数 │ │
│ │1B │1B │1B │1B │标模块 │标模块 │据长度 │ │
│ │ │ │(0x00)│(0xFF)│号2B │号2B │2B │ │
│ │ │ │ │ │(0x0300=自身)│ │ │
│ └──────┴──────┴──────┴──────┴──────┴──────┴──────┘ │
├──────────────────────────────────────────────────────┤
│ 数据部 (Variable) │
│ ┌──────────┬──────────┬──────────┬────────────────┐ │
│ │指令 │子指令 │设备代码 │设备地址 │ │
│ │2B │2B │1B (如*D*)│3B (起始地址) │ │
│ └──────────┴──────────┴──────────┴────────────────┘ │
│ ┌─────────────────────┐ │
│ │设备点数 2B │ │
│ └─────────────────────┘ │
└──────────────────────────────────────────────────────┘
示例:读取D100开始的4个Word (指令0x0401=随机读取, 子指令0x0000)
请求帧: 50 00 00 FF FF 03 00 0C 00 01 04 00 00 2A 00 00 64 00 00 04 00
│类型│保│网│PC│模块号 │长度=12│指│子│码│地址 │点数│
│ │留│号│号│ │ │令 │令│*D*│100=0x64│4 │
响应帧: D0 00 00 FF FF 03 00 0A 00 00 00 00 08 00 00 64 00 C8 00 32 00 01
│类型=响应│... │长度=10│结束码=0│字节数=8│4个Word数据 │
SLMP协议的核心难点是地址计算。三菱PLC的设备地址有D(数据寄存器)、M(内部继电器)、X(输入)、Y(输出)、T(定时器)、C(计数器)等多种,每种地址在SLMP帧中的编码方式不同。
2.2 三菱PLC设备代码与地址映射表
| 设备类型 | 代码(ASCII) | 代码(二进制) | FX5U地址范围 | 典型用途 |
|---|---|---|---|---|
| D 数据寄存器 | *D* | 0xA8 | D0-D7999 | 数值存储 |
| M 内部继电器 | *M* | 0x90 | M0-M9999 | 中间状态 |
| X 输入 | *X* | 0x9C | X0-X377 | 外部输入 |
| Y 输出 | *Y* | 0x9D | Y0-Y377 | 外部输出 |
| T 定时器当前值 | *TN* | 0xC2 | T0-T511 | 定时器 |
| C 计数器当前值 | *CN* | 0xC0 | C0-C511 | 计数器 |
| R 文件寄存器 | *R* | 0xAF | R0-R32767 | 大容量数据 |
| Z 索引寄存器 | *Z* | 0xCC | Z0-Z23 | 变址寻址 |
关键陷阱:M、X、Y这些位元件,在SLMP批量读取时按16位一组处理(即读取M0-M15共16位需要1个Word)。读取M0-M7会返回包含M0-M15的整个Word,需要上位机按位提取。这是初学者最容易出错的地方。
三、C#实现SLMP协议:完整代码示例
以下是赢式科技项目代码中实际使用的SLMP驱动类(简化版):
using System.Net.Sockets;
using System.Text;
public class MitsubishiSlmpDriver : IDisposable
{
private TcpClient _client;
private NetworkStream _stream;
private readonly string _ip;
private readonly int _port = 4999; // FX5U SLMP默认端口
private readonly byte _networkNo = 0x00;
private readonly byte _pcNo = 0xFF;
private readonly byte[] _moduleNo = { 0x03, 0x00 }; // 自身模块
// SLMP指令常量
private static readonly byte[] CMD_READ = { 0x01, 0x04 }; // 随机读取
private static readonly byte[] CMD_WRITE = { 0x01, 0x14 }; // 随机写入
private static readonly byte[] CMD_READ_BLOCK = { 0x00, 0x04 }; // 块读取
public bool IsConnected => _client?.Connected ?? false;
public MitsubishiSlmpDriver(string ip, int port = 4999)
{
_ip = ip;
_port = port;
}
public async Task ConnectAsync()
{
try
{
_client = new TcpClient();
await _client.ConnectAsync(_ip, _port);
_stream = _client.GetStream();
_stream.ReadTimeout = 3000;
_stream.WriteTimeout = 3000;
return true;
}
catch { return false; }
}
/// <summary>
/// 批量读取D寄存器 (Word)
/// </summary>
public async Task<ushort[]> ReadDRegistersAsync(int startAddr, int count)
{
if (count > 960) throw new ArgumentException("单次读取不能超过960个Word");
// 构建SLMP请求帧
using var ms = new MemoryStream();
// 子头部
ms.WriteByte(0x50); // 帧类型: 请求
ms.WriteByte(0x00); // 保留
ms.WriteByte(_networkNo);
ms.WriteByte(_pcNo);
ms.Write(_moduleNo, 0, 2);
ms.Write(_moduleNo, 0, 2); // 请求目标模块号 (重复字段)
// 数据部长度 (后续数据字节数)
int dataLength = 12; // 指令2 + 子指令2 + 设备代码1 + 地址3 + 点数2 + 2 (Word/Byte单位)
byte[] lenBytes = BitConverter.GetBytes((ushort)dataLength);
ms.Write(lenBytes, 0, 2);
// 监视定时器 (2字节, 单位250ms)
ms.Write(BitConverter.GetBytes((ushort)0x0010), 0, 2);
// 指令 + 子指令
ms.Write(CMD_READ_BLOCK, 0, 2);
ms.Write(new byte[] { 0x00, 0x00 }, 0, 2); // 子指令: 0x0000
// 设备代码: D寄存器 = 0xA8
ms.WriteByte(0xA8);
// 设备地址 (3字节, 16进制)
ms.WriteByte((byte)(startAddr & 0xFF));
ms.WriteByte((byte)((startAddr >> 8) & 0xFF));
ms.WriteByte((byte)((startAddr >> 16) & 0xFF));
// 设备点数
ms.Write(BitConverter.GetBytes((ushort)count), 0, 2);
byte[] request = ms.ToArray();
await _stream.WriteAsync(request, 0, request.Length);
// 读取响应
byte[] respHeader = new byte[15];
await _stream.ReadAsync(respHeader, 0, 15);
// 检查结束码 (响应帧偏移9-10)
ushort endCode = BitConverter.ToUInt16(respHeader, 9);
if (endCode != 0)
throw new Exception($"SLMP读取失败, 结束码: 0x{endCode:X4}");
// 读取数据
byte[] data = new byte[count * 2];
await _stream.ReadAsync(data, 0, data.Length);
// 转换为ushort数组 (三菱为小端序, 与PC一致, 无需翻转)
ushort[] result = new ushort[count];
for (int i = 0; i < count; i++)
result[i] = BitConverter.ToUInt16(data, i * 2);
return result;
}
/// <summary>
/// 读取Float (32位, 占用2个Word)
/// </summary>
public async Task<float> ReadFloatAsync(int startAddr)
{
ushort[] words = await ReadDRegistersAsync(startAddr, 2);
byte[] bytes = new byte[4];
BitConverter.GetBytes(words[0]).CopyTo(bytes, 0);
BitConverter.GetBytes(words[1]).CopyTo(bytes, 2);
return BitConverter.ToSingle(bytes, 0);
}
public void Dispose()
{
_stream?.Dispose();
_client?.Dispose();
}
}
使用时需特别注意:三菱PLC的字节序为小端序(Little-Endian),与PC的x86架构一致,因此不需要像西门子那样翻转字节。但读取Float(32位浮点数)时,仍需注意Word顺序:三菱的Float占用2个连续Word,低字节在低地址,需要正确拼接。
四、FX5U侧配置:开启SLMP通讯的5个步骤
在三菱GX Works3中配置FX5U的SLMP通讯:
- 添加以太网端口:导航栏 → [参数] → [FX5UCPU] → [以太网端口],设置IP地址(如192.168.1.10)和子网掩码
- 启用SLMP通讯:在"外部设备配置" → [SLMP] → 勾选"允许SLMP通讯"
- 设置通讯参数:协议=TCP,端口=4999(可改),允许访问IP=0.0.0.0(全部允许)或指定IP段
- 配置设备访问权限:在"对象设备连接配置"中允许外部设备读取D、M等区域
- 下载参数并重启:保存工程 → 写入PLC → 重启FX5U使配置生效
配置完成后,用Ping命令确认网络可达,然后用SLMP测试工具(如三菱官方的MX Configurator或开源的SLMP Tester)验证通讯。
五、实测性能:FX5U SLMP采集基准测试
赢式科技在测试环境(i7-12700H上位机 + FX5U-32MT/ES + 千兆网络)对SLMP协议进行了基准测试:
| 测试项 | 结果 | 说明 |
|---|---|---|
| 单次连接建立耗时 | 3ms | TCP三次握手 |
| 读1个Word往返延迟 | 1.8ms | 含网络往返 |
| 读100个Word批量 | 2.5ms | 批量优化明显 |
| 读960个Word最大批量 | 4.2ms | 单次上限 |
| 写1个Word | 2.1ms | — |
| 写100个Word批量 | 3.0ms | — |
| 持续采集CPU占用 | 2% | 1ms周期 |
| 持续采集丢包率 | 0% | 10小时测试 |
性能结论:SLMP协议性能优异,单次960个Word批量读取仅需4.2ms,完全可以满足1ms级的实时采集需求。FX5U的SLMP实现比FX3U的MC协议性能提升约40%,是FX5U上位机通讯的推荐方案。
六、3种通讯方式实测对比
| 方案 | 100点位采集周期 | 开发难度 | 授权成本 | 跨平台 |
|---|---|---|---|---|
| SLMP协议 | 5ms | 中(需懂协议) | 免费 | 是 |
| MC协议 | 8ms | 中(协议较老) | 免费 | 是 |
| MX Component | 20ms | 低(拖拽即用) | 约5000元/套 | 仅Windows |
| Modbus TCP | 15ms | 低 | 免费 | 是 |
选型建议:①追求性能和长期可控性 → SLMP协议;②快速验证 → MX Component;③跨品牌混合采集 → Modbus TCP;④老旧FX3U改造 → MC协议。
七、赢式科技三菱PLC上位机开发服务
上海赢式信息科技有限公司2010年成立,16年专注三菱PLC上位机通讯开发与数据采集系统建设,累计交付3000+定制化项目,覆盖汽车零部件、纺织机械、包装设备、食品饮料、电子制造等行业。公司在苏州、无锡、济南、西安设有本地服务网点,承诺完整源码交付、1年免费维护、2小时电话响应、24小时现场到达。如果您有三菱PLC上位机通讯或数据采集项目需求,欢迎免费联系赢式科技获取需求评估与方案报价。
- 电话咨询:15001875806(工作日9:00-18:00)
- 在线咨询:点击免费咨询赢式科技工程师
- 相关服务:上位机系统定制开发 | 工业物联网开发