返回顶部
首页 > 资讯 > 精选 >.Net Core的CustomSerialPort()怎么用
  • 732
分享到

.Net Core的CustomSerialPort()怎么用

2023-06-26 06:06:42 732人浏览 薄情痞子
摘要

这篇文章主要介绍“.net Core的CustomSerialPort()怎么用”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“.Net Core的CustomSerialPort

这篇文章主要介绍“.net Core的CustomSerialPort()怎么用”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“.Net Core的CustomSerialPort()怎么用”文章能帮助大家解决问题。

    摘要

    在使用SerialPort进行串口协议解析过程中,经常遇到接收单帧协议数据串口接收事件多次触发,协议解析麻烦的问题。针对此情况,基于开源跨平台串口类库SerialPortStrem进行了进一步封装,实现了一种接收超时响应事件机制,简化串口通讯的使用。

    引言

    最近,写了一篇博文《.net core跨平台应用研究-串口篇》得到了一些园友的好评,文中介绍了在跨平台应用研究过程中,在dotNet Core下使用SerialPort类库在linux下不能支持的踩坑经历及解决办法。

    因网上关于SerialPort类库使用的相关文章较多,在该文中,对串口类库的使用,一笔带过。但在实际使用,使用过SerialPort类库的同学,可能遇到过在数据接收时,由于数据接收事件的触发具有不确定性,很多时候,一帧通讯协议数据,会多次触发,造成程序处理协议数据较为麻烦的问题。

    为简化串口通讯类库的使用,笔者结合自己的相关经验,封装了一个自定义增强型跨平台串口类库,以解决一帧协议数据,多次触发的问题。

    基础类库的选择

    由于考虑的是跨平台应用,SerialPort类库并不支持linux系统(在前一篇文章中已介绍过踩坑经历),笔者选用了SerialPortStream类库进行封装。

    该类库支持windows系统和Linux系统,但在Linux系统下运行,需要额外编译目标平台支持库并进行相关环境配置。

    相关编译配置说明在https://GitHub.com/jcurl/SerialPortStream已有介绍,也可参考本人的拙作《.net core跨平台应用研究-串口篇》

    类库的实现

    创建跨平台类库

    为了支持跨平台,我们使用Visual Studio 2017创建一个基于.NET Standard的类库。

    .Net Core的CustomSerialPort()怎么用

    NET Standard是一项api规范,每一个特定的版本,都定义了必须实现的基类库。

    .NET Core是一个托管框架,针对构建控制台、云、ASP.net coreUWP应用程序进行了优化

    每一种托管实现(如.NET Core、.NET Framework或Xamarin)都必须遵循.NET Standard实现基类库(BCL)。

    关于NET Standard和跨平台的详细说明在此:

    //www.yisu.com/article/234699.htm

    笔者也不再啰嗦呵。

    实现机制/条件

    通常串口通讯中,发送数据后,会有一段时间用于等待接收方应答,如此一来,两次数据发送之间,必然会有一定的时间间隔。如ModbusRTU协议就规定,两次数据报文发送之间,需要等待超过发送4个字节以上的间隔时间。

    笔者在单片机以及实时性较高的嵌入式系统中,为处理串口接收与协议的无关性,通常采用数据帧接收超时来处理数据帧的接收。根据串口通讯的速率计算出两次通讯之间所需要超时间隔,取两倍超时间隔时间作为超时参数,每接收到一个字节,将数据放入缓冲区并进行计时,当最后一个字节的接收时间超过超时时间,返回接收数据并清空缓存,一次完整接收完成(DMA接收方式不在此讨论)。

    .net core跨平台实现

    在自定义的串口类中,订阅基础串口类数据接收事件,在接收事件每次触发后,读出当前可用的缓冲数据到自定义缓冲区,同时,标记最后接收时间Tick为当前系统Tick。判断是否开启了接收超时处理线程,如未开启,则开启一个接收超时处理线程。

    接收超时处理线程中,以一个较小的时间间隔进行判断,如果最后接收时间与当前时间之间的间隔小于设置值(默认128ms),休眠一段时间(默认16ms)后循环检查。如间隔时间大于设定值,触发外部接收订阅事件,传出接收到的数据,退出超时处理线程。

    此处应有流程图。呵呵,懒得画了,大家自行脑补吧。 ^_^

    在windows系统或linux系统中,因系统的多任务处理的特性,系统实时性较差,通常50ms以下时间间隔的定时任务,较大程度会出现不可靠的情况(任务执行时间都有可能超过调用间隔时间)。

    因此,默认超时时间间隔设置为128ms。也可根据实际使用情况调整,但最小间隔不宜低于64ms。

    注:此处为个人经验和理解,如不认同,请直接忽视。

    主要代码

    串口接收事件代码:

             protected void Sp_DataReceived(object sender, SerialDataReceivedEventArgs e)         {             int canReadBytesLen = 0;             if (ReceiveTimeoutEnable)             {                 while (sp.BytesToRead > 0)                 {                     canReadBytesLen = sp.BytesToRead;                     if (receiveDatalen + canReadBytesLen > BufSize)                     {                         receiveDatalen = 0;                         throw new Exception("Serial port receives buffer overflow!");                     }                     var receiveLen = sp.Read(recviceBuffer, receiveDatalen, canReadBytesLen);                     if (receiveLen != canReadBytesLen)                     {                         receiveDatalen = 0;                         throw new Exception("Serial port receives exception!");                     }                     //Array.Copy(recviceBuffer, 0, receivedBytes, receiveDatalen, receiveLen);                     receiveDatalen += receiveLen;                     lastReceiveTick = Environment.TickCount;                     if (!TimeoutCheckThreadIsWork)                     {                         TimeoutCheckThreadIsWork = true;                         Thread thread = new Thread(ReceiveTimeoutCheckFunc)                         {                             Name = "ComReceiveTimeoutCheckThread"                         };                         thread.Start();                     }                 }             }             else             {                 if (ReceivedEvent != null)                 {                     // 获取字节长度                     int bytesNum = sp.BytesToRead;                     if (bytesNum == 0)                         return;                     // 创建字节数组                     byte[] resultBuffer = new byte[bytesNum];                      int i = 0;                     while (i < bytesNum)                     {                         // 读取数据到缓冲区                         int j = sp.Read(recviceBuffer, i, bytesNum - i);                         i += j;                     }                     Array.Copy(recviceBuffer, 0, resultBuffer, 0, i);                     ReceivedEvent(this, resultBuffer);                     //System.Diagnostics.Debug.WriteLine("len " + i.ToString() + " " + ByteToHexStr(resultBuffer));                 }                 //Array.Clear (receivedBytes,0,receivedBytes.Length );                 receiveDatalen = 0;             }         }

    接收超时处理线程代码:

             /// <summary>         /// 超时返回数据处理线程方法         /// </summary>         protected void ReceiveTimeoutCheckFunc()         {             while (TimeoutCheckThreadIsWork)             {                 if (Environment.TickCount - lastReceiveTick > ReceiveTimeout)                 {                     if (ReceivedEvent != null)                     {                         byte[] returnBytes = new byte[receiveDatalen];                         Array.Copy(recviceBuffer, 0, returnBytes, 0, receiveDatalen);                         ReceivedEvent(this, returnBytes);                     }                     //Array.Clear (receivedBytes,0,receivedBytes.Length );                     receiveDatalen = 0;                     TimeoutCheckThreadIsWork = false;                 }                 else                     Thread.Sleep(16);             }         }

    创建.net core控制台程序

    为验证我们的类库是否能够正常工作,我们创建一个使用类库的.net core控制台程序。

    为啥选择dotnet core,原因很简单,跨平台。本程序分别需在windows和linux系统下进行运行测试

    •     显示系统信息(系统标识、程序标识等)

    •     列举系统可用串口资源

    •     选择串口

    •     打开串口/关闭串口

    •     串口测试(打开/发送/关闭)

             static void Main(string[] args)         {             SetLibPath();             ShowWelcome();              GetPortNames();             ShowPortNames();              if (serailports.Length == 0)             {                 Console.WriteLine($"Press any key to exit");                 Console.ReadKey();                  return;             } #if RunIsService             RunService(); #endif              bool quit = false;             while (!quit)             {                 Console.WriteLine("\r\nPlease Input command Key\r\n");                 Console.WriteLine("p:Show SerialPort List");                 Console.WriteLine($"t:Test Uart:\"{selectedComPort}\"");                 Console.WriteLine($"o:Open Uart:\"{selectedComPort}\"");                 Console.WriteLine($"c:Close Uart:\"{selectedComPort}\"");                 Console.WriteLine("n:select next serial port");                 Console.WriteLine("q:exit app");                 Console.WriteLine();                 var key = Console.ReadKey().KeyChar;                 Console.WriteLine();                  switch (key)                 {                     case (Char)27:                     case 'q':                     case 'Q':                         quit = true;                         break;                     case 's':                         ShowWelcome();                         break;                     case 'p':                         ShowPortNames();                         break;                     case 'n':                         SelectSerialPort();                         break;                     case 't':                         TestUart(selectedComPort);                         break;                     case 'w':                         TestWinUart(selectedComPort);                         break;                     case 'o':                         OpenUart(selectedComPort);                         break;                     case 'c':                         CloseUart();                         break;                 }             }         }

    笔者使用类库是直接引用类库项目,大家需要使用的话,可在解决方案资源管理器中,项目的依赖项上点击右键

    .Net Core的CustomSerialPort()怎么用

    在NuGet包管理器中,搜索SerialPort或flyfire即可找到并安装本类库。

    .Net Core的CustomSerialPort()怎么用

    类库地址

    类库地址:Https://www.nuget.org/packages/flyfire.CustomSerialPort

    .Net Core的CustomSerialPort()怎么用

    跨平台测试

    Windows测试输出界面

    .Net Core的CustomSerialPort()怎么用

    .Net Core的CustomSerialPort()怎么用

    ubuntu测试输出界面

    .Net Core的CustomSerialPort()怎么用

    关于“.Net Core的CustomSerialPort()怎么用”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识,可以关注编程网精选频道,小编每天都会为大家更新不同的知识点。

    --结束END--

    本文标题: .Net Core的CustomSerialPort()怎么用

    本文链接: https://lsjlt.com/news/307161.html(转载时请注明来源链接)

    有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

    猜你喜欢
    • .Net Core的CustomSerialPort()怎么用
      这篇文章主要介绍“.Net Core的CustomSerialPort()怎么用”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“.Net Core的CustomSerialPort...
      99+
      2023-06-26
    • .Net Core应用增强型跨平台串口类库CustomSerialPort()详解
      目录摘要引言基础类库的选择类库的实现创建跨平台类库实现机制/条件.net core跨平台实现主要代码创建.net core控制台程序类库地址跨平台测试Windows测试输出界面ubu...
      99+
      2024-04-02
    • .NET Core中的HttpClientFactory类怎么用
      小编给大家分享一下.NET Core中的HttpClientFactory类怎么用,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!一、HttpClient...
      99+
      2023-06-29
    • .NET Core中怎么使用Autofac
      今天小编给大家分享一下.NET Core中怎么使用Autofac的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。Au...
      99+
      2023-06-29
    • NET Core中的Worker Service是什么/怎么用
      本篇内容主要讲解“NET Core中的Worker Service是什么/怎么用”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“NET Core中的Worker Service是什么/怎么用”吧!...
      99+
      2023-06-09
    • 用于.NET Core的ORM是怎样的
      今天就跟大家聊聊有关用于.NET Core的ORM是怎样的,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。尽管EF Core正努力提供视图和存储过程等基本数据库特性,但是开发人员也在寻...
      99+
      2023-06-19
    • .Net Core 之AutoFac的使用
      目录Autofac介绍组件的三种注册方式生命周期AutoFac 在asp .net core中的使用本文不介绍IoC和DI的概念,如果你对Ioc之前没有了解的话,建议先去搜索一下相关...
      99+
      2024-04-02
    • .NET Core怎么配置TLS Cipher
      本篇内容介绍了“.NET Core怎么配置TLS Cipher”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!.NET C...
      99+
      2023-06-21
    • Ubuntu 14.04怎么部署.Net Core
      这篇文章主要介绍了Ubuntu 14.04怎么部署.Net Core的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇Ubuntu 14.04怎么部署.Net Core文章都会有所收获,下面我们一起来看看吧。.NE...
      99+
      2023-06-28
    • .Net Core WebAPI怎么导入CSV
      这篇文章主要介绍“.Net Core WebAPI怎么导入CSV”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“.Net Core WebAPI怎么导入CSV”...
      99+
      2023-06-30
    • 怎么用.net core 实现简单爬虫
      本篇内容主要讲解“怎么用.net core 实现简单爬虫”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“怎么用.net core 实现简单爬虫”吧!一.介绍一个Http请求框架HttpCode.C...
      99+
      2023-06-19
    • Linux中怎么使用Docker托管.NET Core
      这篇文章主要介绍“Linux中怎么使用Docker托管.NET Core”,在日常操作中,相信很多人在Linux中怎么使用Docker托管.NET Core问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Lin...
      99+
      2023-06-27
    • linux怎么部署.net Core项目
      这篇“linux怎么部署.net Core项目”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇...
      99+
      2024-04-02
    • .NET Core、Xamarin、.NET Standard和.NET Framework有什么区别
      这篇文章主要介绍.NET Core、Xamarin、.NET Standard和.NET Framework有什么区别,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!.NET Core.N...
      99+
      2023-06-26
    • .Net Core AOP之AuthorizeAttribute的作用是什么
      AuthorizeAttribute在.Net Core中的作用是用于对控制器或者控制器中的方法进行权限验证。当使用该属性时,只有具...
      99+
      2023-09-26
      .Net
    • 怎么使用Shell脚本执行.NET Core应用
      小编给大家分享一下怎么使用Shell脚本执行.NET Core应用,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!在本文中,我将研究如何创建 shell 脚本来运行...
      99+
      2023-06-09
    • .NET Core中使用gRPC的方法
      目录1.什么是gRPC1.基本介绍2.proto文件3.上手实践2.gRPC流1.服务端流、客户端流、双向流2.NetCore Web项目作为客户端3.gRPC AOP拦截1.什么是...
      99+
      2024-04-02
    • .Net Core下使用Dapper的方法
      目录一、前言二、Dapper环境搭建三、Dapper封装定义DapperDBContext类异步分页构建(PageAsync)定义工作单元与事务定义数据仓储数据库连接四、Dapper...
      99+
      2024-04-02
    • 怎么创建一个.NET Core工程
      小编给大家分享一下怎么创建一个.NET Core工程,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!打开VS2019,点击“创建新项目”,选择“ASP.N...
      99+
      2023-06-29
    • .net core异常中间件的使用
      目录正文结正文 if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } 这样写入中间件哈,那么在env环境...
      99+
      2024-04-02
    软考高级职称资格查询
    编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
    • 官方手机版

    • 微信公众号

    • 商务合作