feat: add 浮点转方法
This commit is contained in:
@@ -3,6 +3,32 @@ using System.Net.Sockets;
|
|||||||
|
|
||||||
namespace PetWashControl.Services;
|
namespace PetWashControl.Services;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 浮点数字节序枚举
|
||||||
|
/// </summary>
|
||||||
|
public enum FloatByteOrder
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 标准Modbus大端序: 寄存器0=高16位(AB),寄存器1=低16位(CD)
|
||||||
|
/// </summary>
|
||||||
|
ABCD,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 字交换: 寄存器0=低16位(CD),寄存器1=高16位(AB)
|
||||||
|
/// </summary>
|
||||||
|
CDAB,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 字节交换: 寄存器0=BA,寄存器1=DC
|
||||||
|
/// </summary>
|
||||||
|
BADC,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 完全反转: 寄存器0=DC,寄存器1=BA
|
||||||
|
/// </summary>
|
||||||
|
DCBA
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Modbus TCP 服务,用于与设备进行通信
|
/// Modbus TCP 服务,用于与设备进行通信
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -393,4 +419,136 @@ public class ModbusService : IDisposable
|
|||||||
{
|
{
|
||||||
Disconnect();
|
Disconnect();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#region 浮点数转换方法
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 将 Modbus 寄存器转换为浮点数
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="registers">寄存器数组</param>
|
||||||
|
/// <param name="startIndex">起始索引</param>
|
||||||
|
/// <param name="byteOrder">字节序</param>
|
||||||
|
/// <returns>浮点数值</returns>
|
||||||
|
public float ConvertRegistersToFloat(ushort[] registers, int startIndex = 0,
|
||||||
|
FloatByteOrder byteOrder = FloatByteOrder.CDAB)
|
||||||
|
{
|
||||||
|
// 参数验证
|
||||||
|
if (registers == null || registers.Length < startIndex + 2)
|
||||||
|
{
|
||||||
|
throw new ArgumentException($"寄存器数组长度不足,需要至少 {startIndex + 2} 个元素");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 读取两个寄存器
|
||||||
|
ushort reg0 = registers[startIndex];
|
||||||
|
ushort reg1 = registers[startIndex + 1];
|
||||||
|
|
||||||
|
// 创建字节数组(4字节 = 32位浮点数)
|
||||||
|
byte[] floatBytes = new byte[4];
|
||||||
|
|
||||||
|
// 根据字节序填充字节数组
|
||||||
|
switch (byteOrder)
|
||||||
|
{
|
||||||
|
case FloatByteOrder.ABCD:
|
||||||
|
// 标准Modbus大端序: Reg0=AB, Reg1=CD
|
||||||
|
floatBytes[0] = (byte)(reg0 >> 8); // A (高字节)
|
||||||
|
floatBytes[1] = (byte)(reg0 & 0xFF); // B (低字节)
|
||||||
|
floatBytes[2] = (byte)(reg1 >> 8); // C (高字节)
|
||||||
|
floatBytes[3] = (byte)(reg1 & 0xFF); // D (低字节)
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FloatByteOrder.CDAB:
|
||||||
|
// 字交换: Reg0=CD, Reg1=AB
|
||||||
|
floatBytes[0] = (byte)(reg1 >> 8); // A
|
||||||
|
floatBytes[1] = (byte)(reg1 & 0xFF); // B
|
||||||
|
floatBytes[2] = (byte)(reg0 >> 8); // C
|
||||||
|
floatBytes[3] = (byte)(reg0 & 0xFF); // D
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FloatByteOrder.BADC:
|
||||||
|
// 字节交换: Reg0=BA, Reg1=DC
|
||||||
|
floatBytes[0] = (byte)(reg0 & 0xFF); // B
|
||||||
|
floatBytes[1] = (byte)(reg0 >> 8); // A
|
||||||
|
floatBytes[2] = (byte)(reg1 & 0xFF); // D
|
||||||
|
floatBytes[3] = (byte)(reg1 >> 8); // C
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FloatByteOrder.DCBA:
|
||||||
|
// 完全反转: Reg0=DC, Reg1=BA
|
||||||
|
floatBytes[0] = (byte)(reg1 & 0xFF); // D
|
||||||
|
floatBytes[1] = (byte)(reg1 >> 8); // C
|
||||||
|
floatBytes[2] = (byte)(reg0 & 0xFF); // B
|
||||||
|
floatBytes[3] = (byte)(reg0 >> 8); // A
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
throw new InvalidOperationException($"未知的字节顺序: {byteOrder}");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 转换为浮点数
|
||||||
|
float result = BitConverter.ToSingle(floatBytes, 0);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 将浮点数转换为 Modbus 寄存器
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value">浮点数值</param>
|
||||||
|
/// <param name="byteOrder">字节序</param>
|
||||||
|
/// <returns>寄存器数组(2个元素)</returns>
|
||||||
|
public ushort[] ConvertFloatToRegisters(float value, FloatByteOrder byteOrder = FloatByteOrder.CDAB)
|
||||||
|
{
|
||||||
|
// 将浮点数转换为字节数组(小端序)
|
||||||
|
byte[] bytes = BitConverter.GetBytes(value);
|
||||||
|
|
||||||
|
// 参数验证
|
||||||
|
if (bytes == null || bytes.Length != 4)
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException($"浮点数字节长度异常: 期望 4,实际 {bytes?.Length ?? 0}");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 分配寄存器数组
|
||||||
|
ushort[] registers = new ushort[2];
|
||||||
|
|
||||||
|
// BitConverter.GetBytes 在小端系统上产生: [Byte0(LSB), Byte1, Byte2, Byte3(MSB)]
|
||||||
|
// 即: [D, C, B, A],其中 A 是最高有效字节
|
||||||
|
// 需要根据目标字节序重新组装
|
||||||
|
|
||||||
|
switch (byteOrder)
|
||||||
|
{
|
||||||
|
case FloatByteOrder.ABCD:
|
||||||
|
// 标准Modbus大端序: Reg0=AB(高16位), Reg1=CD(低16位)
|
||||||
|
// 小端字节 [D,C,B,A] → Reg0=AB, Reg1=CD
|
||||||
|
registers[0] = (ushort)((bytes[3] << 8) | bytes[2]); // A,B
|
||||||
|
registers[1] = (ushort)((bytes[1] << 8) | bytes[0]); // C,D
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FloatByteOrder.CDAB:
|
||||||
|
// 字交换: Reg0=CD(低16位), Reg1=AB(高16位)
|
||||||
|
// 小端字节 [D,C,B,A] → Reg0=CD, Reg1=AB
|
||||||
|
registers[0] = (ushort)((bytes[1] << 8) | bytes[0]); // C,D
|
||||||
|
registers[1] = (ushort)((bytes[3] << 8) | bytes[2]); // A,B
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FloatByteOrder.BADC:
|
||||||
|
// 字节交换: Reg0=BA, Reg1=DC
|
||||||
|
// 小端字节 [D,C,B,A] → Reg0=BA, Reg1=DC
|
||||||
|
registers[0] = (ushort)((bytes[2] << 8) | bytes[3]); // B,A
|
||||||
|
registers[1] = (ushort)((bytes[0] << 8) | bytes[1]); // D,C
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FloatByteOrder.DCBA:
|
||||||
|
// 完全反转: Reg0=DC, Reg1=BA
|
||||||
|
// 小端字节 [D,C,B,A] → Reg0=DC, Reg1=BA
|
||||||
|
registers[0] = (ushort)((bytes[0] << 8) | bytes[1]); // D,C
|
||||||
|
registers[1] = (ushort)((bytes[2] << 8) | bytes[3]); // B,A
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
throw new InvalidOperationException($"未知的字节顺序: {byteOrder}");
|
||||||
|
}
|
||||||
|
|
||||||
|
return registers;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user