using Microsoft.VisualStudio.TestTools.UnitTesting; using Modbus.Net.Modbus; using AddressUnit = Modbus.Net.AddressUnit; namespace Modbus.Net.Tests { /// /// 字节序测试类 /// 测试 Modbus 大端和小端字节序的读写差异 /// [TestClass] public class EndianTest { // Modbus TCP 机器实例(大端) private BaseMachine? _modbusTcpMachine; // Modbus TCP 机器实例(小端) private BaseMachine? _modbusTcpMachine2; // 测试机器 IP 地址 private string _machineIp = "10.10.18.251"; /// /// 测试初始化方法 /// 创建大端和小端两种字节序的 Modbus TCP 机器实例 /// [TestInitialize] public void Init() { // 创建大端字节序的 Modbus TCP 机器 _modbusTcpMachine = new ModbusMachine("1", "", ModbusType.Tcp, _machineIp, null, true, 1, 0, Endian.BigEndianLsb); // 创建小端字节序的 Modbus TCP 机器 _modbusTcpMachine2 = new ModbusMachine("2", "", ModbusType.Tcp, _machineIp, null, true, 1, 0, Endian.LittleEndianLsb); } /// /// 测试 Modbus 字节序 /// 验证大端和小端字节序对同一数据的读写差异 /// [TestMethod] public async Task ModbusEndianSingle() { Random r = new Random(); // 定义地址单元 var addresses = new List { new AddressUnit { Id = "0", Area = "4X", Address = 1, SubAddress = 0, CommunicationTag = "A1", DataType = typeof(ushort) } }; // 生成随机值 var dic1 = new Dictionary() { { "4X 1", r.Next(0, UInt16.MaxValue) } }; // 设置两种字节序机器的地址列表 _modbusTcpMachine!.GetAddresses = addresses; _modbusTcpMachine2!.GetAddresses = addresses; // 使用大端字节序写入数据 await _modbusTcpMachine.SetDatasAsync(MachineDataType.Address, dic1); // 使用大端字节序读取数据 var ans = await _modbusTcpMachine.GetDatasAsync(MachineDataType.Address); _modbusTcpMachine.Disconnect(); // 使用小端字节序读取同一数据 var ans2 = await _modbusTcpMachine2.GetDatasAsync(MachineDataType.Address); // 验证大端读取的值与写入的值一致 Assert.AreEqual(ans.Datas["4X 1.0"].DeviceValue, dic1["4X 1"]); // 验证小端读取的值是字节交换后的值 // 例如:0x1234 在大端是 [0x12, 0x34],在小端会被解读为 [0x34, 0x12] = 0x3412 // 计算公式:低字节*256 + 高字节 Assert.AreEqual(ans2.Datas["4X 1.0"].DeviceValue, (ushort)dic1["4X 1"] % 256 * 256 + (ushort)dic1["4X 1"] / 256); } } }