129 lines
4.2 KiB
C#
129 lines
4.2 KiB
C#
using System;
|
||
using System.IO.Ports;
|
||
using System.Threading.Tasks;
|
||
|
||
namespace ASTM_D7896_Tester.Services
|
||
{
|
||
public class FiveHalfDmmService : IDisposable
|
||
{
|
||
private SerialPort _serialPort;
|
||
private bool _disposed;
|
||
|
||
public FiveHalfDmmService(string portName, int baudRate = 115200)
|
||
{
|
||
_serialPort = new SerialPort(portName, baudRate, Parity.None, 8, StopBits.One);
|
||
_serialPort.ReadTimeout = 2000;
|
||
_serialPort.WriteTimeout = 1000;
|
||
_serialPort.NewLine = "\n";
|
||
}
|
||
|
||
public void Open()
|
||
{
|
||
if (!_serialPort.IsOpen)
|
||
_serialPort.Open();
|
||
}
|
||
|
||
public void Close()
|
||
{
|
||
if (_serialPort.IsOpen)
|
||
_serialPort.Close();
|
||
}
|
||
|
||
public bool IsOpen => _serialPort?.IsOpen == true;
|
||
|
||
private async Task<string> QueryAsync(string command)
|
||
{
|
||
if (!_serialPort.IsOpen) throw new InvalidOperationException("串口未打开");
|
||
// 使用 Task.Run 避免阻塞 UI 线程
|
||
var tcs = new TaskCompletionSource<string>();
|
||
Task.Run(() =>
|
||
{
|
||
try
|
||
{
|
||
_serialPort.WriteLine(command);
|
||
string result = _serialPort.ReadLine();
|
||
tcs.SetResult(result);
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
tcs.SetException(ex);
|
||
}
|
||
});
|
||
return await tcs.Task;
|
||
}
|
||
|
||
private async Task SendCommandAsync(string command)
|
||
{
|
||
if (!_serialPort.IsOpen) throw new InvalidOperationException("串口未打开");
|
||
await Task.Run(() => _serialPort.WriteLine(command));
|
||
}
|
||
|
||
/// <summary>
|
||
/// 配置为高速直流电压测量(FAST 分辨率)
|
||
/// </summary>
|
||
public async Task ConfigureHighSpeedDcvAsync()
|
||
{
|
||
await SendCommandAsync("CONFigure:VOLTage:DC AUTO");
|
||
await SendCommandAsync("SENSe:VOLTage:DC:RESolution FAST");
|
||
await SendCommandAsync("TRIGger:SOURce BUS"); // 使用软件触发
|
||
await SendCommandAsync("TRIGger:DELay:AUTO OFF");
|
||
await SendCommandAsync("TRIGger:DELay 0");
|
||
}
|
||
|
||
/// <summary>
|
||
/// 预置采样点数并进入等待触发状态
|
||
/// </summary>
|
||
public async Task PrepareBatchAsync(int sampleCount)
|
||
{
|
||
await SendCommandAsync($"SAMPle:COUNt {sampleCount}");
|
||
await SendCommandAsync("INITiate");
|
||
}
|
||
|
||
/// <summary>
|
||
/// 发送触发信号(*TRG)
|
||
/// </summary>
|
||
public async Task TriggerAsync()
|
||
{
|
||
await SendCommandAsync("*TRG");
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取批量采集结果(在 PrepareBatchAsync 和 TriggerAsync 之后调用)
|
||
/// </summary>
|
||
public async Task<double[]> FetchBatchAsync()
|
||
{
|
||
string response = await QueryAsync("FETCh?");
|
||
string[] parts = response.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
|
||
double[] values = new double[parts.Length];
|
||
for (int i = 0; i < parts.Length; i++)
|
||
{
|
||
if (!double.TryParse(parts[i], System.Globalization.NumberStyles.Float,
|
||
System.Globalization.CultureInfo.InvariantCulture, out values[i]))
|
||
throw new Exception($"解析失败: {parts[i]}");
|
||
}
|
||
return values;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 单次读取电压(用于实时监控)
|
||
/// </summary>
|
||
public async Task<double> ReadVoltageAsync()
|
||
{
|
||
string resp = await QueryAsync("MEASure:VOLTage:DC?");
|
||
if (double.TryParse(resp, System.Globalization.NumberStyles.Float,
|
||
System.Globalization.CultureInfo.InvariantCulture, out double value))
|
||
return value;
|
||
throw new Exception($"无效响应: {resp}");
|
||
}
|
||
|
||
public void Dispose()
|
||
{
|
||
if (!_disposed)
|
||
{
|
||
Close();
|
||
_serialPort?.Dispose();
|
||
_disposed = true;
|
||
}
|
||
}
|
||
}
|
||
} |