以下是一个基于 .NET Core + WPF 的半导体可靠性测试机上位机系统的完整架构设计,涵盖 UI、业务逻辑、硬件驱动、数据处理模块、日志、计算和扩展功能等。内容将按照模块化、分层设计进行详细说明,并提供关键代码示例。由于内容较长,我会分模块逐步展开,确保清晰且实用。同时,我会根据你的需求(MVVM、Prism、Autofac、Serilog、LiveCharts 等)提供一个系统性框架,并附带中文解释。后续可以根据需要进一步细化代码或扩展其他功能(如深度学习、云端部署等)。
一、系统整体架构设计
1.1 架构目标
模块化:通过 Prism 实现模块化设计,各个功能模块(如首页、配置、监控等)独立开发、动态加载。
可扩展性:硬件驱动抽象化,支持不同厂商硬件切换;数据存储支持多种格式(CSV、MySQL、SQLite 等)。
高性能:异步处理高频采集数据,NumSharp 用于高效计算热阻、结构函数等。
易维护:使用 MVVM 模式分离 UI 和逻辑,Serilog 提供详细日志,DI 容器(Autofac)管理依赖。
用户友好:界面提供帮助提示,LiveCharts 绘制实时曲线,操作简单直观。
1.2 分层架构
UI 层:WPF + Prism + MVVM,负责界面展示和用户交互。
应用服务层:业务逻辑处理,如实验流程控制、数据解析、硬件操作等。
驱动层:硬件抽象接口,适配不同厂商设备(串口、TCP/UDP、Modbus 等)。
数据层:支持 CSV、MySQL、SQLite、SQL Server,Entity Framework Core 管理数据库。
计算层:NumSharp 实现热阻、结构函数等半导体计算公式。
日志层:Serilog 记录操作日志、硬件状态、实验数据。
通信层:SerialPort、TcpClient、UdpClient、Modbus 实现硬件通信。
1.3 项目结构
SemiconductorTestSystem/
├── SemiconductorTestSystem.sln
├── Src/
│ ├── SemiconductorTestSystem.UI/ # WPF UI 项目
│ │ ├── Views/ # XAML 界面
│ │ ├── ViewModels/ # MVVM 视图模型
│ │ ├── Modules/ # Prism 模块(首页、配置等)
│ │ ├── App.xaml # 应用入口
│ │ └── Bootstrapper.cs # Prism 启动配置
│ ├── SemiconductorTestSystem.Core/ # 核心业务逻辑
│ │ ├── Services/ # 业务服务(实验控制、数据处理等)
│ │ ├── Models/ # 数据模型
│ │ └── Interfaces/ # 服务接口
│ ├── SemiconductorTestSystem.Hardware/ # 硬件驱动
│ │ ├── Drivers/ # 具体硬件驱动实现
│ │ ├── Interfaces/ # 硬件抽象接口
│ │ └── Communication/ # 通信协议(串口、TCP 等)
│ ├── SemiconductorTestSystem.Data/ # 数据存储
│ │ ├── Repositories/ # 数据访问层
│ │ ├── Configurations/ # CSV/DB 配置
│ │ └── DbContexts/ # EF Core 上下文
│ ├── SemiconductorTestSystem.Calculations/ # 计算模块
│ │ ├── ThermalCalculations.cs # 热阻、结构函数计算
│ │ └── TestCalculations.cs # 其他测试公式
│ ├── SemiconductorTestSystem.Common/ # 公共类库
│ │ ├── Extensions/ # 扩展方法
│ │ ├── Utilities/ # 工具类
│ │ └── Enums/ # 枚举定义
│ └── SemiconductorTestSystem.Tests/ # 单元测试
├── Docs/ # 文档
└── README.md
二、UI 框架设计
2.1 UI 框架技术栈
WPF:使用 XAML 实现现代化界面,支持数据绑定。
Prism:实现模块化开发,导航管理和依赖注入。
MVVM:分离界面和逻辑,ViewModel 处理业务逻辑。
LiveCharts:绘制实时曲线(如温度、电压等)。
MaterialDesignThemes:美化界面,提供现代化 UI 风格。
2.2 UI 模块划分
根据需求,设计以下五个主要界面模块:
首页:显示通道信息、实验状态,点击查看数据表格和曲线。
配置界面:设置实验流程(升温、升压、延时等)。
监控界面:实时查看硬件状态(温箱、通道、电源等)。
日志界面:显示设备和实验日志,支持订阅和过滤。
硬件控制界面:查看和操作硬件状态。
2.3 Prism 模块化实现
每个界面作为一个 Prism 模块,动态加载到主窗口的 Region 中。
2.3.1 Bootstrapper 配置
csharp
using Prism.Ioc;
using Prism.Modularity;
using Prism.Unity;
using Unity;
namespace SemiconductorTestSystem.UI
{
public class Bootstrapper : PrismBootstrapper
{
protected override DependencyObject CreateShell()
{
return Container.Resolve();
}
protected override void RegisterTypes(IContainerRegistry containerRegistry)
{
// 注册服务
containerRegistry.RegisterSingleton();
containerRegistry.RegisterSingleton();
containerRegistry.RegisterSingleton();
containerRegistry.RegisterSingleton();
}
protected override void ConfigureModuleCatalog(IModuleCatalog moduleCatalog)
{
// 注册模块
moduleCatalog.AddModule();
moduleCatalog.AddModule();
moduleCatalog.AddModule();
moduleCatalog.AddModule();
moduleCatalog.AddModule();
}
}
}
2.3.2 主窗口 XAML
xaml
2.3.3 首页模块示例
HomeView.xaml
xaml
HomeViewModel.cs
csharp
using Prism.Mvvm;
using Prism.Regions;
using LiveCharts;
using LiveCharts.Wpf;
using SemiconductorTestSystem.Core.Services;
namespace SemiconductorTestSystem.UI.Modules.Home.ViewModels
{
public class HomeViewModel : BindableBase, INavigationAware
{
private readonly ITestController _testController;
private Channel _selectedChannel;
private ObservableCollection _channels;
private SeriesCollection _seriesCollection;
public HomeViewModel(ITestController testController)
{
_testController = testController;
Channels = new ObservableCollection(_testController.GetChannels());
SeriesCollection = new SeriesCollection();
}
public Channel SelectedChannel
{
get => _selectedChannel;
set
{
SetProperty(ref _selectedChannel, value);
UpdateChannelData();
}
}
public ObservableCollection Channels
{
get => _channels;
set => SetProperty(ref _channels, value);
}
public SeriesCollection SeriesCollection
{
get => _seriesCollection;
set => SetProperty(ref _seriesCollection, value);
}
private async void UpdateChannelData()
{
if (SelectedChannel != null)
{
var data = await _testController.GetChannelDataAsync(SelectedChannel.Id);
SeriesCollection.Clear();
SeriesCollection.Add(new LineSeries
{
Title = "Temperature",
Values = new ChartValues(data.Temperatures)
});
}
}
public void OnNavigatedTo(NavigationContext navigationContext) { }
public bool IsNavigationTarget(NavigationContext navigationContext) => true;
public void OnNavigatedFrom(NavigationContext navigationContext) { }
}
}
HomeModule.cs
csharp
using Prism.Ioc;
using Prism.Modularity;
using Prism.Regions;
namespace SemiconductorTestSystem.UI.Modules.Home
{
public class HomeModule : IModule
{
public void OnInitialized(IContainerProvider containerProvider)
{
var regionManager = containerProvider.Resolve();
regionManager.RegisterViewWithRegion("MainRegion", typeof(Views.HomeView));
}
public void RegisterTypes(IContainerRegistry containerRegistry)
{
containerRegistry.RegisterForNavigation();
}
}
}
2.4 UI 设计要点
首页:使用 ListBox 显示通道列表,DataGrid 显示表格数据,LiveCharts 绘制温度、电压等曲线。
配置界面:使用 TreeView 或 FlowDocument 展示实验流程,支持拖拽调整步骤。
监控界面:使用 Grid 布局展示硬件状态,颜色指示(绿色正常、红色故障)。
日志界面:使用 DataGrid 显示日志,支持筛选和导出。
硬件控制界面:使用 ComboBox 选择硬件,Button 执行操作,TextBox 设置参数。
三、硬件驱动设计
3.1 硬件驱动目标
抽象化:通过接口和抽象类定义硬件通用操作(初始化、开启、关闭、设置、读取)。
可切换:支持不同厂商硬件,通过反射或 DI 动态加载驱动。
多协议:支持串口(COM)、TCP/UDP、Modbus 等通信协议。
事件驱动:硬件状态变化触发事件,通知上层逻辑。
3.2 硬件抽象接口
csharp
namespace SemiconductorTestSystem.Hardware.Interfaces
{
public interface IHardwareDevice : IDisposable
{
string DeviceId { get; }
string DeviceName { get; }
DeviceStatus Status { get; }
Task InitializeAsync();
Task StartAsync();
Task StopAsync();
Task SetParameterAsync(string parameter, object value);
Task
3.3 具体驱动实现(以电源为例)
csharp
using SemiconductorTestSystem.Hardware.Interfaces;
using System.IO.Ports;
namespace SemiconductorTestSystem.Hardware.Drivers
{
public class TektronixPowerSupply : IHardwareDevice
{
private readonly SerialPort _serialPort;
public string DeviceId { get; }
public string DeviceName { get; } = "Tektronix Power Supply";
public DeviceStatus Status { get; private set; }
public event EventHandler StatusChanged;
public TektronixPowerSupply(string portName)
{
DeviceId = Guid.NewGuid().ToString();
_serialPort = new SerialPort(portName, 9600);
}
public async Task InitializeAsync()
{
try
{
_serialPort.Open();
Status = DeviceStatus.Idle;
RaiseStatusChanged("Initialized");
}
catch (Exception ex)
{
Status = DeviceStatus.Error;
RaiseStatusChanged($"Initialization failed: {ex.Message}");
}
}
public async Task StartAsync()
{
Status = DeviceStatus.Running;
RaiseStatusChanged("Started");
}
public async Task StopAsync()
{
Status = DeviceStatus.Idle;
RaiseStatusChanged("Stopped");
}
public async Task SetParameterAsync(string parameter, object value)
{
// 示例:设置电压
if (parameter == "Voltage")
{
_serialPort.WriteLine($"VOLT {value}");
}
}
public async Task
3.4 硬件驱动加载(反射 + DI)
使用 Autofac 动态注册硬件驱动,支持通过配置文件切换厂商。
csharp
using Autofac;
using SemiconductorTestSystem.Hardware.Interfaces;
using System.Reflection;
namespace SemiconductorTestSystem.Hardware
{
public class HardwareModule : Autofac.Module
{
protected override void Load(ContainerBuilder builder)
{
// 动态加载驱动
var assembly = Assembly.GetExecutingAssembly();
var driverTypes = assembly.GetTypes()
.Where(t => typeof(IHardwareDevice).IsAssignableFrom(t) && !t.IsInterface && !t.IsAbstract);
foreach (var type in driverTypes)
{
builder.RegisterType(type).As().InstancePerDependency();
}
}
}
}
配置文件(appsettings.json)
json
{
"Hardware": {
"PowerSupply": {
"Type": "TektronixPowerSupply",
"Port": "COM1"
},
"Oven": {
"Type": "CustomOven",
"Address": "192.168.1.100",
"Protocol": "TCP"
}
}
}
硬件服务
csharp
using Microsoft.Extensions.Configuration;
using SemiconductorTestSystem.Hardware.Interfaces;
namespace SemiconductorTestSystem.Core.Services
{
public class HardwareService : IHardwareService
{
private readonly IConfiguration _configuration;
private readonly ILifetimeScope _scope;
private readonly Dictionary _devices;
public HardwareService(IConfiguration configuration, ILifetimeScope scope)
{
_configuration = configuration;
_scope = scope;
_devices = new Dictionary();
LoadDevices();
}
private void LoadDevices()
{
var hardwareConfig = _configuration.GetSection("Hardware");
foreach (var deviceConfig in hardwareConfig.GetChildren())
{
var typeName = deviceConfig["Type"];
var deviceType = Type.GetType($"SemiconductorTestSystem.Hardware.Drivers.{typeName}");
if (deviceType != null)
{
var device = (IHardwareDevice)_scope.Resolve(deviceType);
_devices.Add(deviceConfig.Key, device);
}
}
}
public IHardwareDevice GetDevice(string deviceId)
{
return _devices.ContainsKey(deviceId) ? _devices[deviceId] : null;
}
}
}
四、数据存储设计
4.1 数据存储目标
支持多种存储格式:CSV、MySQL、SQL Server、SQLite。
通过配置文件动态切换存储方式。
使用 Entity Framework Core 管理数据库操作。
CSV 文件支持自定义格式,通过反射实现灵活存储。
4.2 数据模型
csharp
namespace SemiconductorTestSystem.Core.Models
{
public class TestData
{
public int Id { get; set; }
public string ChannelId { get; set; }
public DateTime Timestamp { get; set; }
public double Temperature { get; set; }
public double Voltage { get; set; }
public double Current { get; set; }
public string TestMode { get; set; }
}
public class Channel
{
public string Id { get; set; }
public string ChannelName { get; set; }
public string OvenId { get; set; }
public string ZoneId { get; set; }
public string Status { get; set; }
}
}
4.3 EF Core 配置
csharp
using Microsoft.EntityFrameworkCore;
namespace SemiconductorTestSystem.Data.DbContexts
{
public class TestDbContext : DbContext
{
public DbSet TestDatas { get; set; }
public DbSet Channels { get; set; }
public TestDbContext(DbContextOptions options) : base(options) { }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity().HasKey(t => t.Id);
modelBuilder.Entity().HasKey(c => c.Id);
}
}
}
Startup 配置
csharp
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
namespace SemiconductorTestSystem.UI
{
public class Startup
{
public void ConfigureServices(ContainerBuilder builder, IConfiguration configuration)
{
var storageType = configuration["Storage:Type"];
var connectionString = configuration["Storage:ConnectionString"];
if (storageType == "MySQL")
{
builder.Register(c => new TestDbContext(
new DbContextOptionsBuilder()
.UseMySql(connectionString, ServerVersion.AutoDetect(connectionString))
.Options)).AsSelf().InstancePerLifetimeScope();
}
else if (storageType == "SQLite")
{
builder.Register(c => new TestDbContext(
new DbContextOptionsBuilder()
.UseSqlite(connectionString)
.Options)).AsSelf().InstancePerLifetimeScope();
}
}
}
}
appsettings.json
json
{
"Storage": {
"Type": "SQLite",
"ConnectionString": "Data Source=testdata.db"
}
}
4.4 CSV 存储(反射实现)
csharp
using System.Reflection;
namespace SemiconductorTestSystem.Data.Configurations
{
public class CsvStorageProvider
{
private readonly string _filePath;
private readonly Type _dataType;
public CsvStorageProvider(string filePath, Type dataType)
{
_filePath = filePath;
_dataType = dataType;
}
public async Task SaveAsync(IEnumerable data)
{
using var writer = new StreamWriter(_filePath, append: true);
var properties = _dataType.GetProperties(BindingFlags.Public | BindingFlags.Instance);
// 写入表头
if (new FileInfo(_filePath).Length == 0)
{
await writer.WriteLineAsync(string.Join(",", properties.Select(p => p.Name)));
}
// 写入数据
foreach (var item in data)
{
var values = properties.Select(p => p.GetValue(item)?.ToString() ?? "");
await writer.WriteLineAsync(string.Join(",", values));
}
}
}
}
五、实验控制与计算
5.1 TestController 设计
统一管理半导体可靠性实验(HTRB、HTGB、TC 等)。
csharp
using SemiconductorTestSystem.Core.Models;
namespace SemiconductorTestSystem.Core.Services
{
public interface ITestController
{
Task StartTestAsync(string testMode, TestConfig config);
Task StopTestAsync();
Task> GetChannelsAsync();
Task GetChannelDataAsync(string channelId);
}
public class TestController : ITestController
{
private readonly IHardwareService _hardwareService;
private readonly IDataStorageService _dataStorageService;
private readonly ILogService _logService;
public TestController(IHardwareService hardwareService, IDataStorageService dataStorageService, ILogService logService)
{
_hardwareService = hardwareService;
_dataStorageService = dataStorageService;
_logService = logService;
}
public async Task StartTestAsync(string testMode, TestConfig config)
{
_logService.Information($"Starting {testMode} test with config: {config}");
foreach (var step in config.Steps)
{
if (step.Type == TestStepType.Temperature)
{
var oven = _hardwareService.GetDevice("Oven");
await oven.SetParameterAsync("Temperature", step.Value);
}
else if (step.Type == TestStepType.Delay)
{
await Task.Delay(TimeSpan.FromSeconds(step.Value));
}
}
}
public async Task StopTestAsync()
{
_logService.Information("Stopping test");
var devices = _hardwareService.GetAllDevices();
foreach (var device in devices)
{
await device.StopAsync();
}
}
}
}
5.2 热阻计算(NumSharp)
csharp
using NumSharp;
namespace SemiconductorTestSystem.Calculations
{
public class ThermalCalculations
{
public static double CalculateThermalResistance(double[] temperatures, double[] powers)
{
var tempArray = np.array(temperatures);
var powerArray = np.array(powers);
var deltaT = tempArray.max() - tempArray.min();
var avgPower = powerArray.mean();
return deltaT / avgPower;
}
public static NDArray CalculateStructureFunction(double[] times, double[] temperatures)
{
// 示例:结构函数计算(简化)
var timeArray = np.array(times);
var tempArray = np.array(temperatures);
return np.cumsum(tempArray) / timeArray;
}
}
}
六、日志系统
6.1 Serilog 配置
csharp
using Serilog;
namespace SemiconductorTestSystem.Core.Services
{
public class SerilogService : ILogService
{
public SerilogService()
{
Log.Logger = new LoggerConfiguration()
.WriteTo.Console()
.WriteTo.File("logs/app.log", rollingInterval: RollingInterval.Day)
.CreateLogger();
}
public void Information(string message) => Log.Information(message);
public void Error(string message, Exception ex) => Log.Error(ex, message);
}
}
七、异步 vs 同步
7.1 异步优势
高吞吐量:异步适合高频硬件通信和数据采集,避免 UI 阻塞。
扩展性:异步支持多设备并发操作,适合 200+ 设备场景。
用户体验:异步保持 UI 响应,适合实时监控。
7.2 测试用例
csharp
public class AsyncVsSyncTest
{
[Fact]
public async Task AsyncReadTest()
{
var device = new Mock();
device.Setup(d => d.ReadParameterAsync("Voltage")).ReturnsAsync(5.0);
var stopwatch = Stopwatch.StartNew();
var result = await device.Object.ReadParameterAsync("Voltage");
stopwatch.Stop();
Assert.Equal(5.0, result);
Assert.True(stopwatch.ElapsedMilliseconds < 100);
}
[Fact]
public void SyncReadTest()
{
var device = new Mock();
device.Setup(d => d.ReadParameterAsync("Voltage")).Returns(Task.FromResult(5.0));
var stopwatch = Stopwatch.StartNew();
var result = device.Object.ReadParameterAsync("Voltage").Result; // 阻塞
stopwatch.Stop();
Assert.Equal(5.0, result);
Assert.True(stopwatch.ElapsedMilliseconds < 100);
}
}
结论:异步优先,特别是在多设备、高频采集场景下,使用 async/await 提高效率和扩展性。
八、扩展功能
8.1 多设备管理
通过 HardwareService 支持动态添加设备,配置文件驱动。
8.2 历史数据查询
csharp
public class DataQueryService
{
private readonly TestDbContext _dbContext;
public DataQueryService(TestDbContext dbContext)
{
_dbContext = dbContext;
}
public async Task> QueryDataAsync(string channelId, DateTime startTime, DateTime endTime)
{
return await _dbContext.TestDatas
.Where(d => d.ChannelId == channelId && d.Timestamp >= startTime && d.Timestamp <= endTime)
.ToListAsync();
}
}
九、学习路线与教程建议
9.1 C# 高级编程
基础:掌握类、方法、属性、集合(List、Dictionary 等)。
面向对象:深入理解封装、继承、多态,设计 SOLID 原则。
高级特性:
反射:动态加载类型、调用方法,适合动态硬件驱动。 - 接口/抽象类:定义硬件规范,提高扩展性。 - 泛型:约束类型安全,优化数据处理。 - 委托/事件:实现硬件状态通知。 - 多线程/异步:处理高频数据采集。
设计模式:工厂模式(硬件驱动创建)、单例模式(服务实例)、观察者模式(事件通知)。
性能优化:使用 Span、Memory 优化内存,Parallel.For 处理并发。
9.2 上位机开发教程
WPF 入门:学习 XAML、数据绑定、命令。
MVVM 实践:使用 Prism 实现导航和模块化。
硬件通信:掌握 SerialPort、TcpClient、Modbus。
数据处理:学习 EF Core、CSV 处理、NumSharp 计算。
日志与调试:使用 Serilog 记录日志,VS 调试工具。
十、后续扩展
如果你需要以下内容,我可以进一步提供:
深度学习模型:集成 ML.NET 用于实验数据预测。
云端部署:使用 Azure 或 AWS 实现远程监控。
200+ 设备优化:基于 Actor 模型(如 Akka.NET)实现分布式设备管理。
边缘计算:在设备端部署轻量级推理模型。
请明确具体需求,我会提供更详细的代码和说明!