界面设计:
<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 + "\r"; 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); } }