在C#写串口通讯小程序时,可以使用System.IO.Ports
命名空间提供的SerialPort
类。下面是一个简单的例子,包含了一个基本的UI,用于设置串口参数和进行通讯。这里使用了Windows Forms(WinForms)来创建UI。
步骤:
创建新的C#项目: 在Visual Studio中创建一个新的Windows Forms应用程序项目。
设计UI: 打开Form1.cs
文件,通过拖放控件创建以下UI元素:
ComboBox
控件用于选择串口和波特率。Button
控件用于打开/关闭串口。TextBox
控件用于显示接收到的数据。TextBox
控件用于输入要发送的数据。Button
控件用于发送数据。添加SerialPort控件: 在Form1.cs
文件中,在类的顶部添加以下代码:
using System.IO.Ports;
在类的声明下方添加以下代码:
private SerialPort serialPort;
初始化串口: 在Form1
的构造函数中初始化串口和其他控件:
public Form1() { InitializeComponent(); // 初始化串口 serialPort = new SerialPort(); serialPort.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler); // 获取可用串口并添加到ComboBox string[] ports = SerialPort.GetPortNames(); comboBoxPort.Items.AddRange(ports); // 默认波特率选择 comboBoxBaudRate.SelectedItem = "9600"; }
打开/关闭串口按钮点击事件: 添加以下代码到打开/关闭按钮的点击事件中:
private void buttonOpenClose_Click(object sender, EventArgs e) { if (!serialPort.IsOpen) { // 打开串口 serialPort.PortName = comboBoxPort.SelectedItem.ToString(); serialPort.BaudRate = int.Parse(comboBoxBaudRate.SelectedItem.ToString()); try { serialPort.Open(); buttonOpenClose.Text = "关闭串口"; } catch (Exception ex) { MessageBox.Show("串口打开失败:" + ex.Message, "错误"); } } else { // 关闭串口 serialPort.Close(); buttonOpenClose.Text = "打开串口"; } }
发送数据按钮点击事件: 添加以下代码到发送按钮的点击事件中:
private void buttonSend_Click(object sender, EventArgs e) { if (serialPort.IsOpen) { string data = textBoxSend.Text; serialPort.Write(data); } else { MessageBox.Show("串口未打开!", "错误"); } }
接收数据事件处理: 添加以下代码用于处理接收到的数据:
private void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e) { SerialPort sp = (SerialPort)sender; string data = sp.ReadExisting(); // 在UI线程上更新TextBox BeginInvoke(new Action(() => { textBoxReceive.AppendText(data); })); }
清理资源: 在窗体关闭时,确保关闭串口并释放资源:
private void Form1_FormClosing(object sender, FormClosingEventArgs e) { if (serialPort.IsOpen) { serialPort.Close(); } }
完整代码如下:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO.Ports;
namespace 串口程序
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
// 初始化串口
serialPort1 = new SerialPort();
serialPort1.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler);
// 获取可用串口并添加到ComboBox
string[] ports = SerialPort.GetPortNames();
comboBoxPort.Items.AddRange(ports);
// 设置默认的串口号
if (ports.Length > 0)
{
comboBoxPort.SelectedItem = ports[0];
}
// 默认波特率选择
comboBoxBaudRate.SelectedItem = "9600";
}
private void button1_Click(object sender, EventArgs e)//打开串口
{
if (!serialPort1.IsOpen)
{
// 打开串口
serialPort1.PortName = comboBoxPort.SelectedItem.ToString();
serialPort1.BaudRate = int.Parse(comboBoxBaudRate.SelectedItem.ToString());
try
{
serialPort1.Open();
buttonOpenClose.Text = "关闭串口";
buttonOpenClose.BackColor = Color.Lime;
}
catch (Exception ex)
{
MessageBox.Show("串口打开失败:" + ex.Message, "错误");
}
}
else
{
// 关闭串口
serialPort1.Close();
buttonOpenClose.Text = "打开串口";
buttonOpenClose.BackColor = Color.White;
}
}
private void button2_Click(object sender, EventArgs e)//发送数据
{
if (serialPort1.IsOpen)
{
string data = textBoxSend.Text;
byte[] byteData = Encoding.UTF8.GetBytes(data); // 将字符串转换为字节数组
serialPort1.Write(byteData, 0, byteData.Length);
}
else
{
MessageBox.Show("串口未打开!", "错误");
}
}
private void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e)//接收数据
{
SerialPort sp = (SerialPort)sender;
int bytesToRead = sp.BytesToRead;
byte[] byteData = new byte[bytesToRead];
sp.Read(byteData, 0, bytesToRead);
// 将接收到的字节数组转换为字符串
string data = Encoding.UTF8.GetString(byteData);
// 在UI线程上更新TextBox
BeginInvoke(new Action(() =>
{
textBoxReceive.AppendText(data + Environment.NewLine);
}));
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)//关闭窗体时关闭串口
{
if (serialPort1.IsOpen)
{
serialPort1.Close();
}
}
private void button3_Click(object sender, EventArgs e)//清空发送/接收数据
{
textBoxSend.Clear();
textBoxReceive.Clear();
}
}
}
调试截图如下:
以上程序只是一个简单的demo,有很多没有完善,比如接收和发送字符串会出现乱码,小弟只是在此抛砖引玉,望各位大神补齐!