一、前言
我一名还没毕业的大学生,本次我要做一个关于C#的串口接发数据的实验,这个实验有点简单你忍一下,这实验中我参考了一些烂大街的代码,做了自己的总结。
环境:Visual Studio 2017社区版

实验前构思:
要串口通讯,我必须指定一个串口,要是我电脑里同时存在多个串口怎么办?那么我要获取电脑中的串口,用一个Combo Box来保存我的串口号。
有了串口号,但是我们在发送数据前必须打开串口,打开串口必须给串口的一些参数配置好。
串口打开我们就可以收发数据了,收发数据一定要在串口打开的情况下进行。
二、获取串口号添加到combo Box
关键代码:

string[] portname = SerialPort.GetPortNames();

这里我知识用数组保存了一个get到的串口名称,然后我们通过遍历的方法把串口名称添加到combo Box上,

foreach (string s in portname)
    {
        comboBox1.Items.Add(s);
    }

这样的话初始化的时候combo Box上还是空空的看起来不舒服,所以给combo Box添加一个索引,让他初始化的时候就显示其中一个串口名称。

comboBox1.SelectedIndex = 0;

我们可以在窗体上看到的效果

抓串口数据 wireshark 如何抓取串口数据_串口

二、打开串口
配置串口参数需要配置以下的内容:

serial_.PortName = comboBox1.Text.Trim();
serial_.Open();
serial_.BaudRate = 115200;
serial_.DataBits = 8;
serial_.StopBits = StopBits.One;
serial_.Parity = Parity.None;
serial_.ReadTimeout = 100;
serial_.WriteTimeout = -1;

对于接收数据的初始化

serial_.ReceivedBytesThreshold = 1;
serial_.DataReceived += new SerialDataReceivedEventHandler(Serial_Received);

打开串口却不知道有没有打开?添加反馈
1.用messagebox.show()。2.添加到textbox.appendtext()或者输出到控制台console.writeline()。
我选择改变按钮颜色和文字作为反馈,很好理解,我用文字判断串口的状态进行一次开关,在开之前要先确认关闭。

if (button2.Text.Equals(“open”))
 {
 serial_.Close();
 serial_.Open();
 button2.BackColor = Color.Green;
 button2.Text = “close”;
 }
 else if (button2.Text.Equals(“close”)) {
 serial_.Close();
 button2.BackColor = Color.Gray;
 button2.Text = “open”;
 }


添加接收时间时间,(这段函数想要理解清楚一点可以去了解一下委托),只要接收到一位的数据就触发接收信号的函数Serial_Received。

三、串口发送
老规矩一个hello world!
这里我直接用一个按键触发串口发送数据功能,这里演示我直接写死。

private void button1_Click(object sender, EventArgs e)
{
    serial_.Write("Hello World!");
}

四、串口接收
上面我们说了收到信号就触发Serial_Received函数,然后我们重写这个函数。里面的Invoke是很有必要的,必须添加上去不然会报错,具体原因后面补充,当然还有其他办法解决这个错误,但是写法不太稳妥。
简单的串口接收我们只需要做到这个地步。

private void Serial_Received(object sender, SerialDataReceivedEventArgs e)
{
    SerialPort serial = (SerialPort)sender;
    
    string s = serial.ReadExisting();
    this.Invoke(new Action(() =>
    {
        textBox1.AppendText("收到信息!");
        textBox1.AppendText(s);
    }));
}

五、总结

1.这个实验总体不难,但是要实现一些特殊的功能的话还是得改进一下。

2.里面设计的知识有线程(理解),委托(理解),还有对控件的一些基本的使用,对串口的数据传输原理,一些基本接口的使用。

3.运行时遇到一些问题的时候可能会中断,但是这问题自己时知道的,我们可以用抛出异常的方法try{}catch(){}来让程序抛出已知的异常,让程序继续运行下去。这个方法在一些有关连接的模块很广泛地被应用,例如socket,mysql等。

我的窗体布局和实验结果(有点简陋,有待改进)

抓串口数据 wireshark 如何抓取串口数据_抓串口数据 wireshark_02

总代码:

using System;
using System.Windows.Forms;
using System.IO.Ports;
using System.Drawing;

namespace recevice_test
{
    public partial class Form1 : Form
    {
        SerialPort serial_ = new SerialPort();
        string[] portname = SerialPort.GetPortNames();
        public Form1()
        {
            InitializeComponent();
            
        }
        private void Form1_Load(object sender, EventArgs e)
        {
            foreach (string s in portname)
            {
                comboBox1.Items.Add(s);
            }
            comboBox1.SelectedIndex = 0;

            serial_.PortName = comboBox1.Text.Trim();
            serial_.Open();
            serial_.BaudRate = 115200;
            serial_.DataBits = 8;
            serial_.StopBits = StopBits.One;
            serial_.Parity = Parity.None;
            serial_.ReadTimeout = 100;
            serial_.WriteTimeout = -1;
            serial_.ReceivedBytesThreshold = 1;
            serial_.DataReceived += new SerialDataReceivedEventHandler(Serial_Received);
            serial_.Close();
        }

        private void Serial_Received(object sender, SerialDataReceivedEventArgs e)
        {
            SerialPort serial = (SerialPort)sender;
            
            string s = serial.ReadExisting();
            this.Invoke(new Action(() =>
            {
                textBox1.AppendText("收到信息!");
                textBox1.AppendText(s);
            }));
        }

        private void button1_Click(object sender, EventArgs e)
        {
            serial_.Write("Hello World!");
        }

        private void button2_Click(object sender, EventArgs e)
        {
            if (button2.Text.Equals("open"))
            {
                serial_.Close();
                serial_.Open();
                button2.BackColor = Color.Green;
                button2.Text = "close";
            }
            else if (button2.Text.Equals("close")) {
                serial_.Close();
                button2.BackColor = Color.Gray;
                button2.Text = "open";
            }
            
        }
    }
}