返回主站|会员中心|保存桌面

尼得科(nidec)服务商    

尼得科变频器,电机

新闻分类
  • 暂无分类
站内搜索
 
友情链接
  • 暂无链接
首页 > 新闻中心 > 如何在C#中实现对PLC软元件的读写操作?
新闻中心
如何在C#中实现对PLC软元件的读写操作?
发布时间:2025-11-13        浏览次数:15        返回列表

在 C# 中实现对 PLC 软元件(如 D 寄存器、M 继电器、X/Y 输入输出等)的读写操作,核心是通过PLC 支持的通讯协议(如三菱的 SLMP、西门子的 S7 协议、Modbus 等)建立网络连接,并按协议格式构造读写指令。以下以三菱 FX5U(SLMP 协议) 和通用 Modbus 协议为例,详细说明实现方法。

一、基于三菱 SLMP 协议(以 FX5U 为例)

SLMP 是三菱专用协议,适用于 FX5U、Q 系列等 PLC,通过以太网 TCP/UDP 通讯。

1. 核心步骤

  1. 建立 TCP 连接:通过TcpClient连接 PLC 的 IP 和端口(默认 5007)。

  2. 构造协议报文:按 SLMP 帧结构拼接读写指令(包含软元件类型、地址、长度等信息)。

  3. 发送与接收数据:通过NetworkStream发送报文,接收 PLC 响应。

  4. 解析响应数据:提取有效数据或验证操作结果。

2. 代码实现(读写 D 寄存器、M 继电器)

csharp

using System;using System.Net.Sockets;using System.Linq;namespace PLCCommunication{
    public class FX5U_SLMP
    {
        private TcpClient _tcpClient;
        private NetworkStream _stream;
        private string _plcIp;
        private int _port = 5007; // SLMP默认端口
            try
            {

        /// <summary>
        /// 读取PLC软元件
        /// </summary>
        /// <param name="device">软元件类型</param>
        /// <param name="startAddress">起始地址(如D100 → 100)</param>
        /// <param name="count">读取数量</param>
        /// <returns>读取结果(BOOL数组/M寄存器;ushort数组/D寄存器)</returns>
        public object ReadDevice(DeviceCode device, ushort startAddress, ushort count)
        {
            if (!_tcpClient?.Connected ?? true) return null;

            // 构造SLMP读命令帧
            byte[] header = { 0x50, 0x00, 0x00, 0x00 }; // 报头
            byte[] networkStation = { 0x00, 0xFF };     // 网络号、站号(默认广播)
            byte[] reserve = { 0x00, 0x00 };            // 预留
            byte[] command = { 0x04, 0x01 };            // 读命令码
            ushort subCommand = (ushort)device;         // 子命令码(软元件类型)
            byte[] dataLength = BitConverter.GetBytes((ushort)4); // 数据长度(地址2字节+数量2字节)
            if (BitConverter.IsLittleEndian) Array.Reverse(dataLength); // 转为大端模式

            // 起始地址和数量(大端模式)
            byte[] address = BitConverter.GetBytes(startAddress);
            byte[] cnt = BitConverter.GetBytes(count);
            if (BitConverter.IsLittleEndian)
            {
                Array.Reverse(address);
                Array.Reverse(cnt);

            // 转换数据为字节数组(按软元件类型处理)
            switch (device)
            {
                case DeviceCode.M: // M继电器(BOOL数组 → 字节数组)
                    bool[] mData = data as bool[];
                    if (mData == null) return false;
                    count = (ushort)mData.Length;
                    int mByteCount = (count + 7) / 8;
                    dataBytes = new byte[mByteCount];
                    for (int i = 0; i < count; i++)
                    {
                case DeviceCode.D: // D寄存器(ushort数组 → 大端字节数组)
                    ushort[] dData = data as ushort[];
                    if (dData == null) return false;
                    count = (ushort)dData.Length;
                    dataBytes = new byte[count * 2];
                    for (int i = 0; i < count; i++)
            // 构造SLMP写命令帧
            byte[] header = { 0x50, 0x00, 0x00, 0x00 };
            byte[] networkStation = { 0x00, 0xFF };
            byte[] reserve = { 0x00, 0x00 };
            byte[] command = { 0x14, 0x01 }; // 写命令码
            ushort subCommand = (ushort)device;
            ushort dataTotalLen = (ushort)(4 + dataBytes.Length); // 地址2 + 数量2 + 数据n
            byte[] dataLength = BitConverter.GetBytes(dataTotalLen);
            if (BitConverter.IsLittleEndian) Array.Reverse(dataLength);

二、基于 Modbus 协议(通用 PLC)

Modbus 是通用工业协议(支持 RTU/TCP),适用于多数 PLC(如西门子 S7-1200/1500、施耐德 M340 等)。C# 中可使用NModbus库简化开发。

1. 前期准备

  • 安装 NModbus 库:通过 NuGet 安装NModbus4NModbus

  • PLC 配置:启用 Modbus TCP 服务(如西门子 PLC 需在 TIA Portal 中配置 Modbus 服务器)。

2. 代码实现(Modbus TCP 读写)

csharp

using System;using System.Net.Sockets;using Modbus.Device;namespace ModbusCommunication{
    class ModbusClient
    {
        private TcpClient _tcpClient;
        private IModbusMaster _master;
        private string _plcIp;
        private int _port = 502; // Modbus默认端口

        /// <summary>
        /// 读取保持寄存器(对应PLC的D寄存器)
        /// </summary>
        public ushort[] ReadHoldingRegisters(ushort startAddress, ushort count)
        {
            try
            {
                return _master.ReadHoldingRegisters(1, startAddress, count); // 1为从站地址
            }
            catch (Exception ex)
            {
                Console.WriteLine($"读取失败:{ex.Message}");

    // 测试代码
    class Program
    {
        static void Main(string[] args)
        {
            var modbus = new ModbusClient("192.168.1.10");
            if (modbus.Connect())
            {
                // 读保持寄存器(D100对应地址100)
                var data = modbus.ReadHoldingRegisters(100, 2);
                // 写保持寄存器
                modbus.WriteHoldingRegisters(100, new ushort[] { 123, 456 });
                modbus.Disconnect();
            }
        }
    }}

三、关键注意事项

  1. 协议匹配:不同品牌 PLC 支持的协议不同(如三菱 SLMP、西门子 S7、罗克韦尔 EtherNet/IP),需先确认 PLC 支持的协议。

  2. 数据格式

    • 三菱 PLC 默认大端模式(高位在前),C# 需转换字节序。

    • Modbus 协议数据格式由 PLC 定义(通常为大端)。

  3. 地址映射:PLC 软元件地址与协议地址可能存在偏移(如 Modbus 地址 1 对应 PLC 的 D1),需查阅 PLC 手册。

  4. 异常处理:添加超时重试、断线重连逻辑,确保工业环境下的稳定性。

  5. 效率优化:批量读写比单地址读写更高效,避免频繁短连接。

通过上述方法,C# 可灵活实现对不同 PLC 软元件的读写,适用于工业数据采集、远程监控等场景。实际开发中需根据 PLC 型号选择对应协议,并严格按照协议规范处理数据格式。

收缩
  • QQ咨询

  • 电话咨询

  • 18520143666
  • 添加微信客服