当前位置: 首页 > news >正文

C#实现Modbus TCP通讯测试软件

一、环境搭建与依赖配置

  1. 开发环境

    • Visual Studio 2022+
    • .NET 6.0+
    • NuGet包:NModbus(协议实现)、MaterialDesignThemes(UI美化)
  2. 项目结构

    ModbusTester/
    ├── Models/              # 数据模型
    ├── Views/               # WPF界面
    ├── ViewModels/          # MVVM逻辑
    ├── Services/            # 通信服务
    └── Utils/               # 工具类(CRC校验、日志)
    

二、核心代码实现

1. Modbus TCP服务类(基于NModbus)

// Services/ModbusService.cs
using Modbus.Device;
using System.Net.Sockets;public class ModbusTcpService : IDisposable
{private ModbusIpMaster _master;private TcpClient _tcpClient;public async Task ConnectAsync(string ip, int port = 502){_tcpClient = new TcpClient();await _tcpClient.ConnectAsync(ip, port);_master = ModbusIpMaster.CreateIp(_tcpClient);}// 读取保持寄存器(功能码03)public ushort[] ReadHoldingRegisters(ushort startAddr, ushort count){return _master.ReadHoldingRegisters(1, startAddr, count); // 从站ID默认1}// 写入单个寄存器(功能码06)public void WriteSingleRegister(ushort addr, ushort value){_master.WriteSingleRegister(1, addr, value);}// 批量写入寄存器(功能码16)public void WriteMultipleRegisters(ushort startAddr, ushort[] values){_master.WriteMultipleRegisters(1, startAddr, values);}public void Dispose(){_master?.Dispose();_tcpClient?.Close();}
}

2. 数据模型设计

// Models/ModbusDataModel.cs
public class ModbusDataModel : INotifyPropertyChanged
{private ushort _registerValue;public ushort RegisterValue{get => _registerValue;set{_registerValue = value;OnPropertyChanged(nameof(RegisterValue));}}public event PropertyChangedEventHandler PropertyChanged;protected virtual void OnPropertyChanged(string propertyName) =>PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}

三、WPF界面实现

1. 主界面XAML(核心功能区)

<!-- Views/MainView.xaml -->
<Window x:Class="ModbusTester.Views.MainView"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"Title="Modbus TCP测试工具" Height="450" Width="800"><Grid><!-- 连接配置区 --><GroupBox Header="连接配置" Margin="10"><StackPanel Orientation="Vertical"><TextBox x:Name="txtIP" Width="200" materialDesign:HintAssist.Hint="IP地址"/><TextBox x:Name="txtPort" Width="100" materialDesign:HintAssist.Hint="端口"/><Button Content="连接" Command="{Binding ConnectCommand}"/></StackPanel></GroupBox><!-- 数据操作区 --><GroupBox Header="数据操作" Margin="10,120,10,10"><StackPanel Orientation="Vertical"><TextBox x:Name="txtStartAddr" Width="100" materialDesign:HintAssist.Hint="起始地址"/><TextBox x:Name="txtCount" Width="100" materialDesign:HintAssist.Hint="数量"/><Button Content="读取寄存器" Command="{Binding ReadRegistersCommand}"/><DataGrid ItemsSource="{Binding Registers}" AutoGenerateColumns="False"><DataGrid.Columns><DataGridTextColumn Header="地址" Binding="{Binding Address}"/><DataGridTextColumn Header="值" Binding="{Binding Value}"/></DataGrid.Columns></DataGrid></StackPanel></GroupBox></Grid>
</Window>

2. ViewModel逻辑绑定

