|
@@ -0,0 +1,496 @@
|
|
|
|
+using NModbus;
|
|
|
|
+using System;
|
|
|
|
+using System.Net.Sockets;
|
|
|
|
+
|
|
|
|
+namespace MvvmScaffoldFrame48.DLL.CommunicationTools
|
|
|
|
+{
|
|
|
|
+ public class ModbusTcpClient
|
|
|
|
+ {
|
|
|
|
+ #region 实例
|
|
|
|
+ private TcpClient _tcpClient;
|
|
|
|
+ private IModbusMaster _modbusMaster;
|
|
|
|
+ #endregion
|
|
|
|
+
|
|
|
|
+ #region 连接方法
|
|
|
|
+
|
|
|
|
+ /// <summary>
|
|
|
|
+ /// 判断 TCP 连接是否已断开
|
|
|
|
+ /// </summary>
|
|
|
|
+ /// <returns></returns>
|
|
|
|
+ public bool IsTcpClientConnected()
|
|
|
|
+ {
|
|
|
|
+ if (_tcpClient == null || _tcpClient.Client == null)
|
|
|
|
+ return false;
|
|
|
|
+ try
|
|
|
|
+ {
|
|
|
|
+ Socket socket = _tcpClient.Client;
|
|
|
|
+ bool isReadable = socket.Poll(0, SelectMode.SelectRead);
|
|
|
|
+ bool hasNoData = (socket.Available == 0);
|
|
|
|
+
|
|
|
|
+ // 可读且无数据 = 连接已断开
|
|
|
|
+ return !(isReadable && hasNoData);
|
|
|
|
+ }
|
|
|
|
+ catch (SocketException) { return false; }
|
|
|
|
+ catch (ObjectDisposedException) { return false; }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /// <summary>
|
|
|
|
+ /// 连接 Modbus TCP 服务器
|
|
|
|
+ /// </summary>
|
|
|
|
+ /// <param name="ipAddress"></param>
|
|
|
|
+ /// <param name="port"></param>
|
|
|
|
+ /// <returns></returns>
|
|
|
|
+ public bool Connect(string ipAddress, int port = 502)
|
|
|
|
+ {
|
|
|
|
+ try
|
|
|
|
+ {
|
|
|
|
+ _tcpClient = new TcpClient(ipAddress, port)
|
|
|
|
+ {
|
|
|
|
+ SendTimeout = 2000,
|
|
|
|
+ ReceiveTimeout = 2000
|
|
|
|
+ };
|
|
|
|
+ // 使用 ModbusFactory 创建 Master(新版本 API)
|
|
|
|
+ var factory = new ModbusFactory();
|
|
|
|
+ _modbusMaster = factory.CreateMaster(_tcpClient);
|
|
|
|
+ return true;
|
|
|
|
+ }
|
|
|
|
+ catch (Exception ex)
|
|
|
|
+ {
|
|
|
|
+ Console.WriteLine($"连接失败: {ex.Message}");
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /// <summary>
|
|
|
|
+ /// 断开连接
|
|
|
|
+ /// </summary>
|
|
|
|
+ public void Disconnect()
|
|
|
|
+ {
|
|
|
|
+ _modbusMaster?.Dispose();
|
|
|
|
+ _tcpClient?.Close();
|
|
|
|
+ }
|
|
|
|
+ #endregion
|
|
|
|
+
|
|
|
|
+ #region 读取方法
|
|
|
|
+ /// <summary>
|
|
|
|
+ /// 读取线圈(功能码01)
|
|
|
|
+ /// </summary>
|
|
|
|
+ /// <param name="slaveId"></param>
|
|
|
|
+ /// <param name="startAddress"></param>
|
|
|
|
+ /// <param name="numRegisters"></param>
|
|
|
|
+ /// <returns></returns>
|
|
|
|
+ /// <exception cref="InvalidOperationException"></exception>
|
|
|
|
+ public bool[] ReadCoilsRegister(byte slaveId, ushort startAddress, ushort numRegisters)
|
|
|
|
+ {
|
|
|
|
+ if (_modbusMaster == null)
|
|
|
|
+ {
|
|
|
|
+ Console.WriteLine($"ModbusTcpClient-ReadCoilsRegister failed:未连接到服务器");
|
|
|
|
+ return null;
|
|
|
|
+ }
|
|
|
|
+ try
|
|
|
|
+ {
|
|
|
|
+ return _modbusMaster.ReadCoils(slaveId, startAddress, numRegisters);
|
|
|
|
+ }
|
|
|
|
+ catch (Exception ex)
|
|
|
|
+ {
|
|
|
|
+ Console.WriteLine($"读取线圈失败,ModbusTcpClient-ReadCoilsRegister failed: {ex.Message}");
|
|
|
|
+ return null;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /// <summary>
|
|
|
|
+ /// 读取保持寄存器(功能码03)
|
|
|
|
+ /// </summary>
|
|
|
|
+ /// <param name="slaveId"></param>
|
|
|
|
+ /// <param name="startAddress"></param>
|
|
|
|
+ /// <param name="numRegisters"></param>
|
|
|
|
+ /// <returns></returns>
|
|
|
|
+ /// <exception cref="InvalidOperationException"></exception>
|
|
|
|
+ public ushort[] ReadHoldingRegisters(byte slaveId, ushort startAddress, ushort numRegisters)
|
|
|
|
+ {
|
|
|
|
+ if (_modbusMaster == null)
|
|
|
|
+ {
|
|
|
|
+ Console.WriteLine($"ModbusTcpClient-ReadHoldingRegistersAsReal failed:未连接到服务器");
|
|
|
|
+ return null;
|
|
|
|
+ }
|
|
|
|
+ try
|
|
|
|
+ {
|
|
|
|
+ return _modbusMaster.ReadHoldingRegisters(slaveId, startAddress, numRegisters);
|
|
|
|
+ }
|
|
|
|
+ catch (Exception ex)
|
|
|
|
+ {
|
|
|
|
+ Console.WriteLine($"读取保持寄存器失败,ModbusTcpClient-ReadHoldingRegisters failed: {ex.Message}");
|
|
|
|
+ return null;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /// <summary>
|
|
|
|
+ /// 读取保持寄存器中的REAL值(功能码03)
|
|
|
|
+ /// </summary>
|
|
|
|
+ /// <param name="slaveId">从站ID</param>
|
|
|
|
+ /// <param name="startAddress">起始地址</param>
|
|
|
|
+ /// <param name="count">REAL值的数量</param>
|
|
|
|
+ /// <param name="byteOrder">字节序 (ABCD, CDAB, BADC, DCBA)</param>
|
|
|
|
+ /// <returns>REAL值数组</returns>
|
|
|
|
+ public float[] ReadHoldingRegistersAsReal(byte slaveId, ushort startAddress, ushort count, string byteOrder = "BADC")
|
|
|
|
+ {
|
|
|
|
+ if (_modbusMaster == null)
|
|
|
|
+ {
|
|
|
|
+ Console.WriteLine($"ModbusTcpClient-ReadHoldingRegistersAsReal failed:未连接到服务器");
|
|
|
|
+ return null;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ try
|
|
|
|
+ {
|
|
|
|
+ // 每个REAL值占用2个寄存器
|
|
|
|
+ ushort[] registers = _modbusMaster.ReadHoldingRegisters(slaveId, startAddress, (ushort)(count * 2));
|
|
|
|
+ float[] realValues = new float[count];
|
|
|
|
+
|
|
|
|
+ for (int i = 0; i < count; i++)
|
|
|
|
+ {
|
|
|
|
+ ushort highRegister = registers[i * 2];
|
|
|
|
+ ushort lowRegister = registers[i * 2 + 1];
|
|
|
|
+
|
|
|
|
+ byte[] bytes = ConvertToByteArray(lowRegister, highRegister, byteOrder);
|
|
|
|
+ realValues[i] = BitConverter.ToSingle(bytes, 0);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return realValues;
|
|
|
|
+ }
|
|
|
|
+ catch (Exception ex)
|
|
|
|
+ {
|
|
|
|
+ Console.WriteLine($"读取REAL值失败,ModbusTcpClient-ReadHoldingRegistersAsReal failed:{ex.Message}");
|
|
|
|
+ return null;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /// <summary>
|
|
|
|
+ /// 读取保持寄存器中的Int32值(功能码03)
|
|
|
|
+ /// </summary>
|
|
|
|
+ /// <param name="slaveId">从站ID</param>
|
|
|
|
+ /// <param name="startAddress">起始地址</param>
|
|
|
|
+ /// <param name="count">REAL值的数量</param>
|
|
|
|
+ /// <returns>REAL值数组</returns>
|
|
|
|
+ public UInt32[] ReadHoldingRegistersAsInt32(byte slaveId, ushort startAddress, ushort count, string byteOrder = "BADC")
|
|
|
|
+ {
|
|
|
|
+ if (_modbusMaster == null)
|
|
|
|
+ {
|
|
|
|
+ Console.WriteLine($"ModbusTcpClient-ReadHoldingRegistersAsInt32 failed:未连接到服务器");
|
|
|
|
+ return null;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ try
|
|
|
|
+ {
|
|
|
|
+ // 每个REAL值占用2个寄存器
|
|
|
|
+ ushort[] registers = _modbusMaster.ReadHoldingRegisters(slaveId, startAddress, (ushort)(count * 2));
|
|
|
|
+ UInt32[] realValues = new UInt32[count];
|
|
|
|
+
|
|
|
|
+ for (int i = 0; i < count; i++)
|
|
|
|
+ {
|
|
|
|
+ // 获取两个连续的寄存器值
|
|
|
|
+ ushort highRegister = registers[i * 2];
|
|
|
|
+ ushort lowRegister = registers[i * 2 + 1];
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ byte[] bytes = ConvertToByteArray(lowRegister, highRegister, byteOrder);
|
|
|
|
+
|
|
|
|
+ // 转换为float
|
|
|
|
+ realValues[i] = (UInt32)BitConverter.ToInt32(bytes, 0);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return realValues;
|
|
|
|
+ }
|
|
|
|
+ catch (Exception ex)
|
|
|
|
+ {
|
|
|
|
+ Console.WriteLine($"读取Int32值失败: {ex.Message}");
|
|
|
|
+ return null;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ #endregion
|
|
|
|
+
|
|
|
|
+ #region 写入方法
|
|
|
|
+ /// <summary>
|
|
|
|
+ /// 写入线圈(功能码05)
|
|
|
|
+ /// </summary>
|
|
|
|
+ /// <param name="slaveId">Slave编号</param>
|
|
|
|
+ /// <param name="CoilsAddress">写入地址</param>
|
|
|
|
+ /// <param name="values">写入值</param>
|
|
|
|
+ /// <exception cref="InvalidOperationException"></exception>
|
|
|
|
+ public bool WriteCoilsRegister(byte slaveId, ushort CoilsAddress, bool values)
|
|
|
|
+ {
|
|
|
|
+ bool result = false;
|
|
|
|
+ if (_modbusMaster == null)
|
|
|
|
+ {
|
|
|
|
+ Console.WriteLine($"ModbusTcpClient-WriteCoilsRegister failed:未连接到服务器");
|
|
|
|
+ result = false;
|
|
|
|
+ }
|
|
|
|
+ try
|
|
|
|
+ {
|
|
|
|
+ _modbusMaster.WriteSingleCoil(slaveId, CoilsAddress, values);
|
|
|
|
+ result = true;
|
|
|
|
+ }
|
|
|
|
+ catch (Exception ex)
|
|
|
|
+ {
|
|
|
|
+ Console.WriteLine($"ModbusTcpClient-WriteCoilsRegister-WriteCoilsRegister failed:{ex.Message}");
|
|
|
|
+ result = false;
|
|
|
|
+ }
|
|
|
|
+ return result;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /// <summary>
|
|
|
|
+ /// 写入单个寄存器(功能码06)
|
|
|
|
+ /// </summary>
|
|
|
|
+ /// <param name="slaveId"></param>
|
|
|
|
+ /// <param name="registerAddress"></param>
|
|
|
|
+ /// <param name="value"></param>
|
|
|
|
+ /// <exception cref="InvalidOperationException"></exception>
|
|
|
|
+ public bool WriteSingleRegister(byte slaveId, ushort registerAddress, ushort value)
|
|
|
|
+ {
|
|
|
|
+ bool result = false;
|
|
|
|
+ if (_modbusMaster == null)
|
|
|
|
+ {
|
|
|
|
+ Console.WriteLine($"ModbusTcpClient-WriteSingleRegister failed:未连接到服务器");
|
|
|
|
+ result = false;
|
|
|
|
+ return result;
|
|
|
|
+ }
|
|
|
|
+ try
|
|
|
|
+ {
|
|
|
|
+ _modbusMaster.WriteSingleRegister(slaveId, registerAddress, value);
|
|
|
|
+ result = true;
|
|
|
|
+ }
|
|
|
|
+ catch (Exception ex)
|
|
|
|
+ {
|
|
|
|
+ Console.WriteLine($"写入单个寄存器失败,ModbusTcpClient-WriteSingleRegister failed:{ex.Message}");
|
|
|
|
+ result = false;
|
|
|
|
+ }
|
|
|
|
+ return result;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /// <summary>
|
|
|
|
+ /// 写入多个寄存器(功能码16)
|
|
|
|
+ /// </summary>
|
|
|
|
+ /// <param name="slaveId"></param>
|
|
|
|
+ /// <param name="startAddress"></param>
|
|
|
|
+ /// <param name="values"></param>
|
|
|
|
+ /// <exception cref="InvalidOperationException"></exception>
|
|
|
|
+ public bool WriteMultipleRegisters(byte slaveId, ushort startAddress, ushort[] values)
|
|
|
|
+ {
|
|
|
|
+ bool result = false;
|
|
|
|
+ if (_modbusMaster == null)
|
|
|
|
+ {
|
|
|
|
+ Console.WriteLine($"ModbusTcpClient-WriteMultipleRegisters failed:未连接到服务器");
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+ try
|
|
|
|
+ {
|
|
|
|
+ _modbusMaster.WriteMultipleRegisters(slaveId, startAddress, values);
|
|
|
|
+ result = true;
|
|
|
|
+ }
|
|
|
|
+ catch (Exception ex)
|
|
|
|
+ {
|
|
|
|
+ Console.WriteLine($"写入多个寄存器失败,ModbusTcpClient-WriteMultipleRegisters failed:{ex.Message}");
|
|
|
|
+ result = false;
|
|
|
|
+ }
|
|
|
|
+ return result;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /// <summary>
|
|
|
|
+ /// 写入单个REAL值到保持寄存器(功能码16)
|
|
|
|
+ /// </summary>
|
|
|
|
+ /// <param name="slaveId">从站ID</param>
|
|
|
|
+ /// <param name="startAddress">起始地址</param>
|
|
|
|
+ /// <param name="value">REAL值</param>
|
|
|
|
+ /// <param name="byteOrder">字节序 (ABCD, CDAB, BADC, DCBA)</param>
|
|
|
|
+ public bool WriteSingleReal(byte slaveId, ushort startAddress, float value, string byteOrder = "BADC")
|
|
|
|
+ {
|
|
|
|
+ bool result = false;
|
|
|
|
+ if (_modbusMaster == null)
|
|
|
|
+ {
|
|
|
|
+ Console.WriteLine($"ModbusTcpClient-WriteSingleReal failed:未连接到服务器");
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+ try
|
|
|
|
+ {
|
|
|
|
+ // 将float转换为字节数组
|
|
|
|
+ byte[] bytes = BitConverter.GetBytes(value);
|
|
|
|
+
|
|
|
|
+ // 根据字节序重新排列字节
|
|
|
|
+ ushort[] registers = ConvertBytesToRegisters(bytes, byteOrder);
|
|
|
|
+
|
|
|
|
+ // 写入连续的寄存器
|
|
|
|
+ result = WriteMultipleRegisters(slaveId, startAddress, registers);
|
|
|
|
+ }
|
|
|
|
+ catch (Exception ex)
|
|
|
|
+ {
|
|
|
|
+ Console.WriteLine($"写入REAL值失败,ModbusTcpClient-WriteSingleReal failed:{ex.Message}");
|
|
|
|
+ result = false;
|
|
|
|
+ }
|
|
|
|
+ return result;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /// <summary>
|
|
|
|
+ /// 写入多个REAL值到保持寄存器(功能码16)
|
|
|
|
+ /// </summary>
|
|
|
|
+ /// <param name="slaveId">从站ID</param>
|
|
|
|
+ /// <param name="startAddress">起始地址</param>
|
|
|
|
+ /// <param name="values">REAL值数组</param>
|
|
|
|
+ /// <param name="byteOrder">字节序 (ABCD, CDAB, BADC, DCBA)</param>
|
|
|
|
+ public bool WriteMultipleReals(byte slaveId, ushort startAddress, float[] values, string byteOrder = "BADC")
|
|
|
|
+ {
|
|
|
|
+ bool result = false;
|
|
|
|
+ if (_modbusMaster == null)
|
|
|
|
+ {
|
|
|
|
+ Console.WriteLine($"ModbusTcpClient-WriteMultipleReals failed:未连接到服务器");
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+ if (values == null || values.Length == 0)
|
|
|
|
+ {
|
|
|
|
+ Console.WriteLine("写入多个REAL值到保持寄存器-值数组不能为空", 0);
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ try
|
|
|
|
+ {
|
|
|
|
+ // 每个REAL值需要2个寄存器,所以总寄存器数是REAL值数量的2倍
|
|
|
|
+ ushort[] registers = new ushort[values.Length * 2];
|
|
|
|
+
|
|
|
|
+ for (int i = 0; i < values.Length; i++)
|
|
|
|
+ {
|
|
|
|
+ // 将每个float转换为字节数组
|
|
|
|
+ byte[] bytes = BitConverter.GetBytes(values[i]);
|
|
|
|
+
|
|
|
|
+ // 根据字节序转换为寄存器值
|
|
|
|
+ ushort[] regPair = ConvertBytesToRegisters(bytes, byteOrder);
|
|
|
|
+
|
|
|
|
+ // 将寄存器值放入数组
|
|
|
|
+ registers[i * 2] = regPair[0];
|
|
|
|
+ registers[i * 2 + 1] = regPair[1];
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 写入所有寄存器
|
|
|
|
+ _modbusMaster.WriteMultipleRegisters(slaveId, startAddress, registers);
|
|
|
|
+ result = true;
|
|
|
|
+ }
|
|
|
|
+ catch (Exception ex)
|
|
|
|
+ {
|
|
|
|
+ Console.WriteLine($"写入多个REAL值失败: {ex.Message}");
|
|
|
|
+ result = false;
|
|
|
|
+ }
|
|
|
|
+ return result;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /// <summary>
|
|
|
|
+ /// 写入单个Int32值到保持寄存器(功能码16)
|
|
|
|
+ /// </summary>
|
|
|
|
+ /// <param name="slaveId">从站ID</param>
|
|
|
|
+ /// <param name="startAddress">起始地址</param>
|
|
|
|
+ /// <param name="value">REAL值</param>
|
|
|
|
+ /// <param name="byteOrder">字节序 (ABCD, CDAB, BADC, DCBA)</param>
|
|
|
|
+ public bool WriteSingleInt32(byte slaveId, ushort startAddress, UInt32 value, string byteOrder = "BADC")
|
|
|
|
+ {
|
|
|
|
+ // 将32位整数拆分为两个16位寄存器值
|
|
|
|
+ byte[] bytes = BitConverter.GetBytes(value);
|
|
|
|
+ ushort[] registers = new ushort[2];
|
|
|
|
+
|
|
|
|
+ ushort[] regPair = ConvertBytesToRegisters(bytes, byteOrder);
|
|
|
|
+
|
|
|
|
+ // 将寄存器值放入数组
|
|
|
|
+ registers[0] = regPair[0];
|
|
|
|
+ registers[1] = regPair[1];
|
|
|
|
+
|
|
|
|
+ return WriteMultipleRegisters(slaveId, startAddress, registers);
|
|
|
|
+ }
|
|
|
|
+ #endregion
|
|
|
|
+
|
|
|
|
+ #region 辅助方法
|
|
|
|
+ /// <summary>
|
|
|
|
+ /// 将寄存器数组换为字节数组转(根据指定字节序)
|
|
|
|
+ /// </summary>
|
|
|
|
+ /// <param name="lowRegister">低位寄存器</param>
|
|
|
|
+ /// <param name="highRegister">高位寄存器</param>
|
|
|
|
+ /// <param name="byteOrder">字节序</param>
|
|
|
|
+ /// <returns>字节数组</returns>
|
|
|
|
+ private byte[] ConvertToByteArray(ushort lowRegister, ushort highRegister, string byteOrder)
|
|
|
|
+ {
|
|
|
|
+ byte[] bytes = new byte[4];
|
|
|
|
+
|
|
|
|
+ switch (byteOrder.ToUpper())
|
|
|
|
+ {
|
|
|
|
+ case "ABCD": // 大端序
|
|
|
|
+ bytes[0] = (byte)(highRegister >> 8);
|
|
|
|
+ bytes[1] = (byte)(highRegister & 0xFF);
|
|
|
|
+ bytes[2] = (byte)(lowRegister >> 8);
|
|
|
|
+ bytes[3] = (byte)(lowRegister & 0xFF);
|
|
|
|
+ break;
|
|
|
|
+ case "CDAB": // 小端序
|
|
|
|
+ bytes[0] = (byte)(lowRegister >> 8);
|
|
|
|
+ bytes[1] = (byte)(lowRegister & 0xFF);
|
|
|
|
+ bytes[2] = (byte)(highRegister >> 8);
|
|
|
|
+ bytes[3] = (byte)(highRegister & 0xFF);
|
|
|
|
+ break;
|
|
|
|
+ case "BADC":
|
|
|
|
+ bytes[0] = (byte)(highRegister & 0xFF);
|
|
|
|
+ bytes[1] = (byte)(highRegister >> 8);
|
|
|
|
+ bytes[2] = (byte)(lowRegister & 0xFF);
|
|
|
|
+ bytes[3] = (byte)(lowRegister >> 8);
|
|
|
|
+ break;
|
|
|
|
+ case "DCBA":
|
|
|
|
+ bytes[0] = (byte)(lowRegister & 0xFF);
|
|
|
|
+ bytes[1] = (byte)(lowRegister >> 8);
|
|
|
|
+ bytes[2] = (byte)(highRegister & 0xFF);
|
|
|
|
+ bytes[3] = (byte)(highRegister >> 8);
|
|
|
|
+ break;
|
|
|
|
+ default:
|
|
|
|
+ // 默认使用ABCD顺序
|
|
|
|
+ bytes[0] = (byte)(highRegister >> 8);
|
|
|
|
+ bytes[1] = (byte)(highRegister & 0xFF);
|
|
|
|
+ bytes[2] = (byte)(lowRegister >> 8);
|
|
|
|
+ bytes[3] = (byte)(lowRegister & 0xFF);
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ return bytes;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /// <summary>
|
|
|
|
+ /// 将字节数组转换为寄存器数组(根据指定字节序)
|
|
|
|
+ /// </summary>
|
|
|
|
+ /// <param name="bytes">字节数组(4字节)</param>
|
|
|
|
+ /// <param name="byteOrder">字节序</param>
|
|
|
|
+ /// <returns>寄存器数组(2个ushort)</returns>
|
|
|
|
+ private ushort[] ConvertBytesToRegisters(byte[] bytes, string byteOrder)
|
|
|
|
+ {
|
|
|
|
+ if (bytes.Length != 4)
|
|
|
|
+ throw new ArgumentException("字节数组必须包含4个字节用于REAL值转换");
|
|
|
|
+
|
|
|
|
+ ushort[] registers = new ushort[2];
|
|
|
|
+
|
|
|
|
+ switch (byteOrder.ToUpper())
|
|
|
|
+ {
|
|
|
|
+ case "ABCD": // 大端序
|
|
|
|
+ registers[0] = (ushort)((bytes[0] << 8) | bytes[1]); // 高位寄存器
|
|
|
|
+ registers[1] = (ushort)((bytes[2] << 8) | bytes[3]); // 低位寄存器
|
|
|
|
+ break;
|
|
|
|
+ case "CDAB": // 小端序
|
|
|
|
+ registers[0] = (ushort)((bytes[2] << 8) | bytes[3]); // 高位寄存器
|
|
|
|
+ registers[1] = (ushort)((bytes[0] << 8) | bytes[1]); // 低位寄存器
|
|
|
|
+ break;
|
|
|
|
+ case "BADC":
|
|
|
|
+ registers[0] = (ushort)((bytes[1] << 8) | bytes[0]); // 高位寄存器
|
|
|
|
+ registers[1] = (ushort)((bytes[3] << 8) | bytes[2]); // 低位寄存器
|
|
|
|
+ break;
|
|
|
|
+ case "DCBA":
|
|
|
|
+ registers[0] = (ushort)((bytes[3] << 8) | bytes[2]); // 高位寄存器
|
|
|
|
+ registers[1] = (ushort)((bytes[1] << 8) | bytes[0]); // 低位寄存器
|
|
|
|
+ break;
|
|
|
|
+ default:
|
|
|
|
+ // 默认使用ABCD顺序
|
|
|
|
+ registers[0] = (ushort)((bytes[0] << 8) | bytes[1]);
|
|
|
|
+ registers[1] = (ushort)((bytes[2] << 8) | bytes[3]);
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ return registers;
|
|
|
|
+ }
|
|
|
|
+ #endregion
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+}
|