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

}

}