这节介绍实现的是利用SerialPort类进行串口的链接。
.Net Framework 作为微软开发的一个框架,万变不离其宗,要怎么使用一个东西,就最好看它的说明书 。
SerialPort Class 的文档链接:https://docs.microsoft.com/en-us/dotnet/api/system.io.ports.serialport?view=netframework-4.5
它的示例介绍写着:
The following code example demonstrates the use of the SerialPort class to allow two users to chat from two separate computers connected by a null modem cable. In this example, the users are prompted for the port settings and a username before chatting. Both computers must be executing the program to achieve full functionality of this example.
提取重点就是:两个计算机的users 通过使用SerialPort class 去进行聊天 ,两个电脑通过的是a null modem cable(这里应该指的是串口线,因为RS232线的名字是RS232 Cable (Null Modem Cable))进行连接。
我们现阶段主要实现的从串口中获取数据,写数据暂时不需要,所以我们可以在里面提取我们需要的部分。
在文档的左侧,我们可以选择其方法和事件来选择我们所需要的实例。
选取事件中的DataReceived,我们这次所需要的,其实例代码:
using System;
using System.IO.Ports;
class PortDataReceived
{
public static void Main()
{
SerialPort mySerialPort = new SerialPort("COM1");
mySerialPort.BaudRate = 9600;
mySerialPort.Parity = Parity.None;
mySerialPort.StopBits = StopBits.One;
mySerialPort.DataBits = 8;
mySerialPort.Handshake = Handshake.None;
mySerialPort.RtsEnable = true;
mySerialPort.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler);
mySerialPort.Open();
Console.WriteLine("Press any key to continue...");
Console.WriteLine();
Console.ReadKey();
mySerialPort.Close();
}
private static void DataReceivedHandler(
object sender,
SerialDataReceivedEventArgs e)
{
SerialPort sp = (SerialPort)sender;
string indata = sp.ReadExisting();
Console.WriteLine("Data Received:");
Console.Write(indata);
}
}
可以看到,微软的实例很清楚的向我们展示了需要初始化的内容和SerialDataReceivedEventHandler的使用,有兴趣的可以先体验实现一下,然后我们看一下我们程序里面使用的版本。
看一下界面:
界面实现,两个 comboBox,DropDownStyle选择DropDownList只允许选不允许修改,然后通过button进行触发(打开/关闭)。comboBox的数据项自己设计,串口这里就可以利用SerialPort.GetPortNames()来获取电脑的串口。
串口comboBox实现代码:
private void Com_comboBox_Click()
{
string[] portNamesArray = SerialPort.GetPortNames();
this.Com_comboBox.Items.Clear();
foreach (var item in portNamesArray)
{
this.Com_comboBox.Items.Add(item);
}
this.Com_comboBox.Items.Add("");
}
波特率就没什么实现代码啦,数据项我是写了几个常用在item里面了。
(因为停止位什么的都是写死的,所以直接用Label写死)
然后就是按钮的实现代码,里面主要是对串口的初始化和打开 :
private void Com_btn_Click(object sender, EventArgs e)
{
if (!com.IsOpen)
{
try
{
string serialName = Com_comboBox.SelectedItem.ToString();
com.PortName = serialName;
string strBaudRate = Bps_comboBox.SelectedItem.ToString();
Int32 iBaudRate = Convert.ToInt32(strBaudRate);
com.BaudRate = iBaudRate;
com.Parity = Parity.None;//无奇偶校验位
com.StopBits = StopBits.One;//1个停止位
com.Handshake = Handshake.RequestToSend;//控制协议
com.ReceivedBytesThreshold = 13;//设置 DataReceived 事件发生前内部输入缓冲区中的字节数
com.Handshake = Handshake.RequestToSend;//握手协议:RTS硬件流控制
com.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler);
if (com.IsOpen == true)
{
com.Close();
}
com.Open();
Com_btn.Text = "关闭串口";
}
catch (Exception ex)
{
MessageBox.Show("错误信息:" + ex.Message + "!");
return;
}
}
else
{
com.Close();
Com_btn.Text = "打开串口";
}
}
DataReceivedHandler的代码:
void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e)
{
try
{
if (com.IsOpen)
{
try
{
TimeSpan waitTime = new TimeSpan(0, 0, 0, 0, 50);//自己加的延时
Thread.Sleep(waitTime);
string str = "";//接收的字符串
int count = com.BytesToRead;
byte[] readBuffer = new byte[count];//byte
com.Read(readBuffer, 0, count);
foreach (byte item in readBuffer)
{
str += Convert.ToChar(item);//byte[] to char ->string
}
com.DiscardOutBuffer();//outBuffer
if (count != 0)
{
//线程里不可以直接对UI进行赋值
this.Invoke(new System.Threading.ThreadStart(delegate ()
{
/*
这里可以更新UI
*/
}
}));
}
}
catch (TimeoutException) { }
}
else
{
TimeSpan waitTime = new TimeSpan(0, 0, 0, 0, 50);
Thread.Sleep(waitTime);
}
}
catch (Exception ex)
{
MessageBox.Show("错误信息:" + ex.Message + "!");
}
}
(这里转换数据的方法网上五花八门,而且有的还有些乱码什么的,踏了不少坑还是微软的文档比较省事)
我用的是读取字节,再转成char再拼接成字符串,好像Read可以直接接收Char字符,可以把处理数据那里改成:
// Read (char[] buffer, int offset, int count);
char[] readBuffer = new char[count];
com.Read(readBuffer, 0, count);
foreach (char item in readBuffer)
{
str += item;
}
SerialPort类到此就介绍完成了,完成到这里,你的项目已经具备了连接串口、接收数据的功能了(更新UI的代码在更新Ui章节贴出)。
自备串口助手这个就不用说了,除此之外建议大家安装一个虚拟串口工具,在大家没有连接硬件的情况下,通过串口助手发送数据,也能进行测试。
我用的是Configure Virtual Serial Port Driver,添加端口就能用,一个发一个收,还挺好用的。
下一节介绍Chart图表的应用。