C#异步数据接收串口操作类

使用C#调用传统32位API实现串口操作,整个结构特别的简单。接收数据只需要定义数据接收事件即可。

上传源代码我不会,需要源代码的请与我( [email protected] )联系。你也可以教我怎么上传源代码。

using System;
using System.Runtime.InteropServices;

///

 1<summary>   
 2/// (C)2003-2005 C2217 Studio 保留所有权利   
 3///   
 4/// 文件名称: IbmsSerialPort.cs   
 5/// 文件ID:   
 6/// 文件说明:   
 7/// 封装动态链接库IbmsSerialPort.dll的功能,提供在.NET环境中   
 8/// 串口异步接收和发送数据的功能。   
 9///   
10/// 当前版本: 1.0   
11///   
12/// 作者: 邓杨均   
13/// 创建日期: 2005-2-2   
14/// 最后修改日期: 2005-2-2   
15///   
16/// 历史修改记录:   
17///   
18/// </summary>

namespace Ibms.Tool.IO
{

///

1<summary>   
2/// 当串口接收到数据时,会产生一个事件。   
3/// SPRecvDataArgs就是该事件的参数,参数中的RecvData包含接收到的数据。   
4/// 使用方法:   
5/// </summary>

public class SPRecvDataArgs:EventArgs
{
///

1<summary>   
2/// 接收到的数据组成的字节数组   
3/// </summary>

private byte[] recvData;

///

1<summary>   
2/// 构造函数,需要一个包含数据的byte[]作为初始化参数来实例化 SPRecvDataArgs   
3/// </summary>

///

1<param name="recvData"/>

接收到的数据
public SPRecvDataArgs(byte[] recvData)
{
if( recvData == null)
{
throw(new ArgumentNullException());
}

this.recvData = recvData;
}

///

1<summary>   
2/// 返回接收到的数据内容   
3/// </summary>

public byte[] RecvData
{
get
{
return recvData;
}
}
}

///

1<summary>   
2/// 封装动态链接库IbmsSerialPort.dll的功能,提供在.NET环境中异步   
3/// 串口接收和发送功能。特别实现的是异步通过信号自动接收数据的模式。   
4/// </summary>

public class IbmsSerialPort:IDisposable
{

#region 平台调用声明代码

///

1<summary>   
2/// 声明IbmsSerialPort.dll的Ibms_OpenPort函数   
3/// </summary>

///

1<param name="nPort"/>

串口号
///

1<param name="nRate"/>

波特率
///

1<returns></returns>

[DllImport("IbmsSerialPort.dll")]
public static extern IntPtr Ibms_OpenPort(int nPort, int nRate);

///

1<summary>   
2/// 声明IbmsSerialPort.dll的Ibms_Close函数   
3/// </summary>

[DllImport("IbmsSerialPort.dll")]
public static extern void Ibms_Close( IntPtr port);

///

1<summary>   
2/// 声明IbmsSerialPort.dll的Ibms_SendData函数   
3/// </summary>

///

1<param name="data"/>

///

1<param name="nDataSize"/>

///

1<returns></returns>

[DllImport("IbmsSerialPort.dll")]
public static extern bool Ibms_SendData( IntPtr port, byte[] data,int nDataSize);

///

1<summary>   
2/// 声明IbmsSerialPort.dll的Ibms_SetFuncHandle函数   
3/// </summary>

///

1<param name="handDataFunc"/>

[DllImport("IbmsSerialPort.dll")]
public static extern void Ibms_SetFuncHandle( IntPtr port, HandleFunc handDataFunc);

#endregion

#region 定义字段

///

1<summary>   
2/// 定义数据处理委托,作为API的函数指针传入动态链接库   
3/// </summary>

public delegate void HandleFunc(IntPtr pData, int nDataSize);

///

1<summary>   
2/// 定义数据接收事件的原型   
3/// </summary>

public delegate void RecvData(object sender,SPRecvDataArgs e);

///

1<summary>   
2/// 定义数据接收事件   
3/// </summary>

public event RecvData OnRecvData;

///

1<summary>   
2/// 串口处理接收数据的委托   
3/// </summary>

private HandleFunc _handleDataFunc;

///

1<summary>   
2/// 串口的编号,从1开始的整数,最大255   
3/// </summary>

private int port;

///

1<summary>   
2/// 串口所支持的波特率,必须是标准波特率之一   
3/// </summary>

private StanderdRate rate;

///

1<summary>   
2/// 串口当前的打开状态   
3/// </summary>

private bool openStatus=false;

///

1<summary>   
2/// 串口句柄   
3/// </summary>

private IntPtr portHandle;

#region 定义标准的串口波特率

///

1<summary>   
2/// 标准的波特率   
3/// </summary>

public enum StanderdRate
{
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 定义方法

///

1<summary>   
2/// 构造函数   
3/// </summary>

public IbmsSerialPort()
{
portHandle = (IntPtr)0;

_handleDataFunc = new HandleFunc(OnDllRecvData);
}

///

1<summary>   
2/// 打开串口   
3/// </summary>

///

1<param name="nPort"/>

串口号
///

1<param name="nRate"/>

波特率
/// ///

1<exception cref="ApplicationException">抛出应用程序异常,包换错误描述</exception>

public void Open(int nPort, StanderdRate nRate)
{

if(nPort > 255 || nPort < 0)
{
throw(new ArgumentOutOfRangeException());
}

port = nPort;
rate = nRate;

portHandle = Ibms_OpenPort( port, (int)rate );

if( (IntPtr)0 == portHandle )
{
throw( new ApplicationException("打开串口失败"));
}

//注册函数指针
Ibms_SetFuncHandle( portHandle, _handleDataFunc );

openStatus = true;

}

///

1<summary>   
2/// 关闭串口   
3/// </summary>

public void Close()
{
if( openStatus )
{
Ibms_Close( portHandle);

}

openStatus = false;

}

///

1<summary>   
2/// 发送数据   
3/// </summary>

///

1<param name="sendData"/>

数据内容
///

1<exception cref="ApplicationException">抛出应用程序异常,包换错误描述</exception>

public void SendData( byte[] data )
{
if( !openStatus )
{
throw( new ApplicationException("串口没有打开,发送数据失败") );
}

if( !Ibms_SendData( portHandle, data, data.Length ) )
{
throw( new ApplicationException("串口发送数据失败") );
}
}

///

1<summary>   
2/// 处理接收到的串口数据   
3/// </summary>

///

1<param name="pData"/>

串口数据接收缓冲区首地址
///

1<param name="nDataSize"/>

数据大小,一般数据大小不超过2K
unsafe protected void OnDllRecvData(IntPtr pUnhandleData, int nDataSize)
{
int dataSize= nDataSize ;

byte * pData =(byte *) pUnhandleData;

byte[] data = new byte[dataSize];

//复制数据到byte数组
for(int i=0; i

 1<datasize; #endregion="" #region="" );="" <summary="" data[i]="pData[i];" i++)="" new="" onrecvdata(="" sprecvdataargs(data)="" this,="" {="" }="" 定义属性="" 激发事件="">   
 2/// 返回当前的串口号   
 3///    
 4public int Port   
 5{   
 6get   
 7{   
 8return port;   
 9}   
10} 
11
12/// <summary>   
13/// 返回当前串口的波特率   
14/// </summary>   
15public StanderdRate Rate   
16{   
17get   
18{   
19return rate;   
20}   
21} 
22
23/// <summary>   
24/// 返回当前串口的状态   
25/// </summary>   
26public bool OpenStatus   
27{   
28get   
29{   
30return openStatus;   
31}   
32} 
33
34  
35#endregion   
36
37
38#region 非托管资源的及时释放   
39  
40/// <summary>   
41/// 因为包含了非托管的资源(占用系统串口),必须实现IDisposable接口   
42/// 在使用完该类的时候,必须记得调用Dispose(),回收系统资源   
43/// <example>   
44///   
45/// 方法1   
46/// {   
47/// SerialPort port =new SerialPort();   
48/// ...   
49/// //在try-catch-finaly的finaly中释放资源   
50///   
51/// port.Dispose();   
52/// }   
53///   
54/// 方法2   
55/// using( SerialPort port = new SerialPort())   
56/// {   
57/// ...   
58/// }   
59/// 变量超出作用域时会自动调用其Dispose()方法   
60///   
61/// </example>   
62/// </summary>
63
64~IbmsSerialPort()   
65{   
66Dispose( false );   
67} 
68
69protected virtual void Dispose( bool disposing )   
70{   
71if( disposing )   
72{   
73//清理托管的对象   
74} 
75
76//清理非托管的资源   
77Close();   
78} 
79
80  
81#region IDisposable 成员 
82
83public void Dispose()   
84{   
85// TODO: 添加 SerialPort.Dispose 实现   
86Dispose( true ); 
87
88GC.SuppressFinalize(this);   
89} 
90
91#endregion   
92#endregion 
93
94}   
95  
96}</datasize;>
Published At
Categories with Web编程
Tagged with
comments powered by Disqus