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

基于C#和周立功USBCAN设备的完整上位机开发示例

一、环境配置

  1. 驱动安装

    • 下载安装ZLG官方驱动(需区分x86/x64)

    • 确保zlgcan.dll位于应用程序目录或系统PATH

  2. NuGet依赖

    dotnet add package CanKit.Core
    dotnet add package CanKit.Adapter.ZLG
    

二、核心代码实现

1. 设备管理类(DeviceManager.cs)

using CanKit.Core;
using CanKit.Core.Definitions;
using CanKit.Adapter.ZLG;
using System;
using System.Threading.Tasks;public class DeviceManager : IDisposable
{private ICanBus _bus;private readonly string _deviceId = "zlg://ZCAN_USBCANFD_200U?index=0#ch0";private const int BaudRate = 500_000; // 500kbpspublic event Action<CanFrame> FrameReceived;public event Action<string> StatusChanged;public async Task ConnectAsync(){try{_bus = await CanBus.OpenAsync(_deviceId, cfg => cfg.TimingClassic(BaudRate).EnableErrorInfo().SetAsyncBufferCapacity(512));_bus.FrameReceived += OnFrameReceived;StatusChanged?.Invoke("设备已连接");}catch (Exception ex){HandleError($"连接失败: {ex.Message}");}}private void OnFrameReceived(object sender, CanFrameReceivedEventArgs e){FrameReceived?.Invoke(e.Frame);}public async Task SendTestFrameAsync(){var frame = new CanClassicFrame(id: 0x123,data: new byte[] { 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88 },timestamp: DateTimeOffset.Now.ToUnixTimeMilliseconds());await _bus.TransmitAsync(frame);}public void Disconnect(){_bus?.Close();StatusChanged?.Invoke("设备已断开");}private void HandleError(string message){StatusChanged?.Invoke($"错误: {message}");// 记录日志到文件File.AppendAllText("error.log", $"{DateTime.Now}: {message}\n");}public void Dispose(){_bus?.Dispose();}
}

三、用户界面实现(WPF示例)

1. 主窗口XAML

<Window x:Class="USBCANApp.MainWindow"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"Title="USBCAN上位机" Height="600" Width="1200"><DockPanel><!-- 状态栏 --><StatusBar DockPanel.Dock="Bottom"><TextBlock Text="{Binding Status}" Margin="5"/></StatusBar><!-- 数据监控区 --><TabControl><TabItem Header="实时数据"><DataGrid AutoGenerateColumns="False" ItemsSource="{Binding Frames}"><DataGrid.Columns><DataGridTextColumn Header="时间戳" Binding="{Binding Timestamp}"/><DataGridTextColumn Header="ID" Binding="{Binding Id:X}"/><DataGridTextColumn Header="数据" Binding="{Binding Data}"/></DataGrid.Columns></DataGrid></TabItem></TabControl><!-- 控制面板 --><StackPanel Orientation="Horizontal" VerticalAlignment="Top" DockPanel.Dock="Top"><Button Content="连接设备" Command="{Binding ConnectCommand}"/><Button Content="发送测试帧" Command="{Binding SendTestCommand}"/><Button Content="断开连接" Command="{Binding DisconnectCommand}"/></StackPanel></DockPanel>
</Window>

2. ViewModel实现

using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Runtime.CompilerServices;public class MainViewModel : INotifyPropertyChanged
{private readonly DeviceManager _deviceManager = new DeviceManager();public ObservableCollection<CanFrame> Frames { get; } = new();public string Status { get; private set; } = "未连接";public ICommand ConnectCommand => new RelayCommand(async () => await ConnectAsync());public ICommand SendTestCommand => new RelayCommand(async () => await SendTestAsync());public ICommand DisconnectCommand => new RelayCommand(() => Disconnect());public MainViewModel(){_deviceManager.FrameReceived += OnFrameReceived;_deviceManager.StatusChanged += OnStatusChanged;}private async Task ConnectAsync(){await _deviceManager.ConnectAsync();Status = "已连接";}private async Task SendTestAsync(){await _deviceManager.SendTestFrameAsync();}private void Disconnect(){_deviceManager.Disconnect();Status = "已断开";}private void OnFrameReceived(CanFrame frame){Frames.Add(frame);}private void OnStatusChanged(string status){Status = status;}public event PropertyChangedEventHandler PropertyChanged;protected void OnPropertyChanged([CallerMemberName] string? propertyName = null){PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));}
}

四、关键功能扩展

1. CAN FD支持

