C#串口通信工具类的封装

本文实例为大家分享了C#串口通信工具类的封装代码,供大家参考,具体内容如下

 1、SerialPortHelper串口工具类封装

using System;
using System.Collections.Generic;
using System.IO.Ports;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Timers;
 
namespace public.Util
{
 
    /// <summary>
    /// 串口操作助手类
    /// </summary>
    class SerialPortHelper
    {
         /// <summary>
        /// 串口是否已打开
        /// </summary>
        public bool IsOpen { get; set; }
 
        /// <summary>
        /// 初始化 串行端口资源
        /// </summary>
        private SerialPort mySerialPort = new SerialPort();
 
        /// <summary>
        /// 串口接收数据 位置
        /// </summary>
        private static int pSerialPortRecv = 0;
 
        /// <summary>
        /// 缓存区大小的长度
        /// 缓冲区可调大
        /// (接收数据处理定时器 内接收数据量 小于下面设置的值即可)
        /// </summary>
        private static int byteLength = 40960;
 
        /// <summary>
        /// 串口接收字节 缓存区大小
        /// </summary>
        private byte[] byteSerialPortRecv = new byte[byteLength];
 
        /// <summary>
        /// 串口 接收数据处理定时器
        /// </summary>
        private Timer SerialPortRecvTimer;
 
        /// <summary>
        /// 广播 收到的数据 事件
        /// </summary>
        public event EventHandler<SerialPortRecvEventArgs> ReceivedDataEvent;
 
        /// <summary>
        /// 广播 收到的数据
        /// </summary>
        public class SerialPortRecvEventArgs : EventArgs
        {
            /// <summary>
            /// 广播 收到的串口数据
            /// </summary>
            public readonly byte[] RecvData = new byte[byteLength];
 
            /// <summary>
            /// 收到数据 的 长度
            /// </summary>
            public readonly int RecvDataLength;
 
            /// <summary>
            /// 将 收到的数据 转化成 待广播的数据
            /// </summary>
            public SerialPortRecvEventArgs(byte[] recvData, int recvDataLength)
            {
                recvData.CopyTo(RecvData, 0);
                RecvDataLength = recvDataLength;
            }
        }
 
        /// <summary>
        /// 初始化
        /// </summary>
        public SerialPortHelper()
        {
            IsOpen = false;
        }
 
        /// <summary>
        /// 设置 串口配置
        /// </summary>
        /// <param name="portName">串口号</param>
        /// <param name="baudRate">波特率</param>
        /// <param name="parity">校验位</param>
        /// <param name="dataBits">数据位</param>
        /// <param name="stopBits">停止位</param>
        private void SetSerialPortConfig(string portName, int baudRate, int parity, int dataBits, int stopBits)
        {
            // 串口 参数设置
            mySerialPort.PortName = portName;
            mySerialPort.BaudRate = baudRate;
            switch (parity)
            {
                case 0:
                default:
                    mySerialPort.Parity = Parity.None;
                    break;
 
                case 1:
                    mySerialPort.Parity = Parity.Odd;
                    break;
 
                case 2:
                    mySerialPort.Parity = Parity.Even;
                    break;
 
                case 3:
                    mySerialPort.Parity = Parity.Mark;
                    break;
 
                case 4:
                    mySerialPort.Parity = Parity.Space;
                    break;
            }
            mySerialPort.DataBits = ((4 < dataBits) && (dataBits < 9)) ? dataBits : 8;
            switch (stopBits)
            {
                case 0:
                    mySerialPort.StopBits = StopBits.None;
                    break;
 
                case 1:
                default:
                    mySerialPort.StopBits = StopBits.One;
                    break;
 
                case 2:
                    mySerialPort.StopBits = StopBits.OnePointFive;
                    break;
 
                case 3:
                    mySerialPort.StopBits = StopBits.Two;
                    break;
            }
            mySerialPort.ReadTimeout = -1;
            mySerialPort.RtsEnable = true;
            mySerialPort.DataReceived += new SerialDataReceivedEventHandler(DataReceived);
 
            // 串口 接收数据处理定时器 参数设置
            SerialPortRecvTimer = new System.Timers.Timer();
            SerialPortRecvTimer.Interval = 100;
            SerialPortRecvTimer.AutoReset = false;
            SerialPortRecvTimer.Elapsed += new ElapsedEventHandler(SPRecvTimer_Tick);
        }
 
