From bf15605454640e3915fb78a89aea5c1ee8a842d0 Mon Sep 17 00:00:00 2001 From: zhangyongpan Date: Sun, 27 Jul 2025 13:38:44 +0800 Subject: [PATCH] =?UTF-8?q?=E5=86=99=E5=A4=9A=E4=B8=AA=E5=AF=84=E5=AD=98?= =?UTF-8?q?=E5=99=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ModbusDemo/Device/IModbusRTU.cs | 3 + ModbusDemo/Device/ModbusRTU.cs | 61 ++++++++++++++++++++- ModbusDemo/VIew/CoilUC.xaml | 18 ++++-- ModbusDemo/VIewModel/RegisterUCViewModel.cs | 24 ++++++-- 4 files changed, 92 insertions(+), 14 deletions(-) diff --git a/ModbusDemo/Device/IModbusRTU.cs b/ModbusDemo/Device/IModbusRTU.cs index 250c8d5..0a0a0bf 100644 --- a/ModbusDemo/Device/IModbusRTU.cs +++ b/ModbusDemo/Device/IModbusRTU.cs @@ -15,5 +15,8 @@ namespace ModbusDemo.Device public ushort[] ReadRegisters(byte slaveAddress, ushort startAddress, ushort numberOfPoints); + + public void WriteRegisters(byte slaveAddress, ushort startAddress, ushort[] data); + } } diff --git a/ModbusDemo/Device/ModbusRTU.cs b/ModbusDemo/Device/ModbusRTU.cs index aee8904..4eaacfc 100644 --- a/ModbusDemo/Device/ModbusRTU.cs +++ b/ModbusDemo/Device/ModbusRTU.cs @@ -58,7 +58,7 @@ namespace ModbusDemo.Device Thread.Sleep(300); byte[] response = new byte[_serialPort.BytesToRead]; _serialPort.Read(response, 0, _serialPort.BytesToRead); - return ParseCoilresponse(response,numberOfPoints); + return ParseCoilresponse(response, numberOfPoints); } @@ -170,12 +170,12 @@ namespace ModbusDemo.Device if (!CRCUitl.ValidateCRC(response)) { MessageBox.Show("0x14:CRC校验错误"); - + } } - + } public ushort[] ReadRegisters(byte slaveAddress, ushort startAddress, ushort numberOfPoints) @@ -238,5 +238,60 @@ namespace ModbusDemo.Device return registers; } + + public void WriteRegisters(byte slaveAddress, ushort startAddress, ushort[] data) + { + List sendByteList = new List(); + //设置从站地址 + sendByteList.Add(slaveAddress); + //设置功能码 + sendByteList.Add(0x10); + //设置起始地址的高位和低位 + sendByteList.Add(BitConverter.GetBytes(startAddress)[1]); + sendByteList.Add(BitConverter.GetBytes(startAddress)[0]); + //设置写入几个线圈 + sendByteList.Add(BitConverter.GetBytes(data.Length)[1]); + sendByteList.Add(BitConverter.GetBytes(data.Length)[0]); + + // 计算字节数 + int byteCount = (data.Length + 7) / 8; + sendByteList.Add((byte)byteCount); + + foreach (ushort value in data) + { + byte[] valueBytes = BitConverter.GetBytes(value); + // 大端序:高字节在前,低字节在后 + sendByteList.Add(valueBytes[1]); + sendByteList.Add(valueBytes[0]); + } + + //获取CRC校验码 + byte[] getCRC = sendByteList.ToArray(); + byte[] resultCRC = CRCUitl.CalculateCRC(getCRC, getCRC.Length); + sendByteList.Add(resultCRC[0]); + sendByteList.Add(resultCRC[1]); + + + byte[] sendByte = sendByteList.ToArray(); + if (_serialPort.IsOpen) + { + // 清空接收缓冲区(避免残留数据干扰) + _serialPort.DiscardInBuffer(); + + _serialPort.Write(sendByte, 0, sendByte.Length); + Thread.Sleep(300); + byte[] response = new byte[_serialPort.BytesToRead]; + _serialPort.Read(response, 0, _serialPort.BytesToRead); + + //判断发送回来的数据是否正确 + CheckData.CheckResponse(response); + + if (!CRCUitl.ValidateCRC(response)) + { + MessageBox.Show("0x14:CRC校验错误"); + + } + } + } } } diff --git a/ModbusDemo/VIew/CoilUC.xaml b/ModbusDemo/VIew/CoilUC.xaml index db83084..10f4142 100644 --- a/ModbusDemo/VIew/CoilUC.xaml +++ b/ModbusDemo/VIew/CoilUC.xaml @@ -15,8 +15,8 @@ mc:Ignorable="d"> @@ -52,8 +52,10 @@ - - + + + + @@ -78,9 +80,9 @@ - + - + + + + + diff --git a/ModbusDemo/VIewModel/RegisterUCViewModel.cs b/ModbusDemo/VIewModel/RegisterUCViewModel.cs index dbf94e9..a267095 100644 --- a/ModbusDemo/VIewModel/RegisterUCViewModel.cs +++ b/ModbusDemo/VIewModel/RegisterUCViewModel.cs @@ -176,14 +176,28 @@ namespace ModbusDemo.VIewModel } private void WriteRegister() { - //去除字符串中的空格 - WriteData = WriteData.Replace(" ", ""); - //转换为布尔数组 - bool[] data = WriteData.Select(m => m == '1').ToArray(); + string[] parts = WriteData.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); + // 3. 创建结果数组 + ushort[] data = new ushort[parts.Length]; + + // 4. 遍历并转换每个部分 + for (int i = 0; i < parts.Length; i++) + { + // 尝试解析为ushort + if (ushort.TryParse(parts[i], out ushort value)) + { + data[i] = value; + } + else + { + // 处理解析失败的情况 + throw new FormatException($"无法将 '{parts[i]}' 转换为 ushort 类型"); + } + } try { - _modbusRTU.WriteCoil(byte.Parse(WriteSlaveAddress), + _modbusRTU.WriteRegisters(byte.Parse(WriteSlaveAddress), ushort.Parse(WriteStartAddress), data); }