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

菲尼克斯连接器专营    

菲尼克斯连接器、连接端子

新闻分类
  • 暂无分类
联系方式
  • 联系人:吴经理
  • 电话:18576370666
  • 邮件:18576370666@qq.com
首页 > 新闻中心 > C#的Pc跟PLC modbus rtu通訊!
新闻中心
C#的Pc跟PLC modbus rtu通訊!
发布时间:2025-11-08        浏览次数:1        返回列表

C# 与 PLC 进行 Modbus RTU 通讯的核心是通过串口(RS485/RS232)发送符合 Modbus 协议的报文,实现数据读写。以下是详细实现步骤、关键代码及注意事项:

一、前期准备

  1. 硬件连接

    • PLC 需支持 Modbus RTU 协议(如西门子 S7-200/1200、三菱 FX5U(需扩展模块)、欧姆龙 CP1H 等)。

    • 物理接口:通过 RS485 转换器(如 USB 转 RS485)连接 PC 与 PLC,确保接线正确(A 接 A,B 接 B,GND 可选接)。

  2. 参数确认

    • 双方需统一 波特率(如 9600)、数据位(8)、停止位(1)、校验位(无 / 奇 / 偶,常见 NONE)、从站地址(PLC 的 Modbus 从站号,如 1)。

二、实现方式(推荐使用类库)

手动解析 Modbus 报文较繁琐,推荐使用成熟类库简化开发,常用类库:

  • NModbus4(开源,NuGet 可直接安装,支持 Modbus RTU/TCP)

  • Modbus.Device(NModbus 的衍生版本,API 更简洁)

三、完整代码示例(基于 NModbus4)

1. 安装 NModbus4

在 Visual Studio 中,通过 NuGet 安装 NModbus4

bash

Install-Package NModbus4

2. 核心代码(读写示例)

csharp

using System;using System.IO.Ports;using Modbus.Device;class PlcModbusRtu{
    static void Main(string[] args)
    {
        // 1. 配置串口参数(需与PLC一致)
        string portName = "COM3";       // 串口名称(在设备管理器中查看)
        int baudRate = 9600;            // 波特率
        Parity parity = Parity.None;    // 校验位
        int dataBits = 8;               // 数据位
        StopBits stopBits = StopBits.One; // 停止位
        byte slaveAddress = 1;          // PLC的Modbus从站地址

        // 2. 初始化串口并连接
        using (SerialPort serialPort = new SerialPort(portName, baudRate, parity, dataBits, stopBits))
        {
            try
            {
                serialPort.Open();
                if (!serialPort.IsOpen)
                {
                    Console.WriteLine("串口打开失败!");
                    return;
                }

                // 3. 创建Modbus RTU主机
                IModbusSerialMaster master = ModbusSerialMaster.CreateRtu(serialPort);
                master.Transport.Retries = 3; // 通讯失败重试次数
                master.Transport.ReadTimeout = 1000; // 读取超时时间(毫秒)

                // 4. 读取PLC数据(示例:读取保持寄存器,地址0开始的2个寄存器)
                // 寄存器地址:Modbus协议中地址从0开始,需与PLC侧寄存器地址对应
                ushort startAddress = 0;     // 起始地址
                ushort numRegisters = 2;     // 读取数量
                ushort[] holdingRegisters = master.ReadHoldingRegisters(slaveAddress, startAddress, numRegisters);
                Console.WriteLine($"读取保持寄存器:[{string.Join(", ", holdingRegisters)}]");

                // 5. 向PLC写入数据(示例:向地址0写入单个寄存器)
                ushort writevalue = 1234;    // 写入值
                master.WriteSingleRegister(slaveAddress, startAddress, writevalue);
                Console.WriteLine($"向地址{startAddress}写入成功:{writevalue}");

                // 6. 读取输入寄存器(如PLC的模拟量输入,地址10开始的1个)
                ushort inputStartAddress = 10;
                ushort[] inputRegisters = master.ReadInputRegisters(slaveAddress, inputStartAddress, 1);
                Console.WriteLine($"读取输入寄存器(地址10):{inputRegisters[0]}");
            }
            catch (Exception ex)
            {
                Console.WriteLine($"通讯错误:{ex.Message}");
            }
            finally
            {
                if (serialPort.IsOpen)
                    serialPort.Close();
            }
        }
        Console.ReadLine();
    }}

四、关键说明

  1. 数据类型映射

    • Modbus 寄存器为 16 位无符号整数(ushort),若 PLC 中是 32 位浮点数(如温度、压力),需将两个 ushort 拼接后转换:

      csharp

    • // 示例:将寄存器[0]和[1]拼接为32位浮点数byte[] bytes = new byte[4];Buffer.BlockCopy(holdingRegisters, 0, bytes, 0, 4);float value = BitConverter.ToSingle(bytes, 0);
  2. 地址注意事项

    • 读保持寄存器(功能码 03):用于读写 PLC 的可读写寄存器(如 VW 区)。

    • 读输入寄存器(功能码 04):用于读取 PLC 的只读寄存器(如模拟量输入 AIW 区)。

    • PLC 的 Modbus 地址可能存在 “偏移”(如西门子 S7-200 中,VW0 对应 Modbus 地址 0),需查阅 PLC 手册确认映射关系。

    • 功能码对应:

  3. 抗干扰处理

    • 增加重试机制(master.Transport.Retries)和超时控制,避免单次失败导致程序崩溃。

    • 串口线远离动力线,必要时使用带屏蔽的 RS485 线,屏蔽层单端接地。

五、调试工具

若通讯失败,可先用工具排查问题:

  • Modbus Poll(模拟主机读 PLC)

  • Modbus Slave(模拟 PLC 测试 PC 程序)

  • 确认串口是否被占用(通过设备管理器或 SerialPort.GetPortNames() 检查)。

收缩
  • QQ咨询

  • 电话咨询

  • 18576370666
  • 添加微信客服