Files
ASTM-D7896-19TransientHot-W…/Window1.xaml.cs
2026-06-12 16:30:29 +08:00

253 lines
8.3 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using System;
using System.Collections.Generic;
using System.IO.Ports;
using System.Linq;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Threading;
namespace ConstantCurrentControl
{
public partial class Window1 : Window
{
private SerialPort _serialPort;
private bool _isConnected = false;
private DispatcherTimer _readTimer;
private List<byte> _receiveBuffer = new List<byte>(); // 接收缓存
public Window1()
{
InitializeComponent();
Loaded += MainWindow_Loaded;
}
private void MainWindow_Loaded(object sender, RoutedEventArgs e)
{
cmbPort.ItemsSource = SerialPort.GetPortNames();
if (cmbPort.Items.Count > 0) cmbPort.SelectedIndex = 0;
// 初始化定时器50ms 间隔UI 线程)
_readTimer = new DispatcherTimer();
_readTimer.Interval = TimeSpan.FromMilliseconds(50);
_readTimer.Tick += ReadTimer_Tick;
cmbPort.Text = "COM2";
}
#region
private async void BtnConnect_Click(object sender, RoutedEventArgs e)
{
if (cmbPort.SelectedItem == null)
{
MessageBox.Show("请选择串口号");
return;
}
try
{
string port = cmbPort.SelectedItem.ToString();
int baud = int.Parse((cmbBaudrate.SelectedItem as ComboBoxItem).Content.ToString());
_serialPort = new SerialPort(port, baud, Parity.None, 8, StopBits.One);
_serialPort.ReadTimeout = 100;
_serialPort.WriteTimeout = 1000;
_serialPort.Open();
_isConnected = true;
btnConnect.IsEnabled = false;
btnDisconnect.IsEnabled = true;
AddLog($"已连接 {port} @ {baud} bps");
// 清空接收缓存和串口缓冲区
_receiveBuffer.Clear();
_serialPort.DiscardInBuffer();
// 启动定时器读取
_readTimer.Start();
// 发送配置命令不跟踪模式byte8=0
await ConfigureOptimalMode();
}
catch (Exception ex)
{
MessageBox.Show($"连接失败: {ex.Message}");
_isConnected = false;
}
}
private void BtnDisconnect_Click(object sender, RoutedEventArgs e)
{
if (_readTimer != null) _readTimer.Stop();
if (_serialPort != null && _serialPort.IsOpen)
{
_serialPort.Close();
_serialPort.Dispose();
_serialPort = null;
}
_isConnected = false;
btnConnect.IsEnabled = true;
btnDisconnect.IsEnabled = false;
AddLog("已断开连接");
}
#endregion
#region
private void ReadTimer_Tick(object sender, EventArgs e)
{
if (!_isConnected || _serialPort == null || !_serialPort.IsOpen)
return;
try
{
int bytesToRead = _serialPort.BytesToRead;
if (bytesToRead > 0)
{
byte[] buffer = new byte[bytesToRead];
_serialPort.Read(buffer, 0, bytesToRead);
_receiveBuffer.AddRange(buffer);
// 解析完整帧12字节以 FE FE 开头FF FF 结尾)
ParseCompleteFrames();
}
}
catch (Exception ex)
{
AddLog($"读取错误: {ex.Message}");
}
}
private void ParseCompleteFrames()
{
for (int i = 0; i <= _receiveBuffer.Count - 12; i++)
{
if (_receiveBuffer[i] == 0xFE && _receiveBuffer[i + 1] == 0xFE &&
_receiveBuffer[i + 10] == 0xFF && _receiveBuffer[i + 11] == 0xFF)
{
byte[] frame = _receiveBuffer.Skip(i).Take(12).ToArray();
ProcessFrame(frame);
// 移除已处理的帧
_receiveBuffer.RemoveRange(0, i + 12);
i = -1; // 重新扫描
}
}
// 防止缓存无限增长
if (_receiveBuffer.Count > 200)
_receiveBuffer.RemoveRange(0, _receiveBuffer.Count - 200);
}
private void ProcessFrame(byte[] frame)
{
// 解析电流byte4, byte5
int rawCurrent = (frame[4] << 8) | frame[5];
double current = rawCurrent / 1000.0;
AddLog($"回采帧: {BitConverter.ToString(frame)} 电流={current:F3}A");
}
#endregion
#region
private async Task<bool> SendCommand(byte[] command)
{
if (!_isConnected || _serialPort == null || !_serialPort.IsOpen)
{
AddLog("串口未打开");
return false;
}
try
{
await _serialPort.BaseStream.WriteAsync(command, 0, command.Length);
AddLog($"发送: {BitConverter.ToString(command)}");
return true;
}
catch (Exception ex)
{
AddLog($"发送失败: {ex.Message}");
return false;
}
}
private async Task ConfigureOptimalMode()
{
byte[] configCmd = new byte[12];
configCmd[0] = 0xFE;
configCmd[1] = 0xFE;
configCmd[2] = 0x55;
configCmd[3] = 0xAA;
configCmd[4] = 0x00;
configCmd[5] = 0x00;
configCmd[6] = 0x01; // PC调节
configCmd[7] = rb50Hz.IsChecked == true ? (byte)1 : (byte)2;
configCmd[8] = 0x00; // 不跟踪(你实测稳定)
configCmd[9] = 0x00;
configCmd[10] = 0xFF;
configCmd[11] = 0xFF;
await SendCommand(configCmd);
}
#endregion
#region UI操作
private async void BtnSet_Click(object sender, RoutedEventArgs e)
{
if (!_isConnected)
{
MessageBox.Show("请先连接串口");
return;
}
if (!double.TryParse(txtSetCurrent.Text, out double target) || target < 0 || target > 5)
{
MessageBox.Show("电流需为 0~5.000 A");
return;
}
int raw = (int)(target * 1000);
byte cmdH = (byte)((raw >> 8) & 0xFF);
byte cmdL = (byte)(raw & 0xFF);
byte[] currentCmd = new byte[12];
currentCmd[0] = 0xFE;
currentCmd[1] = 0xFE;
currentCmd[2] = 0x55;
currentCmd[3] = 0xAA;
currentCmd[4] = cmdH;
currentCmd[5] = cmdL;
currentCmd[6] = 0x01;
currentCmd[7] = rb50Hz.IsChecked == true ? (byte)1 : (byte)2;
currentCmd[8] = 0x00; // 不跟踪
currentCmd[9] = 0x00;
currentCmd[10] = 0xFF;
currentCmd[11] = 0xFF;
await SendCommand(currentCmd);
AddLog($"设定电流 = {target:F3} A");
}
private async void BtnStop_Click(object sender, RoutedEventArgs e)
{
if (!_isConnected) return;
byte[] stopCmd = new byte[12];
stopCmd[0] = 0xFE;
stopCmd[1] = 0xFE;
stopCmd[2] = 0x55;
stopCmd[3] = 0xAA;
stopCmd[4] = 0x00;
stopCmd[5] = 0x00;
stopCmd[6] = 0x01;
stopCmd[7] = rb50Hz.IsChecked == true ? (byte)1 : (byte)2;
stopCmd[8] = 0x00; // 不跟踪
stopCmd[9] = 0x00;
stopCmd[10] = 0xFF;
stopCmd[11] = 0xFF;
await SendCommand(stopCmd);
AddLog("禁止输出 (0A)");
}
private void AddLog(string msg)
{
Dispatcher.Invoke(() =>
{
lstLog.Items.Insert(0, $"{DateTime.Now:HH:mm:ss} {msg}");
if (lstLog.Items.Count > 50) lstLog.Items.RemoveAt(lstLog.Items.Count - 1);
});
}
#endregion
}
}