This commit is contained in:
xyy
2026-06-08 17:33:46 +08:00
parent ae5803431b
commit 8681cc0163
3 changed files with 298 additions and 1 deletions

223
Window1.xaml.cs Normal file
View File

@@ -0,0 +1,223 @@
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;
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;
}
#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 = 1000; // 关键:避免永久阻塞
_serialPort.WriteTimeout = 1000;
_serialPort.Open();
_isConnected = true;
btnConnect.IsEnabled = false;
btnDisconnect.IsEnabled = true;
AddLog($"已连接 {port} @ {baud} bps");
// 发送配置命令(不输出电流,只设置模式),同样异步等待但不死锁
await ConfigureOptimalMode();
}
catch (Exception ex)
{
MessageBox.Show($"连接失败: {ex.Message}");
_isConnected = false;
}
}
private void BtnDisconnect_Click(object sender, RoutedEventArgs e)
{
if (_serialPort != null && _serialPort.IsOpen)
{
_serialPort.Close();
_serialPort.Dispose();
_serialPort = null;
}
_isConnected = false;
btnConnect.IsEnabled = true;
btnDisconnect.IsEnabled = false;
AddLog("已断开连接");
}
#endregion
#region byte6=1, byte8=1
private async Task ConfigureOptimalMode()
{
// 构造命令:电流 0但强制 PC 模式和跟踪模式
byte[] configCmd = new byte[12];
configCmd[0] = 0xFE;
configCmd[1] = 0xFE;
configCmd[2] = 0x55; // 识别码高
configCmd[3] = 0xAA; // 识别码低
configCmd[4] = 0x00; // 电流高字节 (0A)
configCmd[5] = 0x00; // 电流低字节
configCmd[6] = 0x01; // PC调节模式
configCmd[7] = 1;
configCmd[8] = 0; // 开启跟踪模式
configCmd[9] = 0x00;
configCmd[10] = 0xFF;
configCmd[11] = 0xFF;
await SendCommandSafe(configCmd);
}
#endregion
#region UI
private async Task<bool> SendCommandSafe(byte[] command)
{
if (!_isConnected || _serialPort == null || !_serialPort.IsOpen)
{
AddLog("串口未打开");
return false;
}
try
{
// 清空缓冲区
_serialPort.DiscardInBuffer();
_serialPort.DiscardOutBuffer();
// 发送命令
await _serialPort.BaseStream.WriteAsync(command, 0, command.Length);
AddLog($"发送: {BitConverter.ToString(command)}");
// 异步读取12字节带超时
byte[] buffer = new byte[12];
int totalRead = 0;
DateTime start = DateTime.Now;
while (totalRead < 12 && (DateTime.Now - start).TotalMilliseconds < 1500)
{
if (_serialPort.BytesToRead > 0)
{
int read = await _serialPort.BaseStream.ReadAsync(buffer, totalRead, 12 - totalRead);
if (read > 0) totalRead += read;
}
else
await Task.Delay(20);
}
if (totalRead == 12)
{
AddLog($"接收: {BitConverter.ToString(buffer)}");
// 解析回采电流 (byte4, byte5)
int rawCurrent = (buffer[4] << 8) | buffer[5];
double actualCurrent = rawCurrent / 1000.0;
Dispatcher.Invoke(() => txtActualCurrent.Text = actualCurrent.ToString("F3"));
return true;
}
else
{
AddLog($"接收超时或字节数不足: {totalRead}/12");
return false;
}
}
catch (Exception ex)
{
AddLog($"命令发送异常: {ex.Message}");
return false;
}
}
#endregion
#region
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;
}
// 构造12字节电流命令
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; // PC模式
currentCmd[7] = 1;
currentCmd[8] = 0; // 跟踪
currentCmd[9] = 0x00;
currentCmd[10] = 0xFF;
currentCmd[11] = 0xFF;
await SendCommandSafe(currentCmd);
AddLog($"设定电流 = {target:F3} A");
}
private async void BtnStop_Click(object sender, RoutedEventArgs e)
{
if (!_isConnected) return;
// 发送电流0
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] = 1; // 50Hz
stopCmd[8] = 0;
stopCmd[9] = 0x00;
stopCmd[10] = 0xFF;
stopCmd[11] = 0xFF;
await SendCommandSafe(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