使用c#编写的Modbus TCP通讯软件示例:
时间: 2024-03-23 09:40:45 浏览: 85
下面是一个使用C#编写的Modbus TCP通讯软件示例:
```csharp
using System;
using System.Net.Sockets;
// Modbus TCP帧结构
class ModbusTCPFrame
{
public ushort TransactionId { get; set; }
public ushort ProtocolId { get; set; }
public ushort Length { get; set; }
public byte UnitId { get; set; }
public byte FunctionCode { get; set; }
public byte[] Data { get; set; }
// 将Modbus TCP帧转换为字节数组
public byte[] ToBytes()
{
byte[] buffer = new byte[12 + Data.Length];
BitConverter.GetBytes(TransactionId).CopyTo(buffer, 0);
BitConverter.GetBytes(ProtocolId).CopyTo(buffer, 2);
BitConverter.GetBytes(Length).CopyTo(buffer, 4);
buffer[6] = UnitId;
buffer[7] = FunctionCode;
Data.CopyTo(buffer, 8);
return buffer;
}
// 从字节数组解析Modbus TCP帧
public static ModbusTCPFrame FromBytes(byte[] buffer)
{
ModbusTCPFrame frame = new ModbusTCPFrame();
frame.TransactionId = BitConverter.ToUInt16(buffer, 0);
frame.ProtocolId = BitConverter.ToUInt16(buffer, 2);
frame.Length = BitConverter.ToUInt16(buffer, 4);
frame.UnitId = buffer[6];
frame.FunctionCode = buffer[7];
frame.Data = new byte[frame.Length - 1];
Array.Copy(buffer, 8, frame.Data, 0, frame.Length - 1);
return frame;
}
}
// Modbus TCP客户端
class ModbusTCPClient
{
private TcpClient client;
private NetworkStream stream;
private byte unitId;
public ModbusTCPClient(string host, int port, byte unitId)
{
client = new TcpClient(host, port);
stream = client.GetStream();
this.unitId = unitId;
}
// 发送Modbus TCP请求并接收响应
private byte[] SendRequest(byte functionCode, byte[] data)
{
ModbusTCPFrame frame = new ModbusTCPFrame();
frame.TransactionId = 0;
frame.ProtocolId = 0;
frame.Length = (ushort)(data.Length + 1);
frame.UnitId = unitId;
frame.FunctionCode = functionCode;
frame.Data = data;
byte[] buffer = frame.ToBytes();
stream.Write(buffer, 0, buffer.Length);
buffer = new byte[1024];
int count = stream.Read(buffer, 0, buffer.Length);
Array.Resize(ref buffer, count);
frame = ModbusTCPFrame.FromBytes(buffer);
return frame.Data;
}
// 读取线圈状态
public bool[] ReadCoils(ushort address, ushort count)
{
byte[] data = new byte[4];
BitConverter.GetBytes(address).CopyTo(data, 0);
BitConverter.GetBytes(count).CopyTo(data, 2);
byte[] response_data = SendRequest(0x01, data);
bool[] coils = new bool[count];
for (int i = 0; i < count; i++)
{
coils[i] = (response_data[i / 8] & (1 << (i % 8))) != 0;
}
return coils;
}
// 写入单个线圈状态
public void WriteCoil(ushort address, bool value)
{
byte[] data = new byte[4];
BitConverter.GetBytes(address).CopyTo(data, 0);
BitConverter.GetBytes(value ? (ushort)0xFF00 : (ushort)0x0000).CopyTo(data, 2);
SendRequest(0x05, data);
}
// 读取保持寄存器
public ushort[] ReadHoldingRegisters(ushort address, ushort count)
{
byte[] data = new byte[4];
BitConverter.GetBytes(address).CopyTo(data, 0);
BitConverter.GetBytes(count).CopyTo(data, 2);
byte[] response_data = SendRequest(0x03, data);
ushort[] registers = new ushort[count];
for (int i = 0; i < count; i++)
{
registers[i] = BitConverter.ToUInt16(response_data, i * 2);
}
return registers;
}
// 写入单个保持寄存器
public void WriteHoldingRegister(ushort address, ushort value)
{
byte[] data = new byte[4];
BitConverter.GetBytes(address).CopyTo(data, 0);
BitConverter.GetBytes(value).CopyTo(data, 2);
SendRequest(0x06, data);
}
// 关闭连接
public void Close()
{
stream.Close();
client.Close();
}
}
```
使用该Modbus TCP客户端可以进行读写线圈状态和保持寄存器的操作。例如,读取保持寄存器可以使用以下代码:
```csharp
ModbusTCPClient client = new ModbusTCPClient("192.168.1.10", 502, 1);
ushort[] registers = client.ReadHoldingRegisters(0x0000, 8);
client.Close();
foreach (ushort register in registers)
{
Console.WriteLine(register);
}
```
其中,`192.168.1.10`是Modbus TCP从设备的IP地址,`502`是Modbus TCP从设备的端口号,`1`是Modbus TCP从设备的设备地址,`0x0000`是保持寄存器地址,`8`是读取的保持寄存器数量。
阅读全文