public class ModbusTcpSlaveDemo : IDisposable
{
ILogger _Logger;
public ModbusTcpSlaveDemo(ILogger<ModbusTcpSlaveDemo> logger)
{
_Logger = logger;
Start();
}
#region Modbus TCP 从站实现
private TcpListener _listener;
private ModbusSlave _slave;
private bool _isRunning;
public byte SlaveId { get; set; } = 1;
public int Port { get; set; } = 502;
public void Start()
{
if (_isRunning) return;
try
{
// 创建TCP监听器
_listener = new TcpListener(IPAddress.Any, Port);
_listener.Start();
// 创建Modbus TCP从站
_slave = ModbusTcpSlave.CreateTcp(SlaveId, _listener);
// 初始化测试数据到Modbus数据存储
InitializeTestData();
// 启动从站
_slave.Listen();
_isRunning = true;
_Logger.LogInformation($"Modbus TCP从机启动成功");
_Logger.LogInformation($"从站ID: {SlaveId}, 端口: {Port}");
PrintTestDataInfo();
}
catch (Exception ex)
{
_Logger.LogError(ex, $"Modbus TCP从机启动失败");
throw;
}
}
private void InitializeTestData()
{
// 获取数据存储
var dataStore = _slave.DataStore;
// 初始化保持寄存器 (地址 1-9) - 使用正确的API
for (ushort i = 1; i < 10; i++)
{
dataStore.HoldingRegisters[i] = (ushort)((i + 1) * 100);
}
// 初始化输入寄存器 (地址 1-9)
for (ushort i = 1; i < 10; i++)
{
dataStore.InputRegisters[i] = (ushort)((i + 1) * 50);
}
for (ushort i = 1; i < 10; i++)
{
dataStore.CoilDiscretes[i] = (i % 2 == 0);
}
}
private void PrintTestDataInfo()
{
var dataStore = _slave.DataStore;
_Logger.LogInformation("测试数据已设置:");
// 读取并显示保持寄存器
var holdingValues = new List<string>();
for (int i = 1; i < 5; i++)
{
holdingValues.Add(dataStore.HoldingRegisters[i].ToString());
}
_Logger.LogInformation($"保持寄存器 (地址0-4): {string.Join(", ", holdingValues)}");
// 读取并显示输入寄存器
var inputValues = new List<string>();
for (int i = 1; i < 5; i++)
{
inputValues.Add(dataStore.InputRegisters[i].ToString());
}
_Logger.LogInformation($"输入寄存器 (地址0-4): {string.Join(", ", inputValues)}");
// 读取并显示线圈
var coilValues = new List<string>();
for (int i = 1; i < 5; i++)
{
coilValues.Add(dataStore.CoilDiscretes[i] ? "ON" : "OFF");
}
_Logger.LogInformation($"线圈 (地址0-4): {string.Join(", ", coilValues)}");
}
public void UpdateHoldingRegister(ushort address, ushort value)
{
if (_isRunning)
{
_slave.DataStore.HoldingRegisters[address] = value;
_Logger.LogInformation($"更新保持寄存器地址{address} = {value}");
}
}
public ushort ReadHoldingRegister(ushort address)
{
if (_isRunning)
{
return _slave.DataStore.HoldingRegisters[address];
}
return 0;
}
public void UpdateCoil(ushort address, bool value)
{
if (_isRunning)
{
_slave.DataStore.CoilDiscretes[address] = value;
_Logger.LogInformation($"更新线圈地址{address} = {(value ? "ON" : "OFF")}");
}
}
public bool ReadCoil(ushort address)
{
if (_isRunning)
{
return _slave.DataStore.CoilDiscretes[address];
}
return false;
}
public void Stop()
{
if (!_isRunning) return;
try
{
_listener?.Stop();
_isRunning = false;
_Logger.LogInformation("Modbus TCP从机已停止");
}
catch (Exception ex)
{
_Logger.LogError(ex, "停止Modbus从机时出错");
}
}
public void Dispose()
{
Stop();
}
#endregion
}