c# modbusRTU写多个寄存器代码
时间: 2023-10-10 22:16:05 浏览: 247
以下是使用 C# 编写的 Modbus RTU 协议写多个寄存器的示例代码:
```csharp
using System;
using System.IO.Ports;
namespace ModbusRTU_Write_Multiple_Registers
{
class Program
{
static void Main(string[] args)
{
SerialPort port = new SerialPort("COM1", 9600, Parity.None, 8, StopBits.One);
port.Open();
// Modbus RTU 请求帧
byte slaveAddress = 1; // 从站地址
byte functionCode = 16; // 功能码,16 表示写多个寄存器
ushort startingAddress = 0; // 起始地址,从 0 开始
ushort numberOfRegisters = 3; // 写入的寄存器数量
byte byteCount = (byte)(numberOfRegisters * 2); // 字节数,每个寄存器占用 2 字节
byte[] data = new byte[byteCount]; // 写入的数据
ushort[] values = new ushort[] { 100, 200, 300 }; // 写入的值
for (int i = 0; i < numberOfRegisters; i++)
{
byte[] bytes = BitConverter.GetBytes(values[i]);
data[i * 2] = bytes[1];
data[i * 2 + 1] = bytes[0];
}
byte[] requestFrame = new byte[7 + byteCount];
requestFrame[0] = slaveAddress;
requestFrame[1] = functionCode;
requestFrame[2] = (byte)(startingAddress >> 8);
requestFrame[3] = (byte)startingAddress;
requestFrame[4] = (byte)(numberOfRegisters >> 8);
requestFrame[5] = (byte)numberOfRegisters;
requestFrame[6] = byteCount;
Array.Copy(data, 0, requestFrame, 7, byteCount);
// 计算 CRC 校验码
ushort crc = ModbusRTU.CalculateCRC(requestFrame, 0, requestFrame.Length - 2);
requestFrame[requestFrame.Length - 2] = (byte)(crc & 0xFF);
requestFrame[requestFrame.Length - 1] = (byte)(crc >> 8);
// 发送请求帧
port.Write(requestFrame, 0, requestFrame.Length);
// 接收响应帧
byte[] responseFrame = new byte[8];
int bytesRead = port.Read(responseFrame, 0, responseFrame.Length);
if (bytesRead == responseFrame.Length)
{
// 校验响应帧的地址、功能码和字节数是否与请求帧相同
if (responseFrame[0] == slaveAddress && responseFrame[1] == functionCode && responseFrame[2] == byteCount)
{
// 解析响应帧的 CRC 校验码
ushort actualCRC = (ushort)(responseFrame[responseFrame.Length - 1] << 8 | responseFrame[responseFrame.Length - 2]);
ushort expectedCRC = ModbusRTU.CalculateCRC(responseFrame, 0, responseFrame.Length - 2);
if (actualCRC == expectedCRC)
{
Console.WriteLine("写入多个寄存器成功!");
}
else
{
Console.WriteLine("CRC 校验错误!");
}
}
else
{
Console.WriteLine("响应帧错误!");
}
}
else
{
Console.WriteLine("接收响应帧失败!");
}
port.Close();
}
}
public static class ModbusRTU
{
// 计算 CRC 校验码
public static ushort CalculateCRC(byte[] bytes, int offset, int count)
{
ushort crc = 0xFFFF;
for (int i = offset; i < offset + count; i++)
{
crc ^= bytes[i];
for (int j = 0; j < 8; j++)
{
if ((crc & 0x0001) == 0x0001)
{
crc >>= 1;
crc ^= 0xA001;
}
else
{
crc >>= 1;
}
}
}
return crc;
}
}
}
```
该示例代码使用了 .NET Framework 自带的 `SerialPort` 类来打开串口,然后构造 Modbus RTU 请求帧,发送给从站设备,接收从站设备返回的 Modbus RTU 响应帧,并校验 CRC 校验码。如果 CRC 校验码正确,则表示写入多个寄存器成功。
阅读全文