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数据库,通过写一个子类去继承它,就可以方便的创建.管理数据库.但是当我们需要 ...
随机推荐
- 解决Cannot find or open the PDB file问题
今天使用opencv里的mat想要保存数据里边的像素的平均值和标准差: 但是编程好了之后会出现下面的问题,不能找到pdb file .下面将提供三种解决方法以及产生问题的原因. 程序也运行不出来,整个 ...
- 一名合格QA的基本素养
测试不是无脑的重复劳动.测试与开发一样,先用脑,再动手. 拒绝搬砖,关注技术: 把握需求,极致体验: 把控进度,高效沟通: 测试技术 如果你只会加班,行万里路,也只是个邮差 将程序测"好 ...
- git克隆项目到一个非空目录
这只是记录: 1. 进入非空目录,假设是 /workdir/proj1 2. git clone --no-checkout https://git.oschina.net/NextApp/platf ...
- Web前端面试常识
大四校招即将席卷而来,现在临时抱抱佛脚,百度一下大概可能会问到的知识点,愿与君共勉吧! 1.Doctype(html4) A.strict 严格版本 B.transitional 过渡版本(防止 ...
- TCP/IP详解学习笔记(15)-- TCP的流量控制和拥塞控制
TCP的流量控制 1.概述 所谓的流量控制就是让发送方的发送速率不要太快,让接收方来得及接受.利用滑动窗口机制可以很方便的在TCP连接上实现对发送方的流量控制.TCP的窗口单位是字节,不是报 ...
- jquery获取对象
1.JQuery的核心的一些方法 $("Element").length; ‘元素的个数,是个属性 $("Element").size(); ’也是元素的个数, ...
- ASP.NET 数据库页面访问简单工具
在工作中,有很多项目已上线后,很多项目的数据库服务器都不会对外开放的,外网想直接访问客户数据库服务器时,可能会出现困难. 这时就需要一个可以查询,更新数据库操作的页面了: 本来用sql语句直接操作数据 ...
- win7突然无法启动(以前可以启动的,电脑是ubuntu+win7双系统)
这里 有个解决办法是将win7的menuentry里的chainloader +1改为ntldr /bootmgr,但是这个解决办法是基于把Boot Loader指定在/dev/sda1里了,即win ...
- js的数组申明
//数组的3种申明方法,如下example //数组是一种object类型 通过typeof 来检查 //example 1 var arr= new Array("h",&quo ...
- PowerDesigner生成Oracle数据字典
PowerDesigner版本信息 1.File-->NewModel... 2.选择模型 New Model Model types-->Physical Data Model --&g ...