一、前言
我一名还没毕业的大学生,本次我要做一个关于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;
我们可以在窗体上看到的效果
二、打开串口
配置串口参数需要配置以下的内容:
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等。
我的窗体布局和实验结果(有点简陋,有待改进)
总代码:
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";
}
}
}
}