自定义串口通讯类的实现

前面写串口通讯是有界面的,后面的项目感觉串口通讯只是辅助的作用,应该专门写一个不可视的类来做,这样的好处是通讯模块是独立的,要用的时候直接引用就行了。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.IO.Ports;
using System.Threading;
using System.Windows.Forms;

namespace YBDW
{
? ? class SerialPortCommunication
? ? {
? ? ? ? //声明变量
? ? ? ? public SerialPort sp = new SerialPort();
? ? ? ? public bool isOpen = false;//串口是否被打开
? ? ? ? public bool SetSetPropertyOK = false;//属性是否设置好
? ? ? ? public bool isDataFormatHex = false;//数据格式是否是16进制
? ? ? ? List<byte> ReceiveDataList = new List<byte>();//定义一个泛型数组来接收数据
? ? ? ? string sDataChar;//转换成的字符串
? ? ? ? //声明事件
? ? ? ? public delegate void OnReceiveMsgHandler(string s1);
? ? ? ? public event OnReceiveMsgHandler OnReceiveMsg;//接收数据事件

? ? ? ? public struct isCommPortPropertys
? ? ? ? {
? ? ? ? ? ? public string sPort;//串口号
? ? ? ? ? ? public string sBaudRate;//波特率
? ? ? ? ? ? public string sDataBit;//数据位
? ? ? ? ? ? public string sParity;//校验位
? ? ? ? ? ? public string sStopBit;//停止位
? ? ? ? ? ? public string sDataFormat;//数据格式
? ? ? ? ? ? public string sReadTimeout;//超时读取时间
? ? ? ? }

? ? ? ? public isCommPortPropertys CommPortProperty = new isCommPortPropertys();

? ? ? ? //构造函数
? ? ? ? public SerialPortCommunication()
? ? ? ? {
? ? ? ? ? ? //
? ? ? ? ? ? //sp.sp_DataReceived += OnReceiveMsg;
? ? ? ? }

? ? ? ? public void SetCommPortProperty()
? ? ? ? {
? ? ? ? ? ? //设置串口属性
? ? ? ? ? ? sp.PortName = CommPortProperty.sPort;
? ? ? ? ? ? sp.BaudRate = Convert.ToInt32(CommPortProperty.sBaudRate);
? ? ? ? ? ? sp.DataBits = Convert.ToInt16(CommPortProperty.sDataBit);
? ? ? ? ? ? switch (CommPortProperty.sParity)
? ? ? ? ? ? {
? ? ? ? ? ? ? ? case "无":
? ? ? ? ? ? ? ? ? ? sp.Parity = Parity.None;
? ? ? ? ? ? ? ? ? ? break;
? ? ? ? ? ? ? ? case "奇校验":
? ? ? ? ? ? ? ? ? ? sp.Parity = Parity.Odd;
? ? ? ? ? ? ? ? ? ? break;
? ? ? ? ? ? ? ? case "偶校验":
? ? ? ? ? ? ? ? ? ? sp.Parity = Parity.Even;
? ? ? ? ? ? ? ? ? ? break;
? ? ? ? ? ? ? ? default:
? ? ? ? ? ? ? ? ? ? sp.Parity = Parity.None;
? ? ? ? ? ? ? ? ? ? break;
? ? ? ? ? ? }
? ? ? ? ? ? switch (CommPortProperty.sDataFormat)
? ? ? ? ? ? {
? ? ? ? ? ? ? ? case "ASCII":
? ? ? ? ? ? ? ? ? ? isDataFormatHex = false;
? ? ? ? ? ? ? ? ? ? break;
? ? ? ? ? ? ? ? case "HEX":
? ? ? ? ? ? ? ? ? ? isDataFormatHex = true;
? ? ? ? ? ? ? ? ? ? break;
? ? ? ? ? ? ? ? default:
? ? ? ? ? ? ? ? ? ? isDataFormatHex = false;
? ? ? ? ? ? ? ? ? ? break;
? ? ? ? ? ? }
? ? ? ? ? ? sp.ReadTimeout = Convert.ToInt32(CommPortProperty.sReadTimeout);
? ? ? ? ? ? sp.RtsEnable = true;
? ? ? ? ? ? //挂接DataReceived数据接收事件,当串口收到数据后触发该事件
? ? ? ? ? ? sp.DataReceived += new SerialDataReceivedEventHandler(sp_DataReceived);
? ? ? ? ? ? SetSetPropertyOK = true;
? ? ? ? }

? ? ? ? public void Close()
? ? ? ? {
? ? ? ? ? ? sp.DataReceived -= sp_DataReceived;
? ? ? ? ? ? sp.Close();
? ? ? ? ? ? isOpen = false;
? ? ? ? }

? ? ? ? public void Start()
? ? ? ? {
? ? ? ? ? ? if (SetSetPropertyOK)
? ? ? ? ? ? {
? ? ? ? ? ? ? ? try
? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? sp.Open();
? ? ? ? ? ? ? ? ? ? isOpen = true;
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? catch (Exception e)
? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? sp.Close();
? ? ? ? ? ? ? ? ? ? isOpen = false;
? ? ? ? ? ? ? ? ? ? MessageBox.Show("属性没有设置好!"+e.ToString());
? ? ? ? ? ? ? ? }
? ? ? ? ? ? }
? ? ? ? }

? ? ? ? private void sp_DataReceived(object sender,SerialDataReceivedEventArgs e)
? ? ? ? {
? ? ? ? ? ? Thread.Sleep(100);//休眠100毫秒
? ? ? ? ? ? byte[] ReceiveDataByte = new byte[sp.BytesToRead];//创建接收字节数组 ? ? ? ? ?
? ? ? ? ? ? sp.Read(ReceiveDataByte, 0, ReceiveDataByte.Length);//读取接收到的数据
? ? ? ? ? ? ReceiveDataList.Clear();
? ? ? ? ? ? sDataChar = "";
? ? ? ? ? ? ReceiveDataList.AddRange(ReceiveDataByte);
? ? ? ? ? ? if (isDataFormatHex)
? ? ? ? ? ? {
? ? ? ? ? ? ? ? //16进制
? ? ? ? ? ? ? ? for (int i=0;i<ReceiveDataByte.Length;i++)
? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? sDataChar += ReceiveDataByte[i].ToString("X2") + " ";
? ? ? ? ? ? ? ? }
? ? ? ? ? ? }
? ? ? ? ? ? else
? ? ? ? ? ? {
? ? ? ? ? ? ? ? //ASCII
? ? ? ? ? ? ? ? sDataChar = Encoding.Default.GetString(ReceiveDataList.ToArray());
? ? ? ? ? ? }?
? ? ? ? ? ? if (this.OnReceiveMsg != null) OnReceiveMsg(sDataChar);//通过事件传递接收到的数据
? ? ? ? }?

