C#串口操作类,包括串口读写操作
串口进行操作的类,其中包括写和读操作,类可设置串口参数、设置接收函数、打开串口资源、关闭串口资源,操作完成后,一定要关闭串口、接收串口数据事件、接收数据出错事件、获取当前全部串口、把字节型转换成十六进制字符串等功能。这个串口类已经过了调试,可以使用:
using System;
using System.Collections.Generic;
using System.Text;
using System.IO.Ports;
using System.Globalization;
namespace SerialClass
{
public class SerialClass
{
SerialPort _serialPort = null;
//定义委托
public delegate void SerialPortDataReceiveEventArgs(object sender, SerialDataReceivedEventArgs e, byte[] bits);
//定义接收数据事件
public event SerialPortDataReceiveEventArgs DataReceived;
//定义接收错误事件
//public event SerialErrorReceivedEventHandler Error;
//接收事件是否有效 false表示有效
public bool ReceiveEventFlag = false;
#region 获取串口名
private string protName;
public string PortName
{
get { return _serialPort.PortName; }
set
{
_serialPort.PortName = value;
protName = value;
}
}
#endregion
#region 获取比特率
private int baudRate;
public int BaudRate
{
get { return _serialPort.BaudRate; }
set
{
_serialPort.BaudRate = value;
baudRate = value;
}
}
#endregion
#region 默认构造函数
/// <summary>
/// 默认构造函数,操作COM1,速度为9600,没有奇偶校验,8位字节,停止位为1 "COM1", 9600, Parity.None, 8, StopBits.One
/// </summary>
public SerialClass()
{
_serialPort = new SerialPort();
}
#endregion
#region 构造函数
/// <summary>
/// 构造函数,
/// </summary>
/// <param name="comPortName"></param>
public SerialClass(string comPortName)
{
_serialPort = new SerialPort(comPortName);
_serialPort.BaudRate = 9600;
_serialPort.Parity = Parity.Even;
_serialPort.DataBits = 8;
_serialPort.StopBits = StopBits.One;
_serialPort.Handshake = Handshake.None;
_serialPort.RtsEnable = true;
_serialPort.ReadTimeout = 2000;
setSerialPort();
}
#endregion
#region 构造函数,可以自定义串口的初始化参数
/// <summary>
/// 构造函数,可以自定义串口的初始化参数
/// </summary>
/// <param name="comPortName">需要操作的COM口名称</param>
/// <param name="baudRate">COM的速度</param>
/// <param name="parity">奇偶校验位</param>
/// <param name="dataBits">数据长度</param>
/// <param name="stopBits">停止位</param>
public SerialClass(string comPortName, int baudRate, Parity parity, int dataBits, StopBits stopBits)
{
_serialPort = new SerialPort(comPortName, baudRate, parity, dataBits, stopBits);
_serialPort.RtsEnable = true; //自动请求
_serialPort.ReadTimeout = 3000;//超时
setSerialPort();
}
#endregion
#region 析构函数
/// <summary>
/// 析构函数,关闭串口
/// </summary>
~SerialClass()
{
if (_serialPort.IsOpen)
_serialPort.Close();
}
#endregion
#region 设置串口参数
/// <summary>
/// 设置串口参数
/// </summary>
/// <param name="comPortName">需要操作的COM口名称</param>
/// <param name="baudRate">COM的速度</param>
/// <param name="dataBits">数据长度</param>
/// <param name="stopBits">停止位</param>
public void setSerialPort(string comPortName, int baudRate, int dataBits, int stopBits )
{
if (_serialPort.IsOpen)
_serialPort.Close();
_serialPort.PortName = comPortName;
_serialPort.BaudRate = baudRate;
_serialPort.Parity = Parity.None;
_serialPort.DataBits = dataBits;
_serialPort.StopBits = (StopBits)stopBits;
_serialPort.Handshake = Handshake.None;
_serialPort.RtsEnable = false;
_serialPort.ReadTimeout = 3000;
_serialPort.NewLine = "/r/n";
setSerialPort();
}
#endregion
#region 设置接收函数
/// <summary>
/// 设置串口资源,还需重载多个设置串口的函数
/// </summary>
void setSerialPort()
{
if (_serialPort != null)
{
//设置触发DataReceived事件的字节数为1
_serialPort.ReceivedBytesThreshold = 1;
//接收到一个字节时,也会触发DataReceived事件
_serialPort.DataReceived += new SerialDataReceivedEventHandler(_serialPort_DataReceived);
//接收数据出错,触发事件
_serialPort.ErrorReceived += new SerialErrorReceivedEventHandler(_serialPort_ErrorReceived);
//打开串口
//openPort();
}
}
#endregion
#region 打开串口资源
/// <summary>
/// 打开串口资源
/// <returns>返回bool类型</returns>
/// </summary>
public bool openPort()
{
bool ok = false;
//如果串口是打开的,先关闭
if (_serialPort.IsOpen)
_serialPort.Close();
try
{
//打开串口
_serialPort.Open();
ok = true;
}
catch (Exception Ex)
{
throw Ex;
}
return ok;
}
#endregion
#region 关闭串口
/// <summary>
/// 关闭串口资源,操作完成后,一定要关闭串口
/// </summary>
public void closePort()
{
//如果串口处于打开状态,则关闭
if (_serialPort.IsOpen)
_serialPort.Close();
}
#endregion
#region 接收串口数据事件
/// <summary>
/// 接收串口数据事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void _serialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
//禁止接收事件时直接退出
if (ReceiveEventFlag)
{
return;
}
try
{
System.Threading.Thread.Sleep(20);
byte[] _data = new byte[_serialPort.BytesToRead];
_serialPort.Read(_data, 0, _data.Length);
if (_data.Length == 0) { return; }
if (DataReceived != null)
{
DataReceived(sender, e, _data);
}
//_serialPort.DiscardInBuffer(); //清空接收缓冲区
}
catch (Exception ex)
{
throw ex;
}
}
#endregion
#region 接收数据出错事件
/// <summary>
/// 接收数据出错事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void _serialPort_ErrorReceived(object sender, SerialErrorReceivedEventArgs e)
{
}
#endregion
#region 发送数据string类型
public void SendData(string data)
{
//发送数据
//禁止接收事件时直接退出
if (ReceiveEventFlag)
{
return;
}
if (_serialPort.IsOpen)
{
_serialPort.Write(data);
}
}
#endregion
#region 发送数据byte类型
/// <summary>
/// 数据发送
/// </summary>
/// <param name="data">要发送的数据字节</param>
public void SendData(byte[] data, int offset, int count)
{
//禁止接收事件时直接退出
if (ReceiveEventFlag)
{
return;
}
try
{
if (_serialPort.IsOpen)
{
//_serialPort.DiscardInBuffer();//清空接收缓冲区
_serialPort.Write(data, offset, count);
}
}
catch (Exception ex)
{
throw ex;
}
}
#endregion
#region 发送命令
/// <summary>
/// 发送命令
/// </summary>
/// <param name="SendData">发送数据</param>
/// <param name="ReceiveData">接收数据</param>
/// <param name="Overtime">超时时间</param>
/// <returns></returns>
public int SendCommand(byte[] SendData, ref byte[] ReceiveData, int Overtime)
{
if (_serialPort.IsOpen)
{
try
{
ReceiveEventFlag = true; //关闭接收事件
_serialPort.DiscardInBuffer(); //清空接收缓冲区
_serialPort.Write(SendData, 0, SendData.Length);
int num = 0, ret = 0;
System.Threading.Thread.Sleep(10);
ReceiveEventFlag = false; //打开事件
while (num++ < Overtime)
{
if (_serialPort.BytesToRead >= ReceiveData.Length)
break;
System.Threading.Thread.Sleep(10);
}
if (_serialPort.BytesToRead >= ReceiveData.Length)
{
ret = _serialPort.Read(ReceiveData, 0, ReceiveData.Length);
}
else
{
ret = _serialPort.Read(ReceiveData, 0, _serialPort.BytesToRead);
}
ReceiveEventFlag = false; //打开事件
return ret;
}
catch (Exception ex)
{
ReceiveEventFlag = false;
throw ex;
}
}
return -1;
}
#endregion
#region 获取串口
/// <summary>
/// 获取所有已连接短信猫设备的串口
/// </summary>
/// <returns></returns>
public string[] serialsIsConnected()
{
List<string> lists = new List<string>();
string[] seriallist = getSerials();
foreach (string s in seriallist)
{
}
return lists.ToArray();
}
#endregion
#region 获取当前全部串口资源
/// <summary>
/// 获得当前电脑上的所有串口资源
/// </summary>
/// <returns></returns>
public string[] getSerials()
{
return SerialPort.GetPortNames();
}
#endregion
#region 字节型转换16
/// <summary>
/// 把字节型转换成十六进制字符串
/// </summary>
/// <param name="InBytes"></param>
/// <returns></returns>
public static string ByteToString(byte[] InBytes)
{
string StringOut = "";
foreach (byte InByte in InBytes)
{
StringOut = StringOut + String.Format("{0:X2} ", InByte);
}
return StringOut;
}
#endregion
#region 十六进制字符串转字节型
/// <summary>
/// 把十六进制字符串转换成字节型(方法1)
/// </summary>
/// <param name="InString"></param>
/// <returns></returns>
public static byte[] StringToByte(string InString)
{
string[] ByteStrings;
ByteStrings = InString.Split(" ".ToCharArray());
byte[] ByteOut;
ByteOut = new byte[ByteStrings.Length];
for (int i = 0; i <= ByteStrings.Length-1 ; i++)
{
//ByteOut[i] = System.Text.Encoding.ASCII.GetBytes(ByteStrings[i]);
ByteOut[i] = Byte.Parse(ByteStrings[i], System.Globalization.NumberStyles.HexNumber);
//ByteOut[i] =Convert.ToByte("0x" + ByteStrings[i]);
}
return ByteOut;
}
#endregion
#region 十六进制字符串转字节型
/// <summary>
/// 字符串转16进制字节数组(方法2)
/// </summary>
/// <param name="hexString"></param>
/// <returns></returns>
public static byte[] strToToHexByte(string hexString)
{
hexString = hexString.Replace(" ", "");
if ((hexString.Length % 2) != 0)
hexString += " ";
byte[] returnBytes = new byte[hexString.Length / 2];
for (int i = 0; i < returnBytes.Length; i++)
returnBytes[i] = Convert.ToByte(hexString.Substring(i * 2, 2), 16);
return returnBytes;
}
#endregion
#region 字节型转十六进制字符串
/// <summary>
/// 字节数组转16进制字符串
/// </summary>
/// <param name="bytes"></param>
/// <returns></returns>
public static string byteToHexStr(byte[] bytes)
{
string returnStr = "";
if (bytes != null)
{
for (int i = 0; i < bytes.Length; i++)
{
returnStr += bytes[i].ToString("X2");
}
}
return returnStr;
}
#endregion
}
}
======================================================================================
调用方法:
static SerialClass sc = new SerialClass();
static void Main(string[] Args)
{
sc.DataReceived += new SerialClass.SerialPortDataReceiveEventArgs(sc_DataReceived);
sc.writeData("at");
Console.ReadLine();
sc.closePort();
}
static void sc_DataReceived(object sender, SerialDataReceivedEventArgs e, byte[] bits)
{
Console.WriteLine(Encoding.Default.GetString(bits));
}
C#串口操作类,包括串口读写操作的更多相关文章
- 【知识必备】ezSQL,最好用的数据库操作类,让php操作sql更简单~
最近用php做了点小东东,用上了ezSQL,感觉真的很ez,所以拿来跟大家分享一下~ ezSQL是一个非常好用的PHP数据库操作类.著名的开源博客WordPress的数据库操作就使用了ezSQL的My ...
- Util应用程序框架公共操作类(五):异常公共操作类
任何系统都需要处理错误,本文介绍的异常公共操作类,用于对业务上的错误进行简单支持. 对于刚刚接触.Net的新手,碰到错误的时候,一般喜欢通过返回bool值的方式指示是否执行成功. public boo ...
- Util应用程序框架公共操作类(四):验证公共操作类
为了能够验证领域实体,需要一个验证公共操作类来提供支持.由于我将使用企业库(Enterprise Library)的验证组件来完成这项任务,所以本文也将演示对第三方框架的封装要点. .Net提供了一个 ...
- HDFS API 操作实例(一) HDFS读写操作
1. 读取HDFS文件 1.1 字符读取HDFS上的文件 Configuration conf = new Configuration(); Path path = new Path(pathstr) ...
- Java中Cookie常用操作类(Spring中操作Cookie)
说明:Cookie下用Key取值没有快速的方法,只能便利循环去取. 技巧:置0则cookie会立即删除,设置-1,负值则会在关闭浏览器后删除.切记一定要增加路径:setPath("/&quo ...
- js moment.js日期操作类 datetime,日期操作,dayjs
http://momentjs.com/ JS时间处理插件MomentJS https://juejin.im/post/5a2bdc55f265da432b4abf5e Day.js 2kB超轻量时 ...
- socket 实现单一串口共享读写操作
前提:物理串口连接到PC上,通过串口号被PC唯一识别. 此时,物理串口通过该串口号仅能被单一线程或进程实例并占用,其他线程或进程不能再通过该串口号与物理串口通信.这个暂称为串口独占性. 解决思路:核心 ...
- C#注册表读写完整操作类
1.注册表基项静态域 /// <summary> /// 注册表基项静态域 ///1.Registry.ClassesRoot 对应于HKEY_CLASSES_ROOT 主键 ///2.R ...
- Python---面向对象编程---自定义列表和集合操作类
一.定义一个列表的操作类Listinfo 包括的方法 1.列表元素添加:add_key() 添加的必须是数字或者是字符串 2.列表元素取值:get_key() 3.列表合并:update_list( ...
- Android打造属于自己的数据库操作类。
1.概述 开发Android的同学都知道sdk已经为我们提供了一个SQLiteOpenHelper类来创建和管理SQLite数据库,通过写一个子类去继承它,就可以方便的创建.管理数据库.但是当我们需要 ...
随机推荐
- jmeter随笔(5)--断言中正则表达式的特殊字符问题和中文乱码显示问号的问题
最近在工作中,对jmeter实践的点滴的记录,这里分享交流,不一定正确,仅供参考和讨论,有想法的欢迎留言.谈论,手机上图片如果不清晰,请点击[阅读原文]查看. 问题:今天QQ群一朋友遇到jmeter的 ...
- C/c++笔试经典程序(一)
1.输出结果比较 1) 输出结果:21 2) 输出结果:12.虽然循环只进行了一次,但是对!X++来说,X还是进行了自加运算. 2.指针运算 输出结果8,8.程序运行时,printf语句是从右往左进行 ...
- Android开发-API指南-<instrumentation >
<instrumentation> 英文原文:http://developer.android.com/guide/topics/manifest/instrumentation-elem ...
- 如何制作prezi swf格式字体(prezi 中文字体)
如何制作prezi swf格式字体(prezi 中文字体) 文/玄魂 前言 Prezi软件虽然没有正式进入中国,但是中国的Prezi爱好者却在不遗余力的推广着Prezi.我接触这款软件比较晚,但是从接 ...
- linux中ll和du的区别
首先,明确一个概念,linux中目录其实也是一个文件,它存储了一张表,该表就是该目录文件下,所有文件名和inode的映射关系. 其中inode和数据块block的关系http://c.bianchen ...
- ossim系统原理与实践
本文出自 "李晨光原创技术博客" 博客,请务必保留此出处http://chenguang.blog.51cto.com/350944/1353300
- 【HTML/XML 9】XML中的DTD文件
导读:DTD是Document type definition(文档类型定义的缩写),是一套关于标记符的语法规则,它是XML文件的验证机制,数以XML文件的组成部分.XML文档是一种描述标记语言的语言 ...
- VC++2010下编译STLport,Boost
VC++2010下编译STLport,Boost 最近在想向Boost转移,努力掌握Boost代码的过程中, STLport版本:5.2.1 Boost版本:1.4.6.1 (1.4.7.0也OK) ...
- 前端工程筹建NodeJs+gulp+bower
1.安装nodejs nodejs 官网下载安装文件 安装完成之后,在命令窗口执行,(显示nodejs版本) 和(显示npm版本)可以使用这两个命令查看是否安装成功: node -v npm -v 2 ...
- 对于返回void类型的asyc的异步方法,如何修改,能使用await
下面是使用WebClinet 获取百度首页的html代码,一般的写法如下: private void Button_Click(object sender, RoutedEventArgs e) { ...