C#异步数据接收串口操作类
使用C#调用传统32位API实现串口操作,整个结构特别的简单。接收数据只需要定义数据接收事件即可。
上传源代码我不会,需要源代码的请与我(dyj057@gmail.com)联系。你也可以教我怎么上传源代码。
usingSystem;
usingSystem.Runtime.InteropServices;
///<summary>
///(C)2003-2005C2217Studio保留所有权利
///
///文件名称:IbmsSerialPort.cs
///文件ID:
///文件说明:
///封装动态链接库IbmsSerialPort.dll的功能,提供在.NET环境中
///串口异步接收和发送数据的功能。
///
///当前版本:1.0
///
///作者:邓杨均
///创建日期:2005-2-2
///最后修改日期:2005-2-2
///
///历史修改记录:
///
///</summary>
namespaceIbms.Tool.IO
{
///<summary>
///当串口接收到数据时,会产生一个事件。
///SPRecvDataArgs就是该事件的参数,参数中的RecvData包含接收到的数据。
///使用方法:
///</summary>
publicclassSPRecvDataArgs:EventArgs
{
///<summary>
///接收到的数据组成的字节数组
///</summary>
privatebyte[]recvData;
///<summary>
///构造函数,需要一个包含数据的byte[]作为初始化参数来实例化SPRecvDataArgs
///</summary>
///<paramname="recvData">接收到的数据</param>
publicSPRecvDataArgs(byte[]recvData)
{
if(recvData==null)
{
throw(newArgumentNullException());
}
this.recvData=recvData;
}
///<summary>
///返回接收到的数据内容
///</summary>
publicbyte[]RecvData
{
get
{
returnrecvData;
}
}
}
///<summary>
///封装动态链接库IbmsSerialPort.dll的功能,提供在.NET环境中异步
///串口接收和发送功能。特别实现的是异步通过信号自动接收数据的模式。
///</summary>
publicclassIbmsSerialPort:IDisposable
{
#region平台调用声明代码
///<summary>
///声明IbmsSerialPort.dll的Ibms_OpenPort函数
///</summary>
///<paramname="nPort">串口号</param>
///<paramname="nRate">波特率</param>
///<returns></returns>
[DllImport("IbmsSerialPort.dll")]
publicstaticexternIntPtrIbms_OpenPort(intnPort,intnRate);
///<summary>
///声明IbmsSerialPort.dll的Ibms_Close函数
///</summary>
[DllImport("IbmsSerialPort.dll")]
publicstaticexternvoidIbms_Close(IntPtrport);
///<summary>
///声明IbmsSerialPort.dll的Ibms_SendData函数
///</summary>
///<paramname="data"></param>
///<paramname="nDataSize"></param>
///<returns></returns>
[DllImport("IbmsSerialPort.dll")]
publicstaticexternboolIbms_SendData(IntPtrport,byte[]data,intnDataSize);
///<summary>
///声明IbmsSerialPort.dll的Ibms_SetFuncHandle函数
///</summary>
///<paramname="handDataFunc"></param>
[DllImport("IbmsSerialPort.dll")]
publicstaticexternvoidIbms_SetFuncHandle(IntPtrport,HandleFunchandDataFunc);
#endregion
#region定义字段
///<summary>
///定义数据处理委托,作为API的函数指针传入动态链接库
///</summary>
publicdelegatevoidHandleFunc(IntPtrpData,intnDataSize);
///<summary>
///定义数据接收事件的原型
///</summary>
publicdelegatevoidRecvData(objectsender,SPRecvDataArgse);
///<summary>
///定义数据接收事件
///</summary>
publiceventRecvDataOnRecvData;
///<summary>
///串口处理接收数据的委托
///</summary>
privateHandleFunc_handleDataFunc;
///<summary>
///串口的编号,从1开始的整数,最大255
///</summary>
privateintport;
///<summary>
///串口所支持的波特率,必须是标准波特率之一
///</summary>
privateStanderdRaterate;
///<summary>
///串口当前的打开状态
///</summary>
privateboolopenStatus=false;
///<summary>
///串口句柄
///</summary>
privateIntPtrportHandle;
#region定义标准的串口波特率
///<summary>
///标准的波特率
///</summary>
publicenumStanderdRate
{
R50=50,
R75=75,
R110=110,
R150=150,
R300=300,
R600=600,
R1200=1200,
R2400=2400,
R4800=4800,
R9600=9600,
R19200=19200,
R38400=38400,
R57600=57600,
R76800=76800,
R115200=115200
};
#endregion
#endregion
#region定义方法
///<summary>
///构造函数
///</summary>
publicIbmsSerialPort()
{
portHandle=(IntPtr)0;
_handleDataFunc=newHandleFunc(OnDllRecvData);
}
///<summary>
///打开串口
///</summary>
///<paramname="nPort">串口号</param>
///<paramname="nRate">波特率</param>
//////<exceptioncref="ApplicationException">抛出应用程序异常,包换错误描述</exception>
publicvoidOpen(intnPort,StanderdRatenRate)
{
if(nPort>255||nPort<0)
{
throw(newArgumentOutOfRangeException());
}
port=nPort;
rate=nRate;
portHandle=Ibms_OpenPort(port,(int)rate);
if((IntPtr)0==portHandle)
{
throw(newApplicationException("打开串口失败"));
}
//注册函数指针
Ibms_SetFuncHandle(portHandle,_handleDataFunc);
openStatus=true;
}
///<summary>
///关闭串口
///</summary>
publicvoidClose()
{
if(openStatus)
{
Ibms_Close(portHandle);
}
openStatus=false;
}
///<summary>
///发送数据
///</summary>
///<paramname="sendData">数据内容</param>
///<exceptioncref="ApplicationException">抛出应用程序异常,包换错误描述</exception>
publicvoidSendData(byte[]data)
{
if(!openStatus)
{
throw(newApplicationException("串口没有打开,发送数据失败"));
}
if(!Ibms_SendData(portHandle,data,data.Length))
{
throw(newApplicationException("串口发送数据失败"));
}
}
///<summary>
///处理接收到的串口数据
///</summary>
///<paramname="pData">串口数据接收缓冲区首地址</param>
///<paramname="nDataSize">数据大小,一般数据大小不超过2K</param>
unsafeprotectedvoidOnDllRecvData(IntPtrpUnhandleData,intnDataSize)
{
intdataSize=nDataSize;
byte*pData=(byte*)pUnhandleData;
byte[]data=newbyte[dataSize];
//复制数据到byte数组
for(inti=0;i<dataSize;i++)
{
data[i]=pData[i];
}
//激发事件
OnRecvData(this,newSPRecvDataArgs(data));
}
#endregion
#region定义属性
///<summary>
///返回当前的串口号
///</summary>
publicintPort
{
get
{
returnport;
}
}
///<summary>
///返回当前串口的波特率
///</summary>
publicStanderdRateRate
{
get
{
returnrate;
}
}
///<summary>
///返回当前串口的状态
///</summary>
publicboolOpenStatus
{
get
{
returnopenStatus;
}
}
#endregion
#region非托管资源的及时释放
///<summary>
///因为包含了非托管的资源(占用系统串口),必须实现IDisposable接口
///在使用完该类的时候,必须记得调用Dispose(),回收系统资源
///<example>
///
///方法1
///{
///SerialPortport=newSerialPort();
///...
/////在try-catch-finaly的finaly中释放资源
///
///port.Dispose();
///}
///
///方法2
///using(SerialPortport=newSerialPort())
///{
///...
///}
///变量超出作用域时会自动调用其Dispose()方法
///
///</example>
///</summary>
~IbmsSerialPort()
{
Dispose(false);
}
protectedvirtualvoidDispose(booldisposing)
{
if(disposing)
{
//清理托管的对象
}
//清理非托管的资源
Close();
}
#regionIDisposable成员
publicvoidDispose()
{
//TODO:添加SerialPort.Dispose实现
Dispose(true);
GC.SuppressFinalize(this);
}
#endregion
#endregion
}
}
声明:本站所有文章资源内容,如无特殊说明或标注,均为采集网络资源。如若本站内容侵犯了原著者的合法权益,可联系本站删除。