? ? ? ? public void SendData(string sSendData)
? ? ? ? {
? ? ? ? ? ? bool CanSend = true;
? ? ? ? ? ? if (string.IsNullOrEmpty(sSendData)) CanSend = false;
? ? ? ? ? ? if (!isOpen) CanSend = false;
? ? ? ? ? ? if (CanSend) sp.WriteLine(sSendData);
? ? ? ? }
? ? }
}

这样的好处是通讯只负责接收或者发送数据,处理数据有专门的类来完成,代码是相互独立分开的。
引用:

? ? ? ? //创建串口对象
? ? ? ? SerialPortCommunication YBDWCommPort =new SerialPortCommunication();//串口通讯
  //设置串口属性
  FrmSetCommPort Frm1 = new FrmSetCommPort();
  Frm1.TransmitEvent += Transmit;
  if (Frm1.ShowDialog() == DialogResult.OK)
  {
  ? ? YBDWCommPort.CommPortProperty.sPort = DawnCommPortProperty.sPort;//串口号
  ? ? YBDWCommPort.CommPortProperty.sBaudRate = DawnCommPortProperty.sBaudRate;//波特率
  ? ? YBDWCommPort.CommPortProperty.sStopBit = DawnCommPortProperty.sStopBit;//停止位
  ? ? YBDWCommPort.CommPortProperty.sDataBit = DawnCommPortProperty.sDataBit;//数据位
  ? ? YBDWCommPort.CommPortProperty.sParity = DawnCommPortProperty.sParity;//奇偶校验位
  ? ? YBDWCommPort.CommPortProperty.sDataFormat = DawnCommPortProperty.sDataFormat;//数据格式
  ? ? YBDWCommPort.CommPortProperty.sReadTimeout = DawnCommPortProperty.sReadTimeout;//超时读取时间
  ? ? YBDWCommPort.SetCommPortProperty();
  ? ? //启动侦听,接收串口数据
  ? ? YBDWCommPort.OnReceiveMsg += OnReceiveMsg;
  ? ? YBDWCommPort.Start();
  ? ? this.button1.Text = "关闭串口";
  }

  //数据处理

