.NET Core跨平台串口通讯使用SerialPortStream基础类库问题解决

.NET Core跨平台串口通讯使用SerialPortStream基础类库问题解决

串口通讯在很多行业应用中都有着重要的地位,而串口通讯的跨平台解决方案在.NET Core 3.0之后,就有了更好的支持。本文将介绍如何使用SerialPortStream基础类库进行.NET Core跨平台串口通讯,并解决其中的常见问题。

安装SerialPortStream

在使用SerialPortStream之前,需要通过NuGet安装它。可以在Visual Studio中的NuGet包管理器中搜索SerialPortStream,或者使用以下命令在命令行中安装:

Install-Package SerialPortStream

打开串口并发送数据

使用SerialPortStream打开串口非常简单,可以按照以下代码来实现:

using System.IO.Ports;
using RJCP.IO.Ports;

SerialPortStream port = new SerialPortStream("COM1", 115200);
port.DataReceived += DataReceivedHandler;
port.Open();

这个代码片段的作用是打开COM1串口,并监听串口事件。可以通过添加DataReceived事件处理程序来处理收到的数据。

要向串口发送数据,可以使用以下代码:

byte[] buffer = new byte[] { 0x01, 0x02, 0x03 };
port.Write(buffer, 0, buffer.Length);

这个代码片段会向串口写入一个字节数组。

解决读取数据时发生的问题

在使用SerialPortStream读取数据时,可能会遇到数据不完整的问题。这是由于串口数据的异步性质引起的。解决这个问题的方法是使用缓冲区。可以使用以下代码:

private List<byte> buffer = new List<byte>();

private void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e)
{
    SerialPortStream port = (SerialPortStream)sender;
    int bytesToRead = port.BytesToRead;
    byte[] readBuffer = new byte[bytesToRead];
    port.Read(readBuffer, 0, bytesToRead);
    buffer.AddRange(readBuffer);
    ProcessData();
}

private void ProcessData()
{
    int messageStartIndex = buffer.IndexOf(0x01);
    int messageEndIndex = buffer.IndexOf(0x04);
    while (messageStartIndex >= 0 && messageEndIndex >= 0 && messageEndIndex > messageStartIndex)
    {
        byte[] message = buffer.GetRange(messageStartIndex, messageEndIndex - messageStartIndex + 1).ToArray();
        buffer.RemoveRange(0, messageEndIndex + 1);
        // 处理消息
        messageStartIndex = buffer.IndexOf(0x01);
        messageEndIndex = buffer.IndexOf(0x04);
    }
}

这个代码片段使用了一个buffer列表来缓存读取的数据,并在DataReceived事件处理程序中对读取的数据进行处理。ProcessData方法按照起始位和结束位来分离出完整的消息,并将处理过的数据从buffer中删除。

Python技术站热门推荐:

PDF电子发票识别软件,一键识别电子发票并导入到Excel中!

10大顶级数据挖掘软件!

人工智能的十大作用!

解决写入数据时发生的问题

在使用SerialPortStream写入数据时,可能会遇到数据不完整的问题。这是由于串口的写入速度可能比应用程序处理数据的速度快。解决这个问题的方法是使用写入缓冲区。使用以下代码:

private void WriteData(byte[] data)
{
    int offset = 0;
    while (offset < data.Length)
    {
        int bytesToWrite = Math.Min(data.Length - offset, port.WriteBufferSize);
        port.Write(data, offset, bytesToWrite);
        offset += bytesToWrite;
        port.BaseStream.Flush();
        Thread.Sleep(10); // 等待一段时间,避免写入速度过快
    }
}

这个代码片段将要写入的数据data分段进行写入,并在写入每一段数据后调用Flush方法,以确保数据被写入到串口。

扩展阅读

SerialPortStream类库的文档可以在它的GitHub仓库中找到。如果你想进一步了解.NET Core串口通讯,可读取官方文档。

示例说明

下面是一个使用SerialPortStream读取串口数据的示例代码,它会读取串口数据,并将数据打印出来:

using System;
using System.Collections.Generic;
using System.IO.Ports;
using System.Threading;
using RJCP.IO.Ports;

class Program
{
    static SerialPortStream port;
    static List<byte> buffer = new List<byte>();

    static void Main(string[] args)
    {
        port = new SerialPortStream("COM1", 115200);
        port.DataReceived += DataReceivedHandler;
        port.Open();
        Console.ReadKey();
        port.Close();
    }

    static void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e)
    {
        SerialPortStream port = (SerialPortStream)sender;
        int bytesToRead = port.BytesToRead;
        byte[] readBuffer = new byte[bytesToRead];
        port.Read(readBuffer, 0, bytesToRead);
        buffer.AddRange(readBuffer);
        ProcessData();
    }

    static void ProcessData()
    {
        int messageStartIndex = buffer.IndexOf(0x01);
        int messageEndIndex = buffer.IndexOf(0x04);
        while (messageStartIndex >= 0 && messageEndIndex >= 0 && messageEndIndex > messageStartIndex)
        {
            byte[] message = buffer.GetRange(messageStartIndex, messageEndIndex - messageStartIndex + 1).ToArray();
            buffer.RemoveRange(0, messageEndIndex + 1);
            Console.WriteLine(BitConverter.ToString(message));
            messageStartIndex = buffer.IndexOf(0x01);
            messageEndIndex = buffer.IndexOf(0x04);
        }
    }
}

