2017-02-06 update 1 Add AddressHelper and comments, reformat code.

This commit is contained in:
parallelbgls
2017-02-06 17:15:54 +08:00
parent f2ed8ac72b
commit 0d19567038
55 changed files with 2190 additions and 1821 deletions

View File

@@ -7,40 +7,44 @@ namespace Modbus.Net.Modbus
internal enum ModbusProtocalVariableFunctionCode : byte
{
ReadVariable = 20,
WriteVariable = 21,
WriteVariable = 21
}
/// <summary>
/// 跟时间有关的功能码
/// 跟时间有关的功能码
/// </summary>
public enum ModbusProtocalTimeFunctionCode : byte
{
GetSystemTime = 3,
SetSystemTime = 16,
SetSystemTime = 16
}
/// <summary>
/// 跟读数据有关的功能码
/// 跟读数据有关的功能码
/// </summary>
public enum ModbusProtocalReadDataFunctionCode : byte
{
ReadCoilStatus = 1,
ReadInputStatus = 2,
ReadHoldRegister = 3,
ReadInputRegister = 4,
ReadInputRegister = 4
}
/// <summary>
/// 跟写数据有关的功能码
/// 跟写数据有关的功能码
/// </summary>
internal enum ModbusProtocalWriteDataFunctionCode : byte
{
WriteMultiCoil = 15,
WriteMultiRegister = 16,
WriteMultiRegister = 16
}
public abstract class ModbusProtocal : BaseProtocal
{
protected ModbusProtocal(byte slaveAddress, byte masterAddress) : base(slaveAddress, masterAddress)
{
}
public override bool Connect()
{
return ProtocalLinker.Connect();
@@ -50,45 +54,43 @@ namespace Modbus.Net.Modbus
{
return await ProtocalLinker.ConnectAsync();
}
protected ModbusProtocal(byte belongAddress, byte masterAddress) : base(belongAddress, masterAddress)
{
}
}
#region PLC数据
public class ReadDataModbusInputStruct : InputStruct
{
public ReadDataModbusInputStruct(byte belongAddress, string startAddress, ushort getCount, AddressTranslator addressTranslator)
public ReadDataModbusInputStruct(byte slaveAddress, string startAddress, ushort getCount,
AddressTranslator addressTranslator)
{
BelongAddress = belongAddress;
SlaveAddress = slaveAddress;
var translateAddress = addressTranslator.AddressTranslate(startAddress, true);
FunctionCode = (byte)translateAddress.Area;
StartAddress = (ushort)translateAddress.Address;
GetCount = (ushort)Math.Ceiling(getCount / addressTranslator.GetAreaByteLength(translateAddress.AreaString));
FunctionCode = (byte) translateAddress.Area;
StartAddress = (ushort) translateAddress.Address;
GetCount = (ushort) Math.Ceiling(getCount/addressTranslator.GetAreaByteLength(translateAddress.AreaString));
}
public byte BelongAddress { get; private set; }
public byte SlaveAddress { get; }
public byte FunctionCode { get; private set; }
public byte FunctionCode { get; }
public ushort StartAddress { get; private set; }
public ushort StartAddress { get; }
public ushort GetCount { get; private set; }
public ushort GetCount { get; }
}
public class ReadDataModbusOutputStruct : OutputStruct
{
public ReadDataModbusOutputStruct(byte belongAddress, byte functionCode,
public ReadDataModbusOutputStruct(byte slaveAddress, byte functionCode,
int dataCount, byte[] dataValue)
{
BelongAddress = belongAddress;
SlaveAddress = slaveAddress;
FunctionCode = functionCode;
DataCount = dataCount;
DataValue = dataValue.Clone() as byte[];
}
public byte BelongAddress { get; private set; }
public byte SlaveAddress { get; private set; }
public byte FunctionCode { get; private set; }
@@ -101,71 +103,74 @@ namespace Modbus.Net.Modbus
{
public override byte[] Format(InputStruct message)
{
var r_message = (ReadDataModbusInputStruct)message;
return Format(r_message.BelongAddress, r_message.FunctionCode,
var r_message = (ReadDataModbusInputStruct) message;
return Format(r_message.SlaveAddress, r_message.FunctionCode,
r_message.StartAddress, r_message.GetCount);
}
public override OutputStruct Unformat(byte[] messageBytes, ref int pos)
{
byte belongAddress = BigEndianValueHelper.Instance.GetByte(messageBytes, ref pos);
byte functionCode = BigEndianValueHelper.Instance.GetByte(messageBytes, ref pos);
byte dataCount = BigEndianValueHelper.Instance.GetByte(messageBytes, ref pos);
byte[] dataValue = new byte[dataCount];
var slaveAddress = BigEndianValueHelper.Instance.GetByte(messageBytes, ref pos);
var functionCode = BigEndianValueHelper.Instance.GetByte(messageBytes, ref pos);
var dataCount = BigEndianValueHelper.Instance.GetByte(messageBytes, ref pos);
var dataValue = new byte[dataCount];
Array.Copy(messageBytes, 3, dataValue, 0, dataCount);
if (functionCode == 1 || functionCode == 2)
{
for (int i = 0; i < dataValue.Length; i++)
for (var i = 0; i < dataValue.Length; i++)
{
dataValue[i] = BigEndianValueHelper.Instance.ReverseByte(dataValue[i]);
}
}
return new ReadDataModbusOutputStruct(belongAddress, functionCode, dataCount, dataValue);
return new ReadDataModbusOutputStruct(slaveAddress, functionCode, dataCount, dataValue);
}
}
#endregion
#region PLC数据
public class WriteDataModbusInputStruct : InputStruct
{
public WriteDataModbusInputStruct(byte belongAddress, string startAddress, object[] writeValue, AddressTranslator addressTranslator)
public WriteDataModbusInputStruct(byte slaveAddress, string startAddress, object[] writeValue,
AddressTranslator addressTranslator)
{
BelongAddress = belongAddress;
SlaveAddress = slaveAddress;
var translateAddress = addressTranslator.AddressTranslate(startAddress, false);
FunctionCode = (byte)translateAddress.Area;
StartAddress = (ushort)translateAddress.Address;
FunctionCode = (byte) translateAddress.Area;
StartAddress = (ushort) translateAddress.Address;
var writeByteValue = BigEndianValueHelper.Instance.ObjectArrayToByteArray(writeValue);
WriteCount = (ushort)(writeByteValue.Length / addressTranslator.GetAreaByteLength(translateAddress.AreaString));
WriteByteCount = (byte)writeByteValue.Length;
WriteCount =
(ushort) (writeByteValue.Length/addressTranslator.GetAreaByteLength(translateAddress.AreaString));
WriteByteCount = (byte) writeByteValue.Length;
WriteValue = writeByteValue;
}
public byte BelongAddress { get; private set; }
public byte SlaveAddress { get; }
public byte FunctionCode { get; private set; }
public byte FunctionCode { get; }
public ushort StartAddress { get; private set; }
public ushort StartAddress { get; }
public ushort WriteCount { get; private set; }
public ushort WriteCount { get; }
public byte WriteByteCount { get; private set; }
public byte WriteByteCount { get; }
public byte[] WriteValue { get; private set; }
public byte[] WriteValue { get; }
}
public class WriteDataModbusOutputStruct : OutputStruct
{
public WriteDataModbusOutputStruct(byte belongAddress, byte functionCode,
public WriteDataModbusOutputStruct(byte slaveAddress, byte functionCode,
ushort startAddress, ushort writeCount)
{
BelongAddress = belongAddress;
SlaveAddress = slaveAddress;
FunctionCode = functionCode;
StartAddress = startAddress;
WriteCount = writeCount;
}
public byte BelongAddress { get; private set; }
public byte SlaveAddress { get; private set; }
public byte FunctionCode { get; private set; }
@@ -175,34 +180,34 @@ namespace Modbus.Net.Modbus
}
/// <summary>
/// 写多个寄存器状态
/// 写多个寄存器状态
/// </summary>
public class WriteDataModbusProtocal : ProtocalUnit
{
public override byte[] Format(InputStruct message)
{
var r_message = (WriteDataModbusInputStruct)message;
var r_message = (WriteDataModbusInputStruct) message;
var functionCode = r_message.FunctionCode;
byte[] dataValue = Format(r_message.WriteValue);
var dataValue = Format(r_message.WriteValue);
if (functionCode == 5 || functionCode == 15)
{
for (int i = 0; i < dataValue.Length; i++)
for (var i = 0; i < dataValue.Length; i++)
{
dataValue[i] = BigEndianValueHelper.Instance.ReverseByte(dataValue[i]);
}
}
byte[] formattingBytes = Format(r_message.BelongAddress, r_message.FunctionCode,
var formattingBytes = Format(r_message.SlaveAddress, r_message.FunctionCode,
r_message.StartAddress, r_message.WriteCount, r_message.WriteByteCount, dataValue);
return formattingBytes;
}
public override OutputStruct Unformat(byte[] messageBytes, ref int flag)
{
byte belongAddress = BigEndianValueHelper.Instance.GetByte(messageBytes, ref flag);
byte functionCode = BigEndianValueHelper.Instance.GetByte(messageBytes, ref flag);
ushort startAddress = BigEndianValueHelper.Instance.GetUShort(messageBytes, ref flag);
ushort writeCount = BigEndianValueHelper.Instance.GetUShort(messageBytes, ref flag);
return new WriteDataModbusOutputStruct(belongAddress, functionCode, startAddress,
var slaveAddress = BigEndianValueHelper.Instance.GetByte(messageBytes, ref flag);
var functionCode = BigEndianValueHelper.Instance.GetByte(messageBytes, ref flag);
var startAddress = BigEndianValueHelper.Instance.GetUShort(messageBytes, ref flag);
var writeCount = BigEndianValueHelper.Instance.GetUShort(messageBytes, ref flag);
return new WriteDataModbusOutputStruct(slaveAddress, functionCode, startAddress,
writeCount);
}
}
@@ -210,38 +215,39 @@ namespace Modbus.Net.Modbus
#endregion
#region PLC时间
public class GetSystemTimeModbusInputStruct : InputStruct
{
public GetSystemTimeModbusInputStruct(byte belongAddress)
public GetSystemTimeModbusInputStruct(byte slaveAddress)
{
BelongAddress = belongAddress;
FunctionCode = (byte)ModbusProtocalTimeFunctionCode.GetSystemTime;
SlaveAddress = slaveAddress;
FunctionCode = (byte) ModbusProtocalTimeFunctionCode.GetSystemTime;
StartAddress = 30000;
GetCount = 5;
}
public byte BelongAddress { get; private set; }
public byte SlaveAddress { get; }
public byte FunctionCode { get; private set; }
public byte FunctionCode { get; }
public ushort StartAddress { get; private set; }
public ushort StartAddress { get; }
public ushort GetCount { get; private set; }
public ushort GetCount { get; }
}
public class GetSystemTimeModbusOutputStruct : OutputStruct
{
public GetSystemTimeModbusOutputStruct(byte belongAddress, byte functionCode,
public GetSystemTimeModbusOutputStruct(byte slaveAddress, byte functionCode,
byte writeByteCount, ushort year, byte day, byte month, ushort hour, byte second, byte minute,
ushort millisecond)
{
BelongAddress = belongAddress;
SlaveAddress = slaveAddress;
FunctionCode = functionCode;
WriteByteCount = writeByteCount;
Time = new DateTime(year, month, day, hour, minute, second, millisecond);
}
public byte BelongAddress { get; private set; }
public byte SlaveAddress { get; private set; }
public byte FunctionCode { get; private set; }
@@ -251,30 +257,30 @@ namespace Modbus.Net.Modbus
}
/// <summary>
/// 读系统时间
/// 读系统时间
/// </summary>
public class GetSystemTimeModbusProtocal : ProtocalUnit
{
public override byte[] Format(InputStruct message)
{
var r_message = (GetSystemTimeModbusInputStruct)message;
return Format(r_message.BelongAddress, r_message.FunctionCode,
var r_message = (GetSystemTimeModbusInputStruct) message;
return Format(r_message.SlaveAddress, r_message.FunctionCode,
r_message.StartAddress, r_message.GetCount);
}
public override OutputStruct Unformat(byte[] messageBytes, ref int flag)
{
byte belongAddress = BigEndianValueHelper.Instance.GetByte(messageBytes, ref flag);
byte functionCode = BigEndianValueHelper.Instance.GetByte(messageBytes, ref flag);
byte writeByteCount = BigEndianValueHelper.Instance.GetByte(messageBytes, ref flag);
ushort year = BigEndianValueHelper.Instance.GetUShort(messageBytes, ref flag);
byte day = BigEndianValueHelper.Instance.GetByte(messageBytes, ref flag);
byte month = BigEndianValueHelper.Instance.GetByte(messageBytes, ref flag);
ushort hour = BigEndianValueHelper.Instance.GetUShort(messageBytes, ref flag);
byte second = BigEndianValueHelper.Instance.GetByte(messageBytes, ref flag);
byte minute = BigEndianValueHelper.Instance.GetByte(messageBytes, ref flag);
ushort millisecond = BigEndianValueHelper.Instance.GetUShort(messageBytes, ref flag);
return new GetSystemTimeModbusOutputStruct(belongAddress, functionCode, writeByteCount, year, day,
var slaveAddress = BigEndianValueHelper.Instance.GetByte(messageBytes, ref flag);
var functionCode = BigEndianValueHelper.Instance.GetByte(messageBytes, ref flag);
var writeByteCount = BigEndianValueHelper.Instance.GetByte(messageBytes, ref flag);
var year = BigEndianValueHelper.Instance.GetUShort(messageBytes, ref flag);
var day = BigEndianValueHelper.Instance.GetByte(messageBytes, ref flag);
var month = BigEndianValueHelper.Instance.GetByte(messageBytes, ref flag);
var hour = BigEndianValueHelper.Instance.GetUShort(messageBytes, ref flag);
var second = BigEndianValueHelper.Instance.GetByte(messageBytes, ref flag);
var minute = BigEndianValueHelper.Instance.GetByte(messageBytes, ref flag);
var millisecond = BigEndianValueHelper.Instance.GetUShort(messageBytes, ref flag);
return new GetSystemTimeModbusOutputStruct(slaveAddress, functionCode, writeByteCount, year, day,
month, hour, second, minute, millisecond);
}
}
@@ -282,61 +288,62 @@ namespace Modbus.Net.Modbus
#endregion
#region PLC时间
public class SetSystemTimeModbusInputStruct : InputStruct
{
public SetSystemTimeModbusInputStruct(byte belongAddress, DateTime time)
public SetSystemTimeModbusInputStruct(byte slaveAddress, DateTime time)
{
BelongAddress = belongAddress;
FunctionCode = (byte)ModbusProtocalTimeFunctionCode.SetSystemTime;
SlaveAddress = slaveAddress;
FunctionCode = (byte) ModbusProtocalTimeFunctionCode.SetSystemTime;
StartAddress = 30000;
WriteCount = 5;
WriteByteCount = 10;
Year = (ushort)time.Year;
Day = (byte)time.Day;
Month = (byte)time.Month;
Hour = (ushort)time.Hour;
Second = (byte)time.Second;
Minute = (byte)time.Minute;
Millisecond = (ushort)time.Millisecond;
Year = (ushort) time.Year;
Day = (byte) time.Day;
Month = (byte) time.Month;
Hour = (ushort) time.Hour;
Second = (byte) time.Second;
Minute = (byte) time.Minute;
Millisecond = (ushort) time.Millisecond;
}
public byte BelongAddress { get; private set; }
public byte SlaveAddress { get; }
public byte FunctionCode { get; private set; }
public byte FunctionCode { get; }
public ushort StartAddress { get; private set; }
public ushort StartAddress { get; }
public ushort WriteCount { get; private set; }
public ushort WriteCount { get; }
public byte WriteByteCount { get; private set; }
public byte WriteByteCount { get; }
public ushort Year { get; private set; }
public ushort Year { get; }
public byte Day { get; private set; }
public byte Day { get; }
public byte Month { get; private set; }
public byte Month { get; }
public ushort Hour { get; private set; }
public ushort Hour { get; }
public byte Second { get; private set; }
public byte Second { get; }
public byte Minute { get; private set; }
public byte Minute { get; }
public ushort Millisecond { get; private set; }
public ushort Millisecond { get; }
}
public class SetSystemTimeModbusOutputStruct : OutputStruct
{
public SetSystemTimeModbusOutputStruct(byte belongAddress, byte functionCode,
public SetSystemTimeModbusOutputStruct(byte slaveAddress, byte functionCode,
ushort startAddress, ushort writeCount)
{
BelongAddress = belongAddress;
SlaveAddress = slaveAddress;
FunctionCode = functionCode;
StartAddress = startAddress;
WriteCount = writeCount;
}
public byte BelongAddress { get; private set; }
public byte SlaveAddress { get; private set; }
public byte FunctionCode { get; private set; }
@@ -346,14 +353,14 @@ namespace Modbus.Net.Modbus
}
/// <summary>
/// 写系统时间
/// 写系统时间
/// </summary>
public class SetSystemTimeModbusProtocal : ProtocalUnit
{
public override byte[] Format(InputStruct message)
{
var r_message = (SetSystemTimeModbusInputStruct)message;
return Format(r_message.BelongAddress, r_message.FunctionCode,
var r_message = (SetSystemTimeModbusInputStruct) message;
return Format(r_message.SlaveAddress, r_message.FunctionCode,
r_message.StartAddress, r_message.WriteCount, r_message.WriteByteCount, r_message.Year,
r_message.Day,
r_message.Month, r_message.Hour, r_message.Second, r_message.Minute, r_message.Millisecond);
@@ -361,22 +368,22 @@ namespace Modbus.Net.Modbus
public override OutputStruct Unformat(byte[] messageBytes, ref int flag)
{
byte belongAddress = BigEndianValueHelper.Instance.GetByte(messageBytes, ref flag);
byte functionCode = BigEndianValueHelper.Instance.GetByte(messageBytes, ref flag);
ushort startAddress = BigEndianValueHelper.Instance.GetUShort(messageBytes, ref flag);
ushort writeCount = BigEndianValueHelper.Instance.GetUShort(messageBytes, ref flag);
return new SetSystemTimeModbusOutputStruct(belongAddress, functionCode, startAddress, writeCount);
var slaveAddress = BigEndianValueHelper.Instance.GetByte(messageBytes, ref flag);
var functionCode = BigEndianValueHelper.Instance.GetByte(messageBytes, ref flag);
var startAddress = BigEndianValueHelper.Instance.GetUShort(messageBytes, ref flag);
var writeCount = BigEndianValueHelper.Instance.GetUShort(messageBytes, ref flag);
return new SetSystemTimeModbusOutputStruct(slaveAddress, functionCode, startAddress, writeCount);
}
}
#endregion
/// <summary>
/// Modbus协议错误表
/// Modbus协议错误表
/// </summary>
public class ModbusProtocalErrorException : ProtocalErrorException
{
public int ErrorMessageNumber { get; private set; }
private static readonly Dictionary<int, string> ProtocalErrorDictionary = new Dictionary<int, string>()
private static readonly Dictionary<int, string> ProtocalErrorDictionary = new Dictionary<int, string>
{
{1, "ILLEGAL_FUNCTION"},
{2, "ILLEGAL_DATA_ACCESS"},
@@ -385,7 +392,7 @@ namespace Modbus.Net.Modbus
{5, "ACKNOWLWDGE"},
{6, "SLAVE_DEVICE_BUSY"},
{500, "TCP_ILLEGAL_LENGTH"},
{501, "RTU_ILLEGAL_CRC"},
{501, "RTU_ILLEGAL_CRC"}
};
public ModbusProtocalErrorException(int messageNumber)
@@ -393,5 +400,7 @@ namespace Modbus.Net.Modbus
{
ErrorMessageNumber = messageNumber;
}
public int ErrorMessageNumber { get; private set; }
}
}