? ? ? ? private void OnReceiveMsg(string s1)
? ? ? ? {
? ? ? ? ? ? if (string.IsNullOrEmpty(s1))
? ? ? ? ? ? {
? ? ? ? ? ? ? ? //跳过
? ? ? ? ? ? }
? ? ? ? ? ? else
? ? ? ? ? ? {
? ? ? ? ? ? ? ? //接收数据的处理
? ? ? ? ? ? ? ? this.BeginInvoke(new Action(() => {
? ? ? ? ? ? ? ? //异步处理,不影响其他的进程,关闭串口也不会出现错误
? ? ? ? ? ? ? ? }));
? ? ? ? ? ? {
? ? ? ? }

原文地址:https://blog.51cto.com/dawn0919/2360568

时间: 2024-08-04 21:53:12

自定义串口通讯类的实现的相关文章

串口通讯服务类

通讯事件类 public class ComEvent { /// <summary> /// 数据接收事件 /// </summary> /// <param name="sender"></param> /// <param name="data"></param> public delegate void DataReceivedHandler(object sender, string

VC 串口通信类

为了节省时间,我就贴出来吧 头文件 SerialPort.h 1 /*************************************************************************************************** 2 * SerialPort.h 3 * 4 * 功 能:串口通讯类 5 * 类 名:CSerialPort 6 * 7 * Ver 变更日期 负责人 变更内容 8 * ───────────────────────────────

串口通讯编程

本代码参考  网络通信程序设计<张晓明 编著>,在此记下方便自己以后查询 1.以下窗口为串口设置页面代码 using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using System

设计一个串口装饰类(1)

团队正在开发一个仪器控制软件的框架,希望该框架能兼容/容忍一些硬件的变换,以及灵活定制建立在该硬件平台之上的工作流.目标仪器使用了很多的串口通信(Serial Port),所以大家觉得应该设计/封装一个统一的串口类来管理串口通信的一致性.就我个人的意见来说,我不是建议在System.IO.Port.SerialPort上再做封装的.串口通信逻辑很简单,基本就是I/O.该类已经提供了同步阻塞模型.基于事件的异步模型,各种I/O快捷方法,所以不认为封装该类可以获得什么更多好处.但是面对框架的 一些其

【转载】使用Win32API实现Windows下异步串口通讯

一,异步非阻塞串口通讯的优点 读写串行口时,既可以同步执行,也可以重叠(异步)执行.在同步执行时,函数直到操作完成后才返回.这意味着在同步执行时线程会被阻塞,从而导致效率下降.在重叠执行时,即使操作还未完成,调用的函数也会立即返回.费时的I/O操作在后台进行,这样线程就可以干别的事情.例如,线程可以在不同的句柄上同时执行I/O操作,甚至可以在同一句柄上同时进行读写操作."重叠"一词的含义就在于此. 二,异步非阻塞串口通讯的基本原理首先,确定要打开的串口名.波特率.奇偶校验方式.数据位.

串口通讯的代码 。是别人写的 我加了些注释。

// Communication.h: interface for the CCommunication class. // ////////////////////////////////////////////////////////////////////// #if !defined(AFX_COMMUNICATION_H__6CA00576_F088_11D1_89BB_8311A0F2733D__INCLUDED_) #define AFX_COMMUNICATION_H__6CA0

简单的串口通讯程序

很早以前写过串口通讯的代码,今天又要用到,做了一个简单的类封装. 代码如下: rs485Test.h #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/types.h> #include <sys/stat.h> #include <termios.h> #include <fcntl.h> #include <errno

C#串口操作类,包括串口读写操作

串口进行操作的类,其中包括写和读操作,类可设置串口参数.设置接收函数.打开串口资源.关闭串口资源,操作完成后,一定要关闭串口.接收串口数据事件.接收数据出错事件.获取当前全部串口.把字节型转换成十六进制字符串等功能.这个串口类已经过了调试,可以使用: using System; using System.Collections.Generic; using System.Text; using System.IO.Ports; using System.Globalization; namesp

Winform 串口通讯之读卡器

老板给我的第一个硬件就是一个读卡器, 说让我做一下试试,于是从网上查了查就写了出来,相当的简单. 但是后来还有一个地磅的串口通讯,我整整搞了一天. 在窗体类的构造函数中写入 Form.CheckForIllegalCrossThreadCalls = false; 可以在线程外更新窗体,这样就可以一直接收数据,一直更新ui了. 打开串口按钮: 1 //实例化 2 SerialPort Myport = new SerialPort(); 3 //设置串口端口 4 Myport.PortName