浏览代码

修改寄存器bug

dev1
永攀 张 2 周前
父节点
当前提交
b806c830c0
共有 3 个文件被更改,包括 175 次插入90 次删除
  1. +100
    -58
      ModbusDemo/Device/ModbusRTU.cs
  2. +1
    -1
      ModbusDemo/VIewModel/CoilUCViewModel.cs
  3. +74
    -31
      ModbusDemo/VIewModel/RegisterUCViewModel.cs

+ 100
- 58
ModbusDemo/Device/ModbusRTU.cs 查看文件

@@ -147,7 +147,7 @@ namespace ModbusDemo.Device
}


}
/// <summary>
/// 写入多个线圈操作
@@ -160,7 +160,7 @@ namespace ModbusDemo.Device
if (!_serialPort.IsOpen)
{
MessageBox.Show("串口没有链接,请先链接");
return ;
return;
}
List<byte> sendByteList = new List<byte>();
//设置从站地址
@@ -205,12 +205,10 @@ namespace ModbusDemo.Device
byte[] response = null;
while (attempt < maxRetries)
{

try
{
// 清空接收缓冲区(避免残留数据干扰)
_serialPort.DiscardInBuffer();

_serialPort.Write(sendByte, 0, sendByte.Length);
Thread.Sleep(300);
response = new byte[_serialPort.BytesToRead];
@@ -219,7 +217,6 @@ namespace ModbusDemo.Device
{
break;
}

}
catch (Exception)
{
@@ -241,21 +238,18 @@ namespace ModbusDemo.Device
//判断发送回来的数据是否正确
if (CheckData.CheckResponse(response))
{
if (!CRCUitl.ValidateCRC(response))
{
MessageBox.Show("0x14:CRC校验错误");
}

}

}

public ushort[] ReadRegisters(byte slaveAddress, ushort startAddress, ushort numberOfPoints)
{
ushort[] resultValue = null;
if (!_serialPort.IsOpen)
{
MessageBox.Show("串口没有链接,请先链接");
return null;
return resultValue;
}
List<byte> sendByteList = new List<byte>();
//设置从站地址
@@ -275,19 +269,46 @@ namespace ModbusDemo.Device
sendByteList.Add(resultCRC[1]);

byte[] sendByte = sendByteList.ToArray();
if (_serialPort.IsOpen)
int maxRetries = 3; // 最大重试次数
int attempt = 0;
while (attempt < maxRetries)
{
// 清空接收缓冲区(避免残留数据干扰)
_serialPort.DiscardInBuffer();

_serialPort.Write(sendByte, 0, sendByte.Length);
Thread.Sleep(300);
byte[] response = new byte[_serialPort.BytesToRead];
_serialPort.Read(response, 0, _serialPort.BytesToRead);
return ParseRegistersresponse(sendByte, response, numberOfPoints);
try
{
// 清空接收缓冲区(避免残留数据干扰)
_serialPort.DiscardInBuffer();

_serialPort.Write(sendByte, 0, sendByte.Length);
Thread.Sleep(300);
byte[] response = new byte[_serialPort.BytesToRead];
_serialPort.Read(response, 0, _serialPort.BytesToRead);
if (response[0] == 0x00)
{
continue;
}
resultValue = ParseRegistersresponse(sendByte, response, numberOfPoints);
return resultValue;
}
catch (Exception)
{

attempt++;
}

}
//将操作失败的指令,插入数据库
string RequestStr = ByteArrayToString(sendByte);

ModbusLog m = new ModbusLog();
m.OperationType = "读寄存器";
m.ResponseData = "";
m.RequestData = RequestStr;
_modbusDbContext.Add(m);
_modbusDbContext.SaveChanges();
return resultValue;



return null;
}
public ushort[] ParseRegistersresponse(byte[] sendByte, byte[] response, ushort numberOfPoints)
{
@@ -302,27 +323,35 @@ namespace ModbusDemo.Device
_modbusDbContext.SaveChanges();

//判断发送回来的数据是否正确
CheckData.CheckResponse(response);
if (CheckData.CheckResponse(response))
{
ushort[] registers = new ushort[numberOfPoints];
for (int i = 0; i < numberOfPoints; i++)
{
int pos = 3 + i * 2;
// 大端序转换 (高位在前)
registers[i] = (ushort)((response[pos] << 8) | response[pos + 1]);
}

if (!CRCUitl.ValidateCRC(response))
return registers;
}
else
{
MessageBox.Show("0x14:CRC校验错误");
return null;
}

ushort[] registers = new ushort[numberOfPoints];
for (int i = 0; i < numberOfPoints; i++)
{
int pos = 3 + i * 2;
// 大端序转换 (高位在前)
registers[i] = (ushort)((response[pos] << 8) | response[pos + 1]);
}

return registers;


}

public void WriteRegisters(byte slaveAddress, ushort startAddress, ushort[] data)
{
if (!_serialPort.IsOpen)
{
MessageBox.Show("串口没有链接,请先链接");
return;
}
List<byte> sendByteList = new List<byte>();
//设置从站地址
sendByteList.Add(slaveAddress);
@@ -353,39 +382,52 @@ namespace ModbusDemo.Device
sendByteList.Add(resultCRC[0]);
sendByteList.Add(resultCRC[1]);


byte[] sendByte = sendByteList.ToArray();
if (_serialPort.IsOpen)


int maxRetries = 3; // 最大重试次数
int attempt = 0;
byte[] response = null;

while (attempt< maxRetries)
{
// 清空接收缓冲区(避免残留数据干扰)
_serialPort.DiscardInBuffer();

_serialPort.Write(sendByte, 0, sendByte.Length);
Thread.Sleep(300);
byte[] response = new byte[_serialPort.BytesToRead];
_serialPort.Read(response, 0, _serialPort.BytesToRead);

//将操作的指令,插入数据库
string RequestStr = ByteArrayToString(sendByte);
string responseStr = ByteArrayToString(response);
ModbusLog m = new ModbusLog();
m.OperationType = "写寄存器";
m.ResponseData = responseStr;
m.RequestData = responseStr;
_modbusDbContext.Add(m);
_modbusDbContext.SaveChanges();

//判断发送回来的数据是否正确
CheckData.CheckResponse(response);

if (!CRCUitl.ValidateCRC(response))
try
{
MessageBox.Show("0x14:CRC校验错误");
// 清空接收缓冲区(避免残留数据干扰)
_serialPort.DiscardInBuffer();

_serialPort.Write(sendByte, 0, sendByte.Length);
Thread.Sleep(1000);
response = new byte[_serialPort.BytesToRead];
_serialPort.Read(response, 0, _serialPort.BytesToRead);
if (response[0] != 0x00)
{
break;
}
}
catch (Exception)
{
attempt++;
}
}
//将操作的指令,插入数据库
string RequestStr = ByteArrayToString(sendByte);
string responseStr = ByteArrayToString(response);
ModbusLog m = new ModbusLog();
m.OperationType = "写寄存器";
m.ResponseData = responseStr;
m.RequestData = responseStr;
_modbusDbContext.Add(m);
_modbusDbContext.SaveChanges();

//判断发送回来的数据是否正确
CheckData.CheckResponse(response);


}


static string ByteArrayToString(byte[] byteArray)
{
if (byteArray == null || byteArray.Length == 0)


+ 1
- 1
ModbusDemo/VIewModel/CoilUCViewModel.cs 查看文件

@@ -250,7 +250,7 @@ namespace ModbusDemo.VIewModel
}
else
{
MessageBox.Show("WriteData 格式无效", "error", MessageBoxButton.OK, MessageBoxImage.Error);
MessageBox.Show("写入失败", "error", MessageBoxButton.OK, MessageBoxImage.Error);
}
});