        /// <summary>
        /// 打开串口
        /// </summary>
        /// <param name="portName">串口号</param>
        /// <param name="baudRate">波特率</param>
        /// <param name="parity">校验位</param>
        /// <param name="dataBits">数据位</param>
        /// <param name="stopBits">停止位</param>
        public void OpenSerialPort(string portName, int baudRate, int parity, int dataBits, int stopBits)
        {
            try
            {
                SetSerialPortConfig(portName, baudRate, parity, dataBits, stopBits);
                mySerialPort.Open();
                IsOpen = true;
            }
            catch (System.Exception)
            {
                IsOpen = false;
                throw;
            }
        }
 
        /// <summary>
        /// 关闭串口
        /// </summary>
        public void CloseSerialPort()
        {
            try
            {
                mySerialPort.Close();
                IsOpen = false;
            }
            catch (System.Exception)
            {
                IsOpen = false;
                throw;
            }
        }
 
        /// <summary>
        /// 串口数据发送
        /// </summary>
        /// <param name="content">byte类型数据</param>
        public void SendData(byte[] content)
        {
            try
            {
                mySerialPort.Write(content, 0, content.Length);
            }
            catch (System.Exception)
            {
                throw;
            }
        }
 
        /// <summary>
        /// 串口数据发送
        /// </summary>
        /// <param name="strContent">字符串数据</param>
        /// <param name="encoding">编码规则</param>
        public void SendData(string strContent, Encoding encoding)
        {
            try
            {
                byte[] content = encoding.GetBytes(strContent);
                mySerialPort.Write(content, 0, content.Length);
            }
            catch (System.Exception)
            {
                throw;
            }
        }
 
        /// <summary>
        /// 数据处理定时器
        /// 定时检查缓冲区是否有数据,如果有数据则将数据处理并广播。
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void SPRecvTimer_Tick(object sender, EventArgs e)
        {
            byte[] TemporaryData = new byte[byteLength];
            int TemporaryDataLength = 0;
 
            if (ReceivedDataEvent != null)
            {
                byteSerialPortRecv.CopyTo(TemporaryData, 0);
                TemporaryDataLength = pSerialPortRecv;
 
                ReceivedDataEvent.Invoke(this, new SerialPortRecvEventArgs(TemporaryData, TemporaryDataLength));
                // 数据处理完后,将指针指向数据头,等待接收新的数据
                pSerialPortRecv = 0;
            }
        }
 
        /// <summary>
        /// 数据接收事件
        /// 串口收到数据后,关闭定时器,将收到的数据填入缓冲区,数据填入完毕后,开启定时器,等待下一次数据接收
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            try
            {
                SerialPortRecvTimer.Stop();
 
                byte[] ReadBuf = new byte[mySerialPort.BytesToRead];
                mySerialPort.Read(ReadBuf, 0, ReadBuf.Length);
                ReadBuf.CopyTo(byteSerialPortRecv, pSerialPortRecv);
                pSerialPortRecv += ReadBuf.Length;
 
                SerialPortRecvTimer.Start();
            }
            catch (System.Exception)
            {
                throw;
            }
        }
 