// 修改连接配置
var config = new ZCANChannelConfig
{canfd = new ZCAN_FDConfig{mode = ZCAN_FDMode.FD,nominal_bitrate = 5_000_000, // 5Mbpsdata_bitrate = 20_000_000    // 20Mbps}
};
await _bus.OpenAsync(_deviceId, config);

2. 数据滤波配置

// 添加范围滤波
_config.RangeFilter = new RangeFilter
{StartId = 0x100,EndId = 0x1FF,FilterType = FilterType.Standard
};// 或使用掩码滤波
_config.MaskFilter = new MaskFilter
{Acr = 0x18FF50E5,Amr = 0x1FFFFF00
};

3. 周期发送任务

var periodicTask = _bus.SchedulePeriodic(new CanClassicFrame(0x321, new byte[] { 0xAA, 0x55 }),interval: TimeSpan.FromMilliseconds(100)
);// 停止周期任务
periodicTask.Stop();

五、错误处理机制

1. 异常捕获

try
{await _bus.TransmitAsync(frame);
}
catch (CanTimeoutException ex)
{LogError($"发送超时: {ex.Message}");
}
catch (CanProtocolException ex)
{LogError($"协议错误: {ex.Message}");
}

2. 错误帧订阅

_bus.ErrorFrameReceived += (sender, error) =>
{var errorInfo = new StringBuilder();errorInfo.AppendLine($"错误码: 0x{error.ErrorInfo.ErrorFlag:X4}");errorInfo.AppendLine($"错误类型: {error.ErrorInfo.ErrorType}");errorInfo.AppendLine($"时间戳: {error.Timestamp}");File.AppendAllText("can_errors.log", errorInfo.ToString());
};

六、性能优化

  1. 双缓冲队列

    private ConcurrentQueue<CanFrame> _buffer = new();// 接收线程
    Task.Run(() => 
    {while (true){var frame = _bus.Receive();_buffer.Enqueue(frame);}
    });
    
  2. 硬件加速

    _bus.SetHardwareFilter(new HardwareFilter
    {FilterType = FilterType.Standard,StartId = 0x100,EndId = 0x1FF
    });
    

七、部署与测试

1. 安装包配置

<!-- Inno Setup脚本 -->
[Files]
Source: "USBCANApp.exe"; DestDir: "{app}"; Flags: ignoreversion
Source: "zlgcan.dll"; DestDir: "{app}"; Flags: ignoreversion
Source: "error.log"; DestDir: "{app}"; Flags: ignoreversion[Icons]
Name: "{group}\USBCAN监控"; Filename: "{app}\USBCANApp.exe"

2. 压力测试

// 模拟高负载测试
Parallel.For(0, 1000, i =>
{var task = _bus.TransmitAsync(new CanClassicFrame(id: 0x200, data: new byte[8] { 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55 }));
});

参考代码 基于C#的周立功USBCAN上位机程序例程 www.youwenfan.com/contentcnr/112207.html

八、扩展功能建议

  1. DBC文件解析

    集成CANdb++解析库,实现信号值自动解码

  2. Web监控接口

    使用ASP.NET Core构建REST API提供数据访问

  3. OPC UA集成

    通过OPC Foundation库实现工业协议对接

http://www.jsqmd.com/news/374837/

相关文章:

  • 计算机Java毕设实战-基于springboot的停车场收费管理系统设计与实现基于 SpringBoot 的社区物业车位收费管理系统设计与实现【完整源码+LW+部署说明+演示视频,全bao一条龙等】
  • 题解:P14167 [Algo Beat Contest 002.5 B] 草莓小蛋糕 (cakes)
  • 从“抽卡“到“导演“——如何构建AI视频生成的母提示词系统
  • 【课程设计/毕业设计】基于springboot的粮库设备维修安检管理系统设计与实现【附源码、数据库、万字文档】
  • 实用指南:如何在mac m1模拟鼠标与键盘的自动化操作
  • 中华老字号药企排行TOP10,广药集团白云山登顶百年匠心榜 - 包罗万闻
  • 2000-2024年地级市环境保护数据-29个指标汇总
  • 新房到别墅装修哪家好:2026最新陕西全屋装修设计公司TOP5推荐 - 深度智识库
  • 深入浅出 SPA/MPA - 指南
  • P7422 「PMOI-2」城市 题解
  • 软件检测实验室认可,一次完整的方法验证过程是怎样的?
  • 【花雕动手做】50V380W-500W有霍尔红黑版本驱动模块:6.5寸轮毂电机综合控制方案
  • 基于51单片机的温湿度监测
  • Java毕设项目:基于springboot的粮库设备管理系统设计与实现(源码+文档,讲解、调试运行,定制等)
  • 雅思培训红黑榜,高通过率机构大揭秘! - 品牌测评鉴赏家
  • I.MX6U 开发板网络环境搭建----(电脑 WiFi 上网,开发板和电脑直连)--虚拟机双网口实现-- Ubuntu20.04
  • 2026必备!降AIGC工具 千笔AI VS 灵感ai 专科生专属神器
  • 【毕业设计】基于springboot的粮库设备管理系统设计与实现(源码+文档+远程调试,全bao定制等)
  • 写论文效率低?2026 年 AI 论文软件排行榜权威发布,效率提升 10 倍不是梦!
  • 开题卡住了?8个AI论文工具深度测评,本科生毕业论文写作必备指南
  • 51单片机密码锁的设计
  • 【计算机毕业设计案例】基于springboot的粮库设备管理系统基于java的粮库设备维护管理系统(程序+文档+讲解+定制)
  • 2026最新!AI论文写作软件 千笔ai写作 VS WPS AI,专科生高效写作神器!
  • 基于51单片机和Proteus的智能停车场设计
  • 剪映专业版曲线变速完全教程:从恒定变速到自由调速
  • 2026别错过!降AIGC软件 千笔·降AI率助手 VS 锐智 AI,研究生专属降重神器
  • 89C51单片机汽车尾灯设计
  • 回收天虹提货券前必读清单 - 京顺回收
  • 导师推荐 10个 AI论文软件:自考毕业论文写作必备工具测评与推荐
  • 【毕业设计】基于springboot的停车场收费管理系统设计与实现(源码+文档+远程调试,全bao定制等)