下面是一个向串口发送数据的示例代码,它会周期性地向串口发送数据:

using System;
using System.IO.Ports;
using RJCP.IO.Ports;

class Program
{
    static SerialPortStream port;

    static void Main(string[] args)
    {
        port = new SerialPortStream("COM1", 115200);
        port.Open();
        while (true)
        {
            byte[] data = new byte[] { 0x01, 0x02, 0x03 };
            WriteData(data);
            Thread.Sleep(1000);
        }
    }

    static void WriteData(byte[] data)
    {
        int offset = 0;
        while (offset < data.Length)
        {
            int bytesToWrite = Math.Min(data.Length - offset, port.WriteBufferSize);
            port.Write(data, offset, bytesToWrite);
            offset += bytesToWrite;
            port.BaseStream.Flush();
            Thread.Sleep(10);
        }
    }
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
书名:《Visual C#.NET串口通信及测控应用典型实例》(电子工业出版社.李江全.邓红涛.刘巧.李伟) PDF格式扫描版,全书分为8章,共369页。2012年5月出版。 全书压缩打包成3部分,这是第1部分 内容简介 本书从工程应用的角度出发,通过8个典型应用实例,包括PC与PC、PC与单片机、PC与PLC、PC与远程I/O模块、PC与智能仪器、PC与无线数传模块、Pc与USB数据采集模块等组成的测控系统,利用SerialPort控件和MSComm控件编写C#.NET串口通信程序,并对计算机测控系统中的4类典型应用((模拟量输入(AI)、模拟量输出(AO)、数字量输入(DI)和数字量输出(DO)的程序设计方法进行了详细的讲解。 目 录 第1章 PC与PC串口通信 1.1 串口通信概述 1.1.1 串口通信的基本概念 1.1.2 RS-232C接口标准 1.1.3 RS-422/485接口标准 1.1.4 串口通信线路连接 1.1.5 PC中的串行端口 1.1.6 虚拟串口的使用 1.2 VC++.NET串行通信控件与API函数 1.2.1 MSComm控件的使用 1.2.2 SerialPort控件的使用 1.2.3 串行通信API函数 1.3 PC与PC串口通信实例 1.3.1 两台PC串口通信 1.3.2 一台PC双串口互通信 第2章 PC与单片机串口通信 2.1 典型单片机开发板简介 2.1.1 单片机测控系统的组成 2.1.2 单片机开发板B的功能 2.1.3 单片机开发板B的主要电路 2.2 PC与单片机串口通信实例 2.2.1 PC与单个单片机串口通信 2.2.2 PC与多个单片机串口通信 2.3 PC与单片机串口通信测控应用实例 2.3.1 模拟量输入 2.3.2 模拟量输出 2.3.3 开关量输入 2.3.4 开关量输出 第3章 PC与西门子PLC串口通信 3.1 西门子PLC模拟量扩展模块与通信协议 3.1.1 西门子PLC模拟量输入模块 3.1.2 西门子PLC PPI通信协议 3.2 PC与西门子PLC串口通信测控应用实例 3.2.1 模拟量输入 3.2.2 模拟量输出 3.2.3 开关量输入 3.2.4 开关量输出 第4章 PC与三菱PLC串口通信 4.1 三菱PLC特殊功能模块与通信协议 4.1.1 FX2N系列PLC的特殊功能模块 4.1.2 三菱PLC编程口通信协议 4.2 PC与三菱PLC串口通信测控应用实例 4.2.1 模拟量输入 4.2.2 模拟量输出 4.2.3 开关量输入 4.2.4 开关量输出 第5章 PC与分布式I/O模块串口通信 5.1 典型分布式I/O模块简介 5.1.1 集散控制系统的结构与特点 5.1.2 ADAM4000远程数据采集控制系统 5.1.3 ADAM4000系列模块简介 5.1.4 ADAM4000系列模块的软件安装 5.2 PC与分布式I/O模块串口通信测控应用实例 5.2.1 模拟量输入 5.2.2 模拟量输出 5.2.3 数字量输入 5.2.4 数字量输出 第6章 PC与智能仪器串口通信 6.1 典型智能仪器简介 6.1.1 智能仪器的结构与特点 6.1.2 XMT-3000A型智能仪器的通信协议 6.2 PC与智能仪器串口通信测控应用实例 6.2.1 PC与单台智能仪器温度测控 6.2.2 PC与多台智能仪器温度测控 第7章 PC与无线数据传输模块串口通信 7.1 典型无线数传模块简介 7.1.1 无线数传技术概述 7.1.2 DTD46X系列无线数传模块 7.2 PC与无线数传模块串口通信测控应用实例 7.2.1 设计任务 7.2.2 线路连接 7.2.3 利用C51语言实现基于DS18B20的单片机温度测控 7.2.4 利用汇编语言实现基于DS18B20的单片机温度测控 7.2.5 利用VC++.NET实现PC与无线数传模块温度测控 第8章 USB串行总线模块测控应用 8.1 USB总线在数据采集系统中的应用 8.1.1 USB总线及其数据采集系统的特点 8.1.2 采用USB传输的数据采集系统 8.1.3 典型USB数据采集模块及应用 8.1.4 VC++.NET数据采集与控制的方式 8.2 PC与USB数据采集模块测控应用实例 8.2.1 模拟量输入 8.2.2 模拟量输出 8.2.3 数字量输入 8.2.4 数字量输出 参考文献
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值