C# 与三菱 FX5U PLC 通过以太网基于 SLMP(Seamless Message Protocol)协议通讯,是工业自动化中实现上位机与 PLC 数据交互的常用方式。SLMP 是三菱专用协议,支持 TCP/UDP 传输,可实现对 PLC 软元件(如 D 寄存器、M 继电器、X/Y 输入输出等)的读写操作。以下是具体实现步骤和代码示例:
一、前期准备
1. 硬件与软件环境
2. PLC 侧设置(GX Works3)
二、SLMP 协议基础
SLMP 通讯通过发送特定格式的报文实现数据读写,核心是帧结构和命令码:
三、C# 实现 SLMP 通讯(TCP 模式)
1. 核心步骤
2. 代码示例(读写 D 寄存器)
csharp
using System;using System.Net.Sockets;using System.Text;namespace FX5U_SLMP_Communication{
class FX5UCommunicator
{
private TcpClient client;
private NetworkStream stream;
private string plcIp;
{
client = new TcpClient(plcIp, port);
stream = client.GetStream();
return true;
// 断开连接
public void Disconnect()
{
stream?.Close();
client?.Close();
}
// 读取D寄存器(示例:读D100开始的2个寄存器)
public ushort[] ReadDRegister(ushort startAddress, ushort count)
{
// 起始地址(D100 → 0x0064)
command[14] = (byte)(startAddress >> 8); // 高8位
command[15] = (byte)(startAddress & 0xFF); // 低8位
// 数量(2个寄存器 → 00 02)
command = command.Concat(new byte[] { 0x00, 0x02 }).ToArray();
try
{
// 发送命令
stream.Write(command, 0, command.Length);
// 接收响应(响应长度 = 报头4 + 状态2 + 数据长度2 + 数据n + 校验等,此处简化处理)
byte[] response = new byte[1024];
int bytesRead = stream.Read(response, 0, response.Length);
// 解析响应(假设成功,提取数据)
// 响应数据从第10字节开始,每个D寄存器占2字节(高低位互换)
ushort[] result = new ushort[count];
for (int i = 0; i < count; i++)
{
// 三菱数据为大端模式,需转换为小端
result[i] = (ushort)((response[10 + i * 2 + 1] << 8) | response[10 + i * 2]);
}
return result;
}
catch (Exception ex)
{
Console.WriteLine("读取失败:" + ex.Message);
return null;
}
}
// 写入D寄存器(示例:向D100写入1234,D101写入5678)
public bool WriteDRegister(ushort startAddress, ushort[] data)
{
if (!client.Connected || data == null) return false;
// 构造SLMP写命令报文
int dataLength = 2 + 2 + data.Length * 2; // 地址(2) + 数量(2) + 数据(n*2)
byte[] command = new byte[14 + dataLength];
// 报头
command[0] = 0x50;
command[1] = 0x00;
command[2] = 0x00;
command[3] = 0x00;
// 网络号、站号
command[4] = 0x00;
stream.Write(command, 0, command.Length);
// 接收响应,验证是否成功(响应第8-9字节为00 00表示成功)
byte[] response = new byte[1024];
int bytesRead = stream.Read(response, 0, response.Length);
return response[8] == 0x00 && response[9] == 0x00;
}
catch (Exception ex)
{
Console.WriteLine("写入失败:" + ex.Message);
return false;
// 测试代码
class Program
{
static void Main(string[] args)
{
FX5UCommunicator comm = new FX5UCommunicator("192.168.3.3");
if (comm.Connect())
{
Console.WriteLine("连接成功!");
// 读取D100-D101
ushort[] readData = comm.ReadDRegister(100, 2);
if (readData != null)
{
Console.WriteLine($"D100: {readData[0]}, D101: {readData[1]}");
}
// 写入D100=1234, D101=5678
bool writeSuccess = comm.WriteDRegister(100, new ushort[] { 1234, 5678 });
Console.WriteLine("写入结果:" + (writeSuccess ? "成功" : "失败"));
comm.Disconnect();
}
Console.ReadKey();
}
}}四、关键说明
五、常见问题
通过上述方法,C# 可稳定与 FX5U 通过 SLMP 协议通讯,实现工业数据采集与控制逻辑。


