引言
在工业自动化、物联网等领域中,串口通信是一种常见且重要的数据传输方式。开发一个属于自己的串口助手,不仅可以加深对串口通信原理的理解,还能满足特定场景下的个性化需求。本文将详细介绍如何使用C#语言开发一个具备数据收发与Hex显示功能的串口助手。
一、开发环境准备
1. 软件工具
- 安装Visual Studio ,这里以Visual Studio 2022为例,它提供了强大的C#开发环境和丰富的调试工具。
- 确保安装了.NET桌面开发工作负载,以便支持Windows Forms或WPF应用程序开发。
2. 相关知识储备
- 了解C#编程语言的基础语法,包括变量、数据类型、类、方法等。
- 熟悉串口通信的基本概念,如波特率、数据位、停止位、校验位等参数的含义。
二、创建项目
1. 打开Visual Studio,点击“创建新项目”。在模板选择界面中,选择“Windows Forms应用(.NET Framework)”或“WPF应用(.NET)” 。这里以Windows Forms应用为例进行讲解,点击“下一步”,设置项目名称(如SerialPortAssistant)、存储位置等信息,然后点击“创建”。
2. 项目创建完成后,在“解决方案资源管理器”中可以看到项目的结构,主要包含 Form1.cs (主窗体代码文件)、 Program.cs (程序入口文件)等。
三、设计界面
1. 双击 Form1.cs 打开窗体设计器,在工具箱中拖放以下控件到窗体上:
- ComboBox:用于选择串口端口号。
- ComboBox:用于选择波特率,常见的波特率有9600、115200等,可在属性窗口中预先添加这些选项。
- CheckBox:用于选择数据位(如5、6、7、8位),这里可添加四个CheckBox分别对应不同的数据位。
- CheckBox:用于选择停止位(如1、1.5、2位),同样添加对应数量的CheckBox。
- CheckBox:用于选择校验位(如None、Odd、Even等),添加相应的CheckBox。
- Button:两个按钮,分别命名为“打开串口”和“关闭串口”。
- TextBox:一个用于输入要发送的数据,另一个用于显示接收到的数据。
- CheckBox:用于控制是否以Hex格式显示接收数据。
- Button:用于发送数据。
2. 合理调整控件的大小和位置,设置合适的 Text 属性,使界面布局清晰美观。
四、编写代码
1. 引入命名空间
在 Form1.cs 文件开头,引入必要的命名空间:
csharp
using System;
using System.IO.Ports;
using System.Windows.Forms;
System.IO.Ports 命名空间提供了用于串口通信的类,如 SerialPort 。
2. 定义成员变量
在 Form1 类中,定义以下成员变量:
csharp
private SerialPort serialPort1;
private bool isHexDisplay = false;
serialPort1 用于实例化串口对象, isHexDisplay 用于标识是否以Hex格式显示数据。
3. 初始化串口相关操作
在 Form1 的构造函数中,添加初始化串口端口号选择框的代码:
csharp
public Form1()
{
InitializeComponent();
string[] ports = SerialPort.GetPortNames();
comboBoxPort.DataSource = ports;
}
这段代码获取系统中可用的串口端口号,并将其绑定到用于选择端口号的 ComboBox 上。
4. 打开串口按钮事件处理
双击“打开串口”按钮,生成按钮点击事件处理方法,在方法中编写打开串口的逻辑:
csharp
private void btnOpen_Click(object sender, EventArgs e)
{
try
{
serialPort1 = new SerialPort();
serialPort1.PortName = comboBoxPort.Text;
serialPort1.BaudRate = int.Parse(comboBoxBaudRate.Text);
// 根据CheckBox状态设置数据位、停止位、校验位
if (checkBoxDataBits5.Checked) serialPort1.DataBits = 5;
if (checkBoxDataBits6.Checked) serialPort1.DataBits = 6;
if (checkBoxDataBits7.Checked) serialPort1.DataBits = 7;
if (checkBoxDataBits8.Checked) serialPort1.DataBits = 8;
if (checkBoxStopBits1.Checked) serialPort1.StopBits = StopBits.One;
if (checkBoxStopBits1_5.Checked) serialPort1.StopBits = StopBits.OnePointFive;
if (checkBoxStopBits2.Checked) serialPort1.StopBits = StopBits.Two;
if (checkBoxParityNone.Checked) serialPort1.Parity = Parity.None;
if (checkBoxParityOdd.Checked) serialPort1.Parity = Parity.Odd;
if (checkBoxParityEven.Checked) serialPort1.Parity = Parity.Even;
serialPort1.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler);
serialPort1.Open();
btnOpen.Enabled = false;
btnClose.Enabled = true;
}
catch (Exception ex)
{
MessageBox.Show("打开串口失败:" + ex.Message);
}
}
此代码根据用户在界面上选择的参数配置串口,并订阅 DataReceived 事件,当有数据从串口接收时,该事件会被触发。
5. 关闭串口按钮事件处理
csharp
private void btnClose_Click(object sender, EventArgs e)
{
try
{
if (serialPort1 != null && serialPort1.IsOpen)
{
serialPort1.Close();
}
btnOpen.Enabled = true;
btnClose.Enabled = false;
}
catch (Exception ex)
{
MessageBox.Show("关闭串口失败:" + ex.Message);
}
}
6. 数据接收事件处理
csharp
private void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e)
{
SerialPort sp = (SerialPort)sender;
byte[] buffer = new byte[sp.BytesToRead];
sp.Read(buffer, 0, buffer.Length);
if (isHexDisplay)
{
string hexString = BitConverter.ToString(buffer).Replace("-", "");
this.Invoke(new Action(() => textBoxReceive.Text += hexString + Environment.NewLine));
}
else
{
string data = System.Text.Encoding.Default.GetString(buffer);
this.Invoke(new Action(() => textBoxReceive.Text += data + Environment.NewLine));
}
}
在数据接收事件处理方法中,首先读取串口接收到的数据到字节数组中。然后根据 isHexDisplay 的值判断是以Hex格式还是普通文本格式显示数据。由于串口数据接收事件发生在非UI线程,所以使用 Invoke 方法将数据显示操作切换到UI线程,以避免跨线程操作UI控件的异常。
7. 发送数据按钮事件处理
csharp
private void btnSend_Click(object sender, EventArgs e)
{
try
{
if (serialPort1 != null && serialPort1.IsOpen)
{
string sendData = textBoxSend.Text;
if (checkBoxHexSend.Checked)
{
byte[] hexBytes = StringToByteArray(sendData);
serialPort1.Write(hexBytes, 0, hexBytes.Length);
}
else
{
serialPort1.Write(sendData);
}
}
}
catch (Exception ex)
{
MessageBox.Show("发送数据失败:" + ex.Message);
}
}
private byte[] StringToByteArray(string hex)
{
int NumberChars = hex.Length;
byte[] bytes = new byte[NumberChars / 2];
for (int i = 0; i < NumberChars; i += 2)
bytes[i / 2] = Convert.ToByte(hex.Substring(i, 2), 16);
return bytes;
}
发送数据时,同样根据用户选择的是普通文本发送还是Hex格式发送,对数据进行相应处理后通过串口发送出去。 StringToByteArray 方法用于将Hex字符串转换为字节数组。
8. Hex显示CheckBox事件处理
csharp
private void checkBoxHexDisplay_CheckedChanged(object sender, EventArgs e)
{
isHexDisplay = checkBoxHexDisplay.Checked;
}
该方法用于更新 isHexDisplay 变量的值,以响应用户对Hex显示方式的选择。
五、测试运行
1. 将两个支持串口通信的设备通过串口线连接到计算机(或者使用虚拟串口软件模拟串口通信)。
2. 运行程序,在界面上选择正确的串口端口号、波特率等参数,点击“打开串口”按钮。
3. 在发送数据的文本框中输入数据,点击“发送”按钮,观察数据是否能正确发送到对方设备。
4. 从对方设备发送数据,查看接收数据的文本框是否能正确显示接收到的数据,切换Hex显示CheckBox,观察数据显示格式的变化。
六、总结
本文详细阐述了使用C#语言开发具备数据收发与Hex显示功能串口助手的完整过程。从开发环境的搭建,到项目的创建、界面设计,再到核心代码的编写与功能实现,每一个环节都进行了具体的说明与示例。通过对串口通信相关类库的运用,以及对各个控件事件的合理处理,实现了根据用户设置的参数进行串口的打开与关闭,完成数据的双向传输,并能够按照用户需求以普通文本或Hex格式展示接收数据。