C# 串口连接的读取与发送(附串口工具的编写源码)

您所在的位置:网站首页 如何关闭串口接收中断命令 C# 串口连接的读取与发送(附串口工具的编写源码)

C# 串口连接的读取与发送(附串口工具的编写源码)

#C# 串口连接的读取与发送(附串口工具的编写源码)| 来源: 网络整理| 查看: 265

一、串口连接的打开与关闭

串口,即COM口,在.NET中使用 SerialPort 类进行操作。串口开启与关闭,是涉及慢速硬件的IO操作,频繁打开或关闭会影响整体处理速度,甚至导致打开或关闭串口失败。非特殊情况,串口一次性打开后,在退出程序时关闭串口即可。在打开串口前,可以设置一些常用的参数。常用的参数如下:

(1)串口的接受/发送超时时间:ReadTimeout/WriteTimeout。

(2) 串口的接受/发送缓存区大小:ReadBufferSize/WriteBufferSize。

具体代码如下:

1 // Open Com 2 _serialPort = new SerialPort(com, baud); 3 if (_serialPort.IsOpen) _serialPort.Close(); 4 5 // Set the read / write timeouts 6 _serialPort.ReadTimeout = 500; 7 _serialPort.WriteTimeout = 500; 8 9 // Set read / write buffer Size,the default of value is 1MB 10 _serialPort.ReadBufferSize = 1024 * 1024; 11 _serialPort.WriteBufferSize = 1024 * 1024; 12 13 _serialPort.Open(); 14 15 // Discard Buffer 16 _serialPort.DiscardInBuffer(); 17 _serialPort.DiscardOutBuffer();

需要注意的是超出缓冲区的部分会被直接丢弃。因此,如果需要使用串口传送大文件,那接收方和发送方都需要将各自的缓冲区域设置的足够大,以便能够一次性存储下大文件的二进制数组。若条件限制,缓冲区域不能设置过大,那就需要在发送大文件的时候按照发送缓冲区大小分包去发送,接收方按顺序把该数组组合起来形成接受文件的二进制数组。

二、串口发送

SerialPort 类发送支持二进制发送与文本发送,需要注意的是文本发送时,需要知道转换的规则,一般常用的是ASCII、UTF7、UTF-8、UNICODE、UTF32。具体代码如下:

1 #region Send 2 /// 3 /// 发送消息(byte数组) 4 /// 5 /// 6 /// 7 /// 8 public void Send(byte[] buffer, int offset, int count) 9 { 10 lock (_mux) 11 { 12 _serialPort.Write(buffer, offset, count); 13 _sendCount += (count - offset); 14 } 15 } 16 17 /// 18 /// 发送消息(字符串) 19 /// 20 /// 字符串编码方式,具体方式见 21 /// 22 public void Send(Encoding encoding , string message) 23 { 24 lock (_mux) 25 { 26 var buffer = encoding.GetBytes(message); 27 _serialPort.Write(buffer, 0, buffer.Length); 28 _sendCount += buffer.Length; 29 } 30 } 31 #endregion

三、串口接受

​ 串口接受需要注意,消息接受与消息处理要代码分离。不能把流程处理的代码放入信息接受处,因为消息处理或多或少会有耗时,这会造成当发送方发送过快时,接受方的接受缓冲区会缓存多条消息。我们可以把接受到的消息放入队列中,然后在外部线程中,尝试去拿出该条消息进行消费。采用 “生产-消费”模式。具体代码如下:

1 #region Receive 2 private void PushMessage() 3 { 4 _serialPort.DataReceived += (sender, e) => 5 { 6 lock (_mux) 7 { 8 if (_serialPort.IsOpen == false) return; 9 int length = _serialPort.BytesToRead; 10 byte[] buffer = new byte[length]; 11 _serialPort.Read(buffer, 0, length); 12 _receiveCount += length; 13 _messageQueue.Enqueue(buffer); 14 _messageWaitHandle.Set(); 15 } 16 }; 17 } 18 19 /// 20 /// 获取串口接受到的内容 21 /// 22 /// 取消息的超时时间 23 /// 返回byte数组 24 public byte[] TryMessage(int millisecondsToTimeout = -1) 25 { 26 if (_messageQueue.TryDequeue(out var message)) 27 { 28 return message; 29 } 30 31 if (_messageWaitHandle.WaitOne(millisecondsToTimeout)) 32 { 33 if (_messageQueue.TryDequeue(out message)) 34 { 35 return message; 36 } 37 } 38 return default; 39 } 40 #endregion

四、完整代码与测试结果

​ 串口工具类的完整代码如下:

imgView Code

​ 测试代码如下:

imgView Code

使用串口工具测试如下,对于串口的接受如丝般顺滑。当我们在消息中增加测试延时后,就会发现当串口工具继续快速发送一段时间后关闭发送,发现使用队列后,依然没有丢失一条来自发送方的消息。

img

五、串口工具编写实例

通过以上对串口的了解,我们模仿串口工具进行编程,完成如下:

img img

该串口工具采用WPF框架的MVVM模式进行开发,代码地址:https://github.com/Dwayne112401/MyProgra-SerialportTool



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3