        /// <summary>
        /// 获取当前可用PortName
        /// </summary>
        /// <returns></returns>
        public static List<SerialPortParam<string>> GetPortList()
        {
            try
            {
                List<SerialPortParam<string>> lst_sParameterClass = new List<SerialPortParam<string>>();
                foreach (string data in SerialPort.GetPortNames())
                {
                    SerialPortParam<string> i_sParameterClass = new SerialPortParam<string>();
                    i_sParameterClass.Name = data;
                    i_sParameterClass.Value = data;
                    lst_sParameterClass.Add(i_sParameterClass);
                }
 
                return lst_sParameterClass;
            }
            catch (Exception)
            {
                
                throw;
            }
        }
 
        /// <summary>
        /// 设置波特率
        /// </summary>
        /// <returns></returns>
        public static List<SerialPortParam<int>> SetBaudRateValues()
        {
            try
            {
                List<SerialPortParam<int>> lst_sParameterClass = new List<SerialPortParam<int>>();
                foreach (SerialPortBaudRates rate in Enum.GetValues(typeof(SerialPortBaudRates)))
                {
                    SerialPortParam<int> i_sParameterClass = new SerialPortParam<int>();
                    i_sParameterClass.Name = ((int)rate).ToString();
                    i_sParameterClass.Value = (int)rate;
                    lst_sParameterClass.Add(i_sParameterClass);
                }
 
                return lst_sParameterClass;
            }
            catch (Exception)
            {
                throw;
            }
        }
    }
 
 
 
    /// <summary>
    /// 设置串口助手参数类,如:波特率
    /// </summary>
    public class SerialPortParam<T> {
        /// <summary>
        /// 显示值
        /// </summary>
        string name;
 
        /// <summary>
        /// 显示值
        /// </summary>
        public string Name
        {
            get { return name; }
            set { name = value; }
        }
 
        /// <summary>
        /// 值
        /// </summary>
        T value;
 
        /// <summary>
        /// 值
        /// </summary>
        public T Value
        {
            get { return this.value; }
            set { this.value = value; }
        }
 
    }
 
 
    /// <summary>
    /// 串口波特率列表。
    /// 75,110,150,300,600,1200,2400,4800,9600,14400,19200,28800,38400,56000,57600,
    /// 115200,128000,230400,256000
    /// </summary>
    public enum SerialPortBaudRates
    {
        BaudRate_75 = 75,
        BaudRate_110 = 110,
        BaudRate_150 = 150,
        BaudRate_300 = 300,
        BaudRate_600 = 600,
        BaudRate_1200 = 1200,
        BaudRate_2400 = 2400,
        BaudRate_4800 = 4800,
        BaudRate_9600 = 9600,
        BaudRate_14400 = 14400,
        BaudRate_19200 = 19200,
        BaudRate_28800 = 28800,
        BaudRate_38400 = 38400,
        BaudRate_56000 = 56000,
        BaudRate_57600 = 57600,
        BaudRate_115200 = 115200,
        BaudRate_128000 = 128000,
        BaudRate_230400 = 230400,
        BaudRate_256000 = 256000
    }
}

2、串工工具类的使用方法

//模拟一个点击事件 
SerialPortHelper serialPortHelper = new SerialPortHelper();
private void button1_Click(object sender, EventArgs e)
 {
           
            serialPortHelper.OpenSerialPort("COM2"/*串口号*/, 115200/*波特率*/, 0/*校验位*/, 8/*数据位*/, 1/*停止位*/);
 
            // 订阅事件 可以放在 Form_Load 中 或者其他函数中,但必须执行
            serialPortHelper.ReceivedDataEvent += new EventHandler<SerialPortHelper.SerialPortRecvEventArgs>(serialPortHelper_ReceivedDataEvent);
 
            serialPortHelper.SendData(new byte[] { 0x0D });//send
 
 
            serialPortHelper.CloseSerialPort();//close
 
        }
 
