在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);// 获取可用串口并添加到ComboBoxstring[] 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线程上更新TextBoxBeginInvoke(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,有很多没有完善,比如接收和发送字符串会出现乱码,小弟只是在此抛砖引玉,望各位大神补齐!