+ 74
- 31
ModbusDemo/VIewModel/RegisterUCViewModel.cs 查看文件

@@ -12,7 +12,7 @@ using System.Windows;

namespace ModbusDemo.VIewModel
{
class RegisterUCViewModel:BindableBase
class RegisterUCViewModel : BindableBase
{
//定义数据库操作类
private ModbusDbContext _modbusDbContext;
@@ -147,9 +147,9 @@ namespace ModbusDemo.VIewModel

public RegisterUCViewModel()
{
}
public RegisterUCViewModel(SerialPort serialPort, ModbusRTU modbusRTU,ModbusDbContext modbusDbContext)
public RegisterUCViewModel(SerialPort serialPort, ModbusRTU modbusRTU, ModbusDbContext modbusDbContext)
{
_serialPort = serialPort;
ReadRegisterCmm = new DelegateCommand(ReadRegister);
@@ -161,7 +161,7 @@ namespace ModbusDemo.VIewModel

}



/// <summary>
@@ -169,31 +169,65 @@ namespace ModbusDemo.VIewModel
/// </summary>
private void ReadRegister()
{
try
if (!byte.TryParse(SlaveAddress, out byte slaveAddressValue))
{
ushort[] result = _modbusRTU.ReadRegisters(byte.Parse(SlaveAddress),
ushort.Parse(StartAddress),
ushort.Parse(NumberOfPoints));
if (result != null)
{
string temp = "";
foreach (var item in result)
{
temp += item;
temp += " ";
}
ReadResult = temp;
}
MessageBox.Show("SlaveAddress 格式无效", "warning", MessageBoxButton.OK, MessageBoxImage.Warning);
return;
}
catch (Exception)

if (!ushort.TryParse(StartAddress, out ushort startAddressValue))
{
MessageBox.Show("StartAddress 格式无效", "warning", MessageBoxButton.OK, MessageBoxImage.Warning);
return;
}

MessageBox.Show("参数配置错误");
if (!ushort.TryParse(NumberOfPoints, out ushort numberOfPointsValue))
{
MessageBox.Show("NumberOfPoints 格式无效", "warning", MessageBoxButton.OK, MessageBoxImage.Warning);
return;
}
//使用子线程进行读取,防止ui线程卡顿
Task.Run(() =>
{
ushort[] result = _modbusRTU.ReadRegisters(slaveAddressValue, startAddressValue, numberOfPointsValue);
if (result == null)
{
MessageBox.Show("读取失败", "error", MessageBoxButton.OK, MessageBoxImage.Error);
ModbusLogList = GetOperateRegister();
return;
}
string temp = "";
foreach (var item in result)
{
temp += item;
temp += " ";
}
ReadResult = temp;
MessageBox.Show("读取成功");
ModbusLogList = GetOperateRegister();
});

}



private void WriteRegister()
{
if (!byte.TryParse(WriteSlaveAddress, out byte writeSlaveAddressValue))
{
MessageBox.Show("WriteSlaveAddress 格式无效", "warning", MessageBoxButton.OK, MessageBoxImage.Warning);
return;
}
if (!ushort.TryParse(WriteStartAddress, out ushort WriteStartAddressValue))
{
MessageBox.Show("WriteStartAddress 格式无效", "warning", MessageBoxButton.OK, MessageBoxImage.Warning);
return;
}
if (string.IsNullOrEmpty(WriteData))
{
MessageBox.Show("WriteData 格式无效", "warning", MessageBoxButton.OK, MessageBoxImage.Warning);
return;
}
string[] parts = WriteData.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
// 3. 创建结果数组
ushort[] data = new ushort[parts.Length];
@@ -208,22 +242,31 @@ namespace ModbusDemo.VIewModel
}
else
{
// 处理解析失败的情况
throw new FormatException($"无法将 '{parts[i]}' 转换为 ushort 类型");

MessageBox.Show($"无法将 '{parts[i]}' 转换为 ushort 类型");
return;
}
}

try
{
_modbusRTU.WriteRegisters(byte.Parse(WriteSlaveAddress),
ushort.Parse(WriteStartAddress),
data);
}
catch (Exception)
//使用子线程来去执行操作,防止ui线程卡顿
Task.Run(() =>
{
_modbusRTU.WriteRegisters(writeSlaveAddressValue, WriteStartAddressValue, data);
ModbusLogList = GetOperateRegister();
ModbusLog modbusLog = ModbusLogList.FirstOrDefault();
if (modbusLog != null && modbusLog.ResponseData != string.Empty)
{
MessageBox.Show("写入成功");

}
else
{
MessageBox.Show("写入失败", "error", MessageBoxButton.OK, MessageBoxImage.Error);
}
});


MessageBox.Show("信息配置错误");
}

}
/// <summary>


正在加载...
取消
保存