本篇内容介绍了“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);}
“C#串口通信工具类的封装方法”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注编程网网站,小编将为大家输出更多高质量的实用文章!