/// <summary>
/// 接收串口数据
/// </summary>
/// <param name="sender"></param>
/// <param name="args"></param>
private void serialPortHelper_ReceivedDataEvent(object sender, SerialPortHelper.SerialPortRecvEventArgs args)
  {
            // 数据内容
            Console.Write(args.RecvData);
            // 数据长度
            Console.Write(args.RecvDataLength);
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • C#串口通信程序实例详解

    创建C#串口通信程序之命名空间 System.IO.Ports命名空间中最重用的是SerialPort 类. 创建C#串口通信程序之创建SerialPort 对象 通过创建SerialPort 对象,我们可以在程序中控制串口通信的全过程. 我们将要用到的SerialPort 类的方法: ReadLine():从输入缓冲区读一新行的值,如果没有,会返回NULLWriteLine(string):写入输出缓冲Open():打开一个新的串口连接Close():关闭 复制代码 代码如下: SerialP

  • 基于C#实现串口通信

    本文实例为大家分享了C#实现串口通信的具体代码,供大家参考,具体内容如下 1.基本概念 2.前端winForm布局如下(仅仅为了实现功能,布局略丑) 3.代码实现如下 namespace SerialPortTest   {       public partial class Form1 : Form       {           SerialPort sp1 = new SerialPort();           public Form1()           {        

  • C#串口通信实现方法

    本文实例讲述了C#串口通信实现方法.分享给大家供大家参考.具体方法如下: 通过COM1发送数据,COM2接收数据.当COM2接收完本次发送的数据后,向COM1发送信息通知COM1本次数据已发完,COM1接到通知后,再发下一段数据.这样可以确保每次发送的数据都可以被正确接收. 代码如下: 复制代码 代码如下: using System; using System.Collections.Generic; using System.ComponentModel; using System.Data;

  • C#中的串口通信SerialPort详解

    今天这篇文章带大家学习下C#中的串口通讯.在日常的开发工作中,如果工作内容是CS方向的同学应该很容易接触到串口通讯方面的业务需求.那么也就很容易想到C#中SerialPort类,它就是专门来处理串口通讯相关的. 了解什么是串口通讯 串口通讯是指外设和计算机间通过数据信号线,地线,控制线等,按位进行传输数据的一种通讯方式. 这种通讯方式使用的数据线少,在远距离通信中可以节约成本,但其传输速度比并行通讯慢. 串口是计算机上一种非常通用的设备通讯协议.大多数计算机包含两个基于RS-232的串口. 串口

  • C#串口通信模块使用方法示例

    C#串口模块的使用.使用VS .net框架下WinForm程序应用开发. C#开发的串口通信小工具. 相比于QT添加的串口类,WinForm是通过组件的形式将串口加入到程序中.. 在创建完windows窗体之后,添加组件类,就可以将串口加入到其中. 然后就需要写数据成员,初始化和方法,实现串口的读写功能. 串口类数据成员 SerialPort SComm; // 使用构造函数取串口控件 TextBox MsgRc; // 接收数据成员 //构造函数初始化 public SerialComm(Se

  • C#串口通信工具类的封装

    本文实例为大家分享了C#串口通信工具类的封装代码,供大家参考,具体内容如下  1.SerialPortHelper串口工具类封装 using System; using System.Collections.Generic; using System.IO.Ports; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Timers;   namespace public.Util {

  • 基于Java编写串口通信工具

    最近一门课要求编写一个上位机串口通信工具,我基于Java编写了一个带有图形界面的简单串口通信工具,下面详述一下过程,供大家参考 ^_^ 一: 首先,你需要下载一个额外的支持Java串口通信操作的jar包,由于java.comm比较老了,而且不支持64位系统,这里推荐Rxtx这个jar包(32位/64位均支持). 官方下载地址:http://fizzed.com/oss/rxtx-for-java (注:可能需要FQ才能下载) 不能FQ的童鞋,可以在这里下载: http://xiazai.jb51

  • Java实现Http工具类的封装操作示例

    本文实例讲述了Java实现Http工具类的封装操作.分享给大家供大家参考,具体如下: http工具类的实现:(通过apache包)第一个类 import java.io.IOException; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.HttpStatus; import org.apache.http.client.ClientProtocolE

  • 实例解析iOS app开发中音频文件播放工具类的封装

    一.简单说明 1.关于音乐播放的简单说明 (1)音乐播放用到一个叫做AVAudioPlayer的类 (2)AVAudioPlayer常用方法 加载音乐文件 复制代码 代码如下: - (id)initWithContentsOfURL:(NSURL *)url error:(NSError **)outError; - (id)initWithData:(NSData *)data error:(NSError **)outError; 准备播放(缓冲,提高播放的流畅性) - (BOOL)prep

  • Android动画工具类的封装实战记录

    起因 最近在做一个组件化框架的封装,现在开发到一些常用工具类的封装了,突然意识到好像还没有做动画的工具类,于是开始着手开发之. 思路 既然要做动画,肯定是要做属性动画的工具类的封装了,由于补间动画和逐帧动画并不能改变目标动画主题的实际属性,在Android的开发中已经越来越少人去用这两个动画框架做开发了,而属性动画则相对的越来越广泛的使用在开发过程中了,于是这次的工具类的封装,只针对属性动画来封装. 属性动画对应的类叫做ObjectAnimator,主要就是用这个类来实现动画的一些基础设置,其具

  • Redis缓存穿透/击穿工具类的封装

    目录 1. 简单的步骤说明 2. 逻辑缓存数据类型 3. 缓冲工具类的封装 3.1 CacheClient 类的类图结构 3.2 CacheClient 类代码 1. 简单的步骤说明 创建一个逻辑缓存数据类型 封装缓冲穿透和缓冲击穿工具类 2. 逻辑缓存数据类型 这里主要是创建一个可以往Redis里边存放的数据类型 RedisData 的Java类型 import lombok.Data; import java.time.LocalDateTime; @Data public class Re

  • pagehelper分页工具类的封装

    本文实例为大家分享了pagehelper分页工具类的封装代码,供大家参考,具体内容如下 现状: 在使用Mybatis进行数据库分页查询时,我们经常使用的是插件:pagehelper 此插件可以帮助我们很方便的进行数据库分页操作,但是使用此插件每次都需要先开启插件,然后再手动的对参数进行封装,这些都是模板化的套路,有没有一种更简洁的方法,让我们不在关注具体的分页细节,只需要实现我们的业务逻辑呢?所以接下来我将使用Spring AOP技术,对该工具类进行封装,让我们可以更方便的进行分页操作: 依赖:

  • iOS开发中音频工具类的封装以及音乐播放器的细节控制

    一.控制器间数据传递 两个控制器之间数据的传递 第一种方法: 复制代码 代码如下: self.parentViewController.music=self.music[indexPath.row]; 不能满足 第二种做法:把整个数组传递给它 第三种做法:设置一个数据源,设置播放控制器的数据源是这个控制器.self.parentViewController.dataSource=self;好处:没有耦合性,任何实现了协议的可以作为数据源. 第四种做法:把整个项目会使用到的音频资源交给一个工具类去

  • 详解javascript常用工具类的封装

    前言 因为工作中经常用到这些方法,所有便把这些方法进行了总结. JavaScript 1. type 类型判断 isString (o) { //是否字符串 return Object.prototype.toString.call(o).slice(8, -1) === 'String' } isNumber (o) { //是否数字 return Object.prototype.toString.call(o).slice(8, -1) === 'Number' } isObj (o) {

  • Android指纹登录工具类封装

    本文实例为大家分享了Android指纹登录工具类的封装代码,供大家参考,具体内容如下 核心 Android 指纹 是在 6.0 才出来的一个重要的功能 @RequiresApi(api = Build.VERSION_CODES.M) 核心的两个 api: FingerprintManager KeyguardManager step1 判断android 版本,如果小于 6.0 支持不了指纹 if(Build.VERSION.SDK_INT < Build.VERSION_CODES.M){

随机推荐