年前写到python串口通信发送16进制字符串,年后实习工作中尝试使用C#进行串口通信。由于这个语言不是很熟,所以转圈了一天半。值得一提的是,两者在尝试的经历都是极为一致,第一天网上漫无目的的找demo发现都不能用,烦恼了一天,第二天上午往往打算从头再来的时候,都能够成功。

该实验需要用到C#的SerialPort库函数,该函数存在于C# 的.net framework中,C# core没有的。

详情可以参看文末的参考链接。

本实验分为三个步骤:构建对象配置参数、发送数据、收受数据。

构建对象

首先需要引用IO库

using System.IO.Ports;

一般来说,使用频率较大的有两个构造函数,一个是无参构造,一个是”全参”构造函数,本人比较推荐后者。

//无参构造
SerialPort port=new SerialPort();
port.PortName = "COM1";
port.BaudRate = 9600;
port.Parity = Parity.Even;
port.StopBits = StopBits.One;
port.DataBits = 8;
//"全参"构造
SerialPort port = new SerialPort("COM1", 9600, Parity.Even, 8, StopBits.One);

发送数据

这里我要发送的数据是一串16进制的数,简写成“68 AA AA AA AA AA AA 68 13 00 DF 16”。

关于数据组织,有两种写法,前一种是新手的写法,最简单、保险;后一种是网上找来的,是用来linq,比较优雅,有种写python推导式的感觉,如沐春风,见贤思齐。

//方法一
byte[] aa = new byte[12];
aa[0] = 0x68;
aa[1] = 0xAA;
aa[2] = 0xAA;
aa[3] = 0xAA;
aa[4] = 0xAA;
aa[5] = 0xAA;
aa[6] = 0xAA;
aa[7] = 0x68;
aa[8] = 0x13;
aa[9] = 0x00;
aa[10] = 0xDF;
aa[11] = 0x16;
//方法二
//最上面引用
using System.Linq;
String s = "68 AA AA AA AA AA AA 68 13 00 DF 16";
byte[] aa = s.Split(' ').AsParallel().Select(x => Convert.ToByte(x, 16)).ToArray();

SerialPort有一个Write()方法,根据官方文档的写法有三个重载,我们选择第二个,因为是16进制数。

Write(String) 将指定的字符串写入串行端口。
Write(Byte[], Int32, Int32) 使用缓冲区中的数据将指定数量的字节写入串行端口。
Write(Char[], Int32, Int32) 使用缓冲区中的数据将指定数量的字符写入串行端口。
port.Write(aa, 0, aa.Length);

接收数据

根据年前python的经验,我们需要设置延迟时间,要不然无法接收数据。我们需要引用Threading

using System.Threading;

其中,延迟的使用方法为使用Thread的静态方法

Thread.Sleep(100);

使用Read()来接收串口数据,两种方法都需要我们先创造一个数组来接收数据。

Read(Byte[], Int32, Int32) 从 SerialPort输入缓冲区读取一些字节并将那些字节写入字节数组中指定的偏移量处。
Read(Char[], Int32, Int32) 从 SerialPort输入缓冲区中读取一些字符,然后将这些字符写入字符数组中指定的偏移量处。
byte[] data = new byte[20];
port.Read(data, 0, 20);

至此,我们已经接收到了数据,但是是10进制数,我们可以根据需求进一步处理。

参考链接

微软文档-SerialPort 构造函数