C#串口通讯

发布时间:2023年12月19日

在C#写串口通讯小程序时,可以使用System.IO.Ports命名空间提供的SerialPort类。下面是一个简单的例子,包含了一个基本的UI,用于设置串口参数和进行通讯。这里使用了Windows Forms(WinForms)来创建UI。

步骤:

  1. 创建新的C#项目: 在Visual Studio中创建一个新的Windows Forms应用程序项目。

  2. 设计UI: 打开Form1.cs文件,通过拖放控件创建以下UI元素:

    • 两个ComboBox控件用于选择串口和波特率。
    • 一个Button控件用于打开/关闭串口。
    • 一个TextBox控件用于显示接收到的数据。
    • 一个TextBox控件用于输入要发送的数据。
    • 一个Button控件用于发送数据。
  3. 添加SerialPort控件:Form1.cs文件中,在类的顶部添加以下代码:

    using System.IO.Ports;

    在类的声明下方添加以下代码:

    private SerialPort serialPort;

  4. 初始化串口:Form1的构造函数中初始化串口和其他控件:

    public Form1() { InitializeComponent(); // 初始化串口 serialPort = new SerialPort(); serialPort.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler); // 获取可用串口并添加到ComboBox string[] ports = SerialPort.GetPortNames(); comboBoxPort.Items.AddRange(ports); // 默认波特率选择 comboBoxBaudRate.SelectedItem = "9600"; }

  5. 打开/关闭串口按钮点击事件: 添加以下代码到打开/关闭按钮的点击事件中:

    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 = "打开串口"; } }

  6. 发送数据按钮点击事件: 添加以下代码到发送按钮的点击事件中:

    private void buttonSend_Click(object sender, EventArgs e) { if (serialPort.IsOpen) { string data = textBoxSend.Text; serialPort.Write(data); } else { MessageBox.Show("串口未打开!", "错误"); } }

  7. 接收数据事件处理: 添加以下代码用于处理接收到的数据:

    private void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e) { SerialPort sp = (SerialPort)sender; string data = sp.ReadExisting(); // 在UI线程上更新TextBox BeginInvoke(new Action(() => { textBoxReceive.AppendText(data); })); }

  8. 清理资源: 在窗体关闭时,确保关闭串口并释放资源:

    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,有很多没有完善,比如接收和发送字符串会出现乱码,小弟只是在此抛砖引玉,望各位大神补齐!

文章来源:https://blog.csdn.net/weixin_42026861/article/details/135020614
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。