// ViewModels/MainViewModel.cs
using MaterialDesignThemes.Wpf;
using System.Windows.Input;public class MainViewModel : ObservableObject
{private readonly ModbusTcpService _modbusService = new ModbusTcpService();public ObservableCollection<ModbusDataModel> Registers { get; } = new();public ICommand ConnectCommand => new RelayCommand(async () => {await _modbusService.ConnectAsync(txtIP.Text, int.Parse(txtPort.Text));ReadRegisters();});public ICommand ReadRegistersCommand => new RelayCommand(() =>{var values = _modbusService.ReadHoldingRegisters(0, 10); // 读取0-9号寄存器Registers.Clear();for (int i = 0; i < values.Length; i++){Registers.Add(new ModbusDataModel { Address = 0 + i, Value = values[i] });}});private void ReadRegisters(){// 异步读取逻辑}
}

四、关键调试

  1. CRC校验验证

    // 工具类方法
    public static byte[] CalculateCrc(byte[] data)
    {ushort crc = 0xFFFF;foreach (byte b in data){crc ^= (ushort)b;for (int i = 0; i < 8; i++){if ((crc & 0x0001) != 0)crc >>= 1;elsecrc = (ushort)((crc >> 1) ^ 0xA001);}}return new[] { (byte)crc, (byte)(crc >> 8) };
    }
    
  2. 异常处理策略

    try
    {await _modbusService.ConnectAsync(ip, port);
    }
    catch (SocketException ex)
    {ShowErrorMessage($"连接失败:{ex.Message}");Log.Error(ex, "网络连接异常");
    }
    
  3. 性能优化

    • 连接池管理:复用TcpClient实例
    • 批量操作:使用WriteMultipleRegisters替代多次单次写入
    • 异步处理:通过async/await避免界面冻结

五、扩展功能实现

  1. 数据曲线监控

    // 使用LiveCharts库
    public SeriesCollection TemperatureSeries { get; } = new();// 实时更新数据
    private void UpdateChart(double value)
    {TemperatureSeries.Add(new LineSeries{Values = new ChartValues<double> { value }});
    }
    
  2. 十六进制查看器

    // 显示原始Modbus报文
    public string HexDisplay
    {get{return BitConverter.ToString(data).Replace("-", "");}
    }
    

参考代码 C#实现Modbus TCP 通讯测试软件 www.youwenfan.com/contentcnq/111967.html

六、测试用例示例

测试场景 输入参数 预期结果
读取保持寄存器 IP=192.168.1.100, Port=502, 地址=0, 数量=10 返回10个寄存器的16进制值
写入单个寄存器 地址=40001, 值=25 寄存器值变为25(0x19)
批量写入 地址=40002, 值数组= 三个寄存器依次写入成功

七、部署建议

  1. 依赖项打包

    • 使用ILMerge合并DLL文件
    • 包含NModbus许可证文件
  2. 安装包制作

    # 使用Inno Setup创建安装程序
    [Files]
    Source: "ModbusTester.exe"; DestDir: "{app}"; Flags: ignoreversion
    Source: "NModbus.dll"; DestDir: "{app}"; Flags: ignoreversion
    
http://www.jsqmd.com/news/336714/

相关文章:

  • 2026挖掘机培训行业报告:西北地区实训基地选择与就业前景解析 - 深度智识库
  • 支持单列、多列等布局自定义表单系统源码 带完整的搭建部署教程
  • leetcode 889. Construct Binary Tree from Preorder and Postorder Traversal 根据前序和后序遍历构造二叉树
  • 2026少儿编程品牌怎么选?十大品牌综合实力榜出炉!为家长提供专业参考 - 匠言榜单
  • 脊柱外科手术显微镜哪家好?深度盘点新天医疗等六家代表企业 - 企师傅推荐官
  • 前特斯拉 AI 总监:AI 编程最大的谎言,是 “提效”
  • 支持在线收款的自定义表单系统源码
  • 2026年耐火材料厂家最新推荐榜:耐火砖/高铝砖/刚玉砖/磷酸盐砖等类型优质厂家权威榜单发布保温砖/浇注料/可塑料/莫来石砖厂家推荐 - 深度智识库
  • 2026年湖北纸塑复合袋定制服务商综合实力深度解析 - 2026年企业推荐榜
  • 2026挖掘机培训学校深度测评:如何选对学校,开启高薪职业生涯 - 深度智识库
  • 灵活自定义表单系统源码,满足多样化业务需求的终极工具
  • 2026年目前有名的推拉窗品牌推荐,推拉窗/侧压平移推拉窗/平移断桥提升窗/断桥铝门窗,推拉窗实力厂家有哪些 - 品牌推荐师
  • USACO历年青铜组真题解析 | 2023年2月
  • 2026年山西文博展柜机构综合实力TOP5盘点 - 2026年企业推荐榜
  • 国产大模型适配优选,MonkeyCode 赋能企业研发
  • 【瑞芯微平台实时Linux方案系列】第二十五篇 - 瑞芯微平台实时Linux驱动开发规范与实践
  • OpenCSG(开放传神)赋能商业银行:三网隔离下的大模型资产跨网治理与复用
  • SSM毕设选题推荐:基于ssm的城市生活e家物业管理平台的设计与开发【附源码、mysql、文档、调试+代码讲解+全bao等】
  • 【录用率高,见刊快,检索稳定 | IEEE Fellow国际化组委】第二届健康信息化与数据分析国际学术会议(HIDA 2026)
  • 计算机SSM毕设实战-基于SSM架构的物业管理系统的设计与实现基于ssm的城市生活e家平台的设计与开发【完整源码+LW+部署说明+演示视频,全bao一条龙等】
  • 洛轲智能千匠网络:打造跨境B2B商城,启航海外分销新生态 - 圆圆小达人
  • Python之面向对象详解(一篇足矣)
  • P0904AK桌面接口模块
  • 推荐一个神器!画股票K线图这么简单!这个宝藏库让我爱不释手!
  • P0973BP冗余电源模块
  • C++ 模板初级:函数 / 类模板 + 实例化 + 匹配原则全讲透
  • 【瑞芯微平台实时Linux方案系列】第二十四篇 - 瑞芯微平台实时Linux异构计算协同方案
  • SSM毕设选题推荐:基于ssm的中小学生阅读能力培养系统阅读能力训练平台【附源码、mysql、文档、调试+代码讲解+全bao等】
  • Ivanti 提醒注意已遭利用的两个 EPMM 漏洞
  • 数眼智能实战指南:3 大核心场景落地,解锁多模态数据处理效率密码