C#串口通信工具类的封装
作者:绿叶清风 发布时间:2023-11-23 11:19:54
标签: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);
}
来源:https://blog.csdn.net/PZ0605/article/details/107863448
0
投稿
猜你喜欢
- Spring提供的工具类,主要用于框架内部使用,这个类提供了一些简单的方法,并且提供了易于使用的方法在分割字符串,如CSV字符串,以及集合和
- 添加MyBatis的代码并修改以下部分:1.添加MyBatisConfigpackage myshop.config;import java
- Spring Boot读取配置文件1)通过注入ApplicationContext 或者 Environment对象来读取配置文件里的配置信
- 一:SparkSQL1.SparkSQL简介Spark SQL是Spark的一个模块,用于处理结构化的数据,它提供了一个数据抽象DataFr
- 本文实例为大家分享了Android保存QQ密码功能的具体代码,供大家参考,具体内容如下技术要点:使用文件储存的方式保存数据实现步骤:①用户交
- 什么是抽象类什么是抽象类呢?抽象类顾名思义就是很抽象,就是当我们没有足够的信息去描述这个类的时候我们就可以先不用描述,这样的类就是抽象类。用
- Java中Filter、Servlet、Listener的学习资料,希望大家喜欢1、Filter的功能filter功能,它使用户可以改变一个
- 前言新建的Compose项目默认的 Material 主题为我们提供了一些颜色,但对我这种花里胡哨的人来说根本不够呀。
- 购物车项目,业务需要实现了一个购物车的项目,简单的了解下实现逻辑:数据计算等是在Adapter中计算出来的,通过在Adapter中计算出来的
- 本文实例讲述了Android开发实现判断通知栏是否打开及前往设置页面的方法。分享给大家供大家参考,具体如下:项目中用到日程提醒功能,如果应用
- Android XML設置屏幕方向(android:screenOrientation)详解注意:Android只支持270度旋
- 最近在公司,项目不是很忙了,偶尔看见一个兄台在CSDN求助,帮忙要一个自定义的渐变色进度条,我当时看了一下进度条,感觉挺漂亮的,就尝试的去自
- 1、Service层:业务层–>控制业务业务模块的逻辑功能设计,和DAO层一样都是先设计接口,再创建要实现的类,然
- 前言之所以会有这篇文章,是因为公司的开发环境比较老,寻找一些jar包的时候总是会纠结对应的编译版本,感觉很麻烦,所以写了一个工具类用于读取c
- 本文实例为大家分享了java实现简单猜数字的具体代码,供大家参考,具体内容如下代码不多说,图片自加,实现功能有数字比大小,菜单开始,帮助,退
- JOL简介JOL的全称是Java Object Layout。是一个用来分析JVM中Object布局的小工具。包括Object在内存中的占用
- 面试官:sychronized关键字有哪些特性?应聘者:可以用来修饰方法;可以用来修饰代码块;可以用来修饰静态方法;可以保证线程安全;支持锁
- 在C++中,当你去创建一个类的时候,即便这个类是空类,也会自动生成下面6个默认成员函数,在本篇博客中,我将逐一分析下面6个默认成员函数。构造
- 本文实例为大家分享了AnAndroid图片无限轮播的具体代码,供大家参考,具体内容如下public class MainActivity e
- 前言目前正在做的项目,为了增加用户的体验度,准备增加一些动画效果,其中底部栏中间按钮的点击事件参考了闲鱼的动效,便在此基础上仿写了该动效,并