界面设计:
<Window x:Class="SerialPortDebug.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:SerialPortDebug"
mc:Ignorable="d"
Title="串口调试助手 - ASCII" Height="450" Width="800" WindowStartupLocation="CenterScreen" Loaded="Window_Loaded">
<Grid Margin="0,0,0,0.5">
<Grid.RowDefinitions>
<RowDefinition Height="292*"/>
<RowDefinition Height="131*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="236"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<GroupBox Header="配置" Margin="10" Grid.RowSpan="2">
<Grid >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="83"/>
<ColumnDefinition Width="121"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="30"/>
<RowDefinition Height="30"/>
<RowDefinition Height="30"/>
<RowDefinition Height="30"/>
<RowDefinition Height="30"/>
<RowDefinition Height="30"/>
<RowDefinition Height="30"/>
<RowDefinition Height="14"/>
<RowDefinition/>
</Grid.RowDefinitions>
<Label Name="label1" Content="端口" Margin="37,2,9,2" VerticalAlignment="Center" Height="26" HorizontalContentAlignment="Right"/>
<Label Name="label2" Content="波特率" Margin="0,2,10,2" VerticalAlignment="Center" Height="26" Width="54" Grid.Row="1" HorizontalAlignment="Right" HorizontalContentAlignment="Right"/>
<Label Name="label3" Content="奇偶校验位" HorizontalAlignment="Right" Margin="0,2,10,2" VerticalAlignment="Center" Height="26" Width="71" Grid.Row="2" HorizontalContentAlignment="Right"/>
<Label Name="label4" Content="停止位" HorizontalAlignment="Right" Margin="0,2,10,2" VerticalAlignment="Center" Height="26" Width="54" Grid.Row="3" HorizontalContentAlignment="Right"/>
<Label Name="label5" Content="数据位" HorizontalAlignment="Right" Margin="0,4,10,2" VerticalAlignment="Center" Height="24" Width="54" Grid.Row="4" HorizontalContentAlignment="Right"/>
<Label Name="label6" Content="流控制" HorizontalAlignment="Right" VerticalAlignment="Center" Height="25" Width="54" Grid.Row="5" Margin="0,3,10,2" HorizontalContentAlignment="Right"/>
<Label Name="label7" Content="超时(ms)" HorizontalAlignment="Right" VerticalAlignment="Center" Height="26" Width="61" Grid.Row="6" Margin="0,2,10,2" HorizontalContentAlignment="Right"/>
<ComboBox Name="comboBox1" Grid.Column="1" Margin="15,4,18,4" VerticalAlignment="Center" Height="22"/>
<ComboBox Name="comboBox2" Grid.Column="1" Margin="15,4,18,4" VerticalAlignment="Center" Height="22" Grid.Row="1"/>
<ComboBox Name="comboBox3" Grid.Column="1" Margin="15,4,18,4" VerticalAlignment="Center" Height="22" Grid.Row="2"/>
<ComboBox Name="comboBox4" Grid.Column="1" Margin="15,4,18,4" VerticalAlignment="Center" Height="22" Grid.Row="3"/>
<ComboBox Name="comboBox5" Grid.Column="1" Margin="15,4,18,4" VerticalAlignment="Center" Height="22" Grid.Row="4"/>
<ComboBox Name="comboBox6" Grid.Column="1" Margin="15,4,18,4" VerticalAlignment="Center" Height="22" Grid.Row="5"/>
<TextBox Name="textBox1" Grid.Column="1" Height="22" Margin="15,4,18,4" Grid.Row="6" TextWrapping="Wrap" Text="2000" VerticalAlignment="Center"/>
<Button Name="button1" Content="开启" Grid.Column="1" Margin="15,10,18,0" Grid.Row="8" VerticalAlignment="Top" Height="26" Click="button1_Click"/>
</Grid>
</GroupBox>
<GroupBox Name="groupBox1" Grid.Column="1" Header="接收区" Margin="10,5,10,14.5">
<Grid >
<Grid.RowDefinitions>
<RowDefinition Height="5*"/>
<RowDefinition Height="246*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<TextBox Name="textBox2" Margin="10,5,10,10" Grid.Row="1" TextWrapping="Wrap" Text="TextBox"/>
</Grid>
</GroupBox>
<GroupBox Name="groupBox2" Grid.Column="1" Header="发送区" Margin="10,0.5,10,10" Grid.Row="1">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="317*"/>
<ColumnDefinition Width="70"/>
<ColumnDefinition Width="80"/>
<ColumnDefinition Width="80"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition Height="23"/>
</Grid.RowDefinitions>
<TextBox Name="textBox3" Margin="10,10,6,10" TextWrapping="Wrap" Text="TextBox" Grid.ColumnSpan="4"/>
<Button x:Name="button2" Content="回车发送" Grid.Column="2" HorizontalAlignment="Center" Margin="0" Grid.Row="1" VerticalAlignment="Center" Width="70" Height="19" Click="button2_Click"/>
<Button Name="button3" Content="直接发送" Grid.Column="3" HorizontalAlignment="Center" Margin="5,2" Grid.Row="1" VerticalAlignment="Center" Width="70" Height="19" Click="button3_Click"/>
</Grid>
</GroupBox>
</Grid>
</Window>
主程序代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.IO.Ports;
using System.Threading;
namespace SerialPortDebug
{
/// <summary>
/// MainWindow.xaml 的交互逻辑
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void EnableReceiveAndSendGroup(bool isFirstLoad, bool enable)
{
groupBox1.IsEnabled = enable;
if (isFirstLoad)
{
textBox2.IsEnabled = false;
textBox2.Clear();
}
groupBox2.IsEnabled = enable;
if (!textBox3.IsEnabled) textBox3.Clear();
}
private void LoadParameters()
{
EnableReceiveAndSendGroup(true, false);
button1.IsEnabled = false;
comboBox1.ItemsSource = SerialPortHelper.GetSerialPorts();
if (comboBox1.Items.Count == 0) return;
button1.IsEnabled = true;
comboBox1.Text = comboBox1.Items[0].ToString();
comboBox2.ItemsSource = SerialPortHelper.GetBaudRates();
comboBox2.Text = comboBox2.Items[9].ToString();
comboBox3.ItemsSource = SerialPortHelper.GetParities();
comboBox3.Text = comboBox3.Items[0].ToString();
comboBox4.ItemsSource = SerialPortHelper.GetStopBits();
comboBox4.Text = comboBox4.Items[1].ToString();
comboBox5.ItemsSource = SerialPortHelper.GetDataBits();
comboBox5.Text = comboBox5.Items[1].ToString();
comboBox6.ItemsSource = SerialPortHelper.GetFlowControls();
comboBox6.Text = comboBox6.Items[0].ToString();
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
LoadParameters();
}
private void EnableConfig(bool enable)
{
if (enable) button1.Content = "开启";
else button1.Content = "关闭";
label1.IsEnabled = enable;
label2.IsEnabled = enable;
label3.IsEnabled = enable;
label4.IsEnabled = enable;
label5.IsEnabled = enable;
label6.IsEnabled = enable;
label7.IsEnabled = enable;
comboBox1.IsEnabled = enable;
comboBox2.IsEnabled = enable;
comboBox3.IsEnabled = enable;
comboBox4.IsEnabled = enable;
comboBox5.IsEnabled = enable;
comboBox6.IsEnabled = enable;
textBox1.IsEnabled = enable;
}
SerialPort serialPort;
private void button1_Click(object sender, RoutedEventArgs e)
{
if (button1.Content.ToString() == "开启")
{
try
{
if (!int.TryParse(textBox1.Text, out int result))
{
MessageBox.Show("超时时间设置错误!");
return;
}
serialPort = new SerialPort(comboBox1.Text,
SerialPortHelper.GetBaudRate(comboBox2.Text),
SerialPortHelper.GetParity(comboBox3.Text),
SerialPortHelper.GetDataBit(comboBox5.Text),
SerialPortHelper.GetStopBit(comboBox4.Text))
{
Handshake = SerialPortHelper.GetFlowControl(comboBox6.Text),
ReadTimeout = result
};
serialPort.Encoding = Encoding.ASCII;
serialPort.DataReceived += SerialPort_DataReceived;
serialPort.Open();
EnableConfig(false);
EnableReceiveAndSendGroup(false, true);
}
catch (Exception ex)
{
serialPort.Close();
MessageBox.Show(ex.Message);
}
}
else
{
serialPort.Close();
EnableConfig(true);
EnableReceiveAndSendGroup(false, false);
}
}
private void SerialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
textBox2.Dispatcher.Invoke(new Action(() =>
{
textBox2.Text += serialPort.ReadExisting();
}));
}
private void button2_Click(object sender, RoutedEventArgs e)
{
string text = textBox3.Text + "
";
serialPort.Write(Encoding.ASCII.GetBytes(text), 0, text.Length);
}
private void button3_Click(object sender, RoutedEventArgs e)
{
serialPort.Write(Encoding.ASCII.GetBytes(textBox3.Text), 0, textBox3.Text.Length);
}
}
}
类:EnumHelper
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SerialPortDebug
{
class EnumHelper
{
public static T GetValue<T>(string valueString) => (T)Enum.Parse(typeof(T), valueString);
}
}
类:SerialPortHelper
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO.Ports;
namespace SerialPortDebug
{
class SerialPortHelper
{
public static string[] GetSerialPorts() => SerialPort.GetPortNames().OrderBy(x => x).ToArray();
public static string[] GetBaudRates() => new string[] { "256000", "128000", "115200", "57600", "56000", "43000", "38400", "28800", "19200", "9600", "4800", "2400", "1200", "600", "300", "110" };
public static string[] GetParities() => Enum.GetNames(typeof(Parity));
public static string[] GetStopBits() => Enum.GetNames(typeof(StopBits));
public static string[] GetDataBits() => new string[] { "7", "8", "9" };
public static string[] GetFlowControls() => Enum.GetNames(typeof(Handshake));
public static int GetBaudRate(string baudRates) => Convert.ToInt32(baudRates);
public static Parity GetParity(string parity) => EnumHelper.GetValue<Parity>(parity);
public static StopBits GetStopBit(string stopbit) => EnumHelper.GetValue<StopBits>(stopbit);
public static int GetDataBit(string dataBit) => Convert.ToInt32(dataBit);
public static Handshake GetFlowControl(string flowControl) => EnumHelper.GetValue<Handshake>(flowControl);
}
}