使用C#调用传统32位API实现串口操作,整个结构特别的简单。接收数据只需要定义数据接收事件即可。
上传源代码我不会,需要源代码的请与我(dyj057@gmail.com)联系。你也可以教我怎么上传源代码。
using System;
using System.Runtime.InteropServices;
/// <summary>
/// (C)2003-2005 C2217 Studio 保留所有权利
///
/// 文件名称: IbmsSerialPort.cs
/// 文件ID:
/// 文件说明:
/// 封装动态链接库IbmsSerialPort.dll的功能,提供在.NET环境中
/// 串口异步接收和发送数据的功能。
///
/// 当前版本: 1.0
///
/// 作者: 邓杨均
/// 创建日期: 2005-2-2
/// 最后修改日期: 2005-2-2
///
/// 历史修改记录:
///
/// </summary>
namespace Ibms.Tool.IO
{
/// <summary>
/// 当串口接收到数据时,会产生一个事件。
/// SPRecvDataArgs就是该事件的参数,参数中的RecvData包含接收到的数据。
/// 使用方法:
/// </summary>
public class SPRecvDataArgs:EventArgs
{
/// <summary>
/// 接收到的数据组成的字节数组
/// </summary>
private byte[] recvData;
/// <summary>
/// 构造函数,需要一个包含数据的byte[]作为初始化参数来实例化 SPRecvDataArgs
/// </summary>
/// <param name="recvData">接收到的数据</param>
public SPRecvDataArgs(byte[] recvData)
{
if( recvData == null)
{
throw(new ArgumentNullException());
}
this.recvData = recvData;
}
/// <summary>
/// 返回接收到的数据内容
/// </summary>
public byte[] RecvData
{
get
{
return recvData;
}
}
}
/// <summary>
/// 封装动态链接库IbmsSerialPort.dll的功能,提供在.NET环境中异步
/// 串口接收和发送功能。特别实现的是异步通过信号自动接收数据的模式。
/// </summary>
public class IbmsSerialPort:IDisposable
{
#region 平台调用声明代码
/// <summary>
/// 声明IbmsSerialPort.dll的Ibms_OpenPort函数
/// </summary>
/// <param name="nPort">串口号</param>
/// <param name="nRate">波特率</param>
/// <returns></returns>
[DllImport("IbmsSerialPort.dll")]
public static extern IntPtr Ibms_OpenPort(int nPort, int nRate);
/// <summary>
/// 声明IbmsSerialPort.dll的Ibms_Close函数
/// </summary>
[DllImport("IbmsSerialPort.dll")]
public static extern void Ibms_Close( IntPtr port);
/// <summary>
/// 声明IbmsSerialPort.dll的Ibms_SendData函数
/// </summary>
/// <param name="data"></param>
/// <param name="nDataSize"></param>
/// <returns></returns>
[DllImport("IbmsSerialPort.dll")]
public static extern bool Ibms_SendData( IntPtr port, byte[] data,int nDataSize);
/// <summary>
/// 声明IbmsSerialPort.dll的Ibms_SetFuncHandle函数
/// </summary>
/// <param name="handDataFunc"></param>
[DllImport("IbmsSerialPort.dll")]
public static extern void Ibms_SetFuncHandle( IntPtr port, HandleFunc handDataFunc);
#endregion
#region 定义字段
/// <summary>
/// 定义数据处理委托,作为API的函数指针传入动态链接库
/// </summary>
public delegate void HandleFunc(IntPtr pData, int nDataSize);
/// <summary>
/// 定义数据接收事件的原型
/// </summary>
public delegate void RecvData(object sender,SPRecvDataArgs e);
/// <summary>
/// 定义数据接收事件
/// </summary>
public event RecvData OnRecvData;
/// <summary>
/// 串口处理接收数据的委托
/// </summary>
private HandleFunc _handleDataFunc;
/// <summary>
/// 串口的编号,从1开始的整数,最大255
/// </summary>
private int port;
/// <summary>
/// 串口所支持的波特率,必须是标准波特率之一
/// </summary>
private StanderdRate rate;
/// <summary>
/// 串口当前的打开状态
/// </summary>
private bool openStatus=false;
/// <summary>
/// 串口句柄
/// </summary>
private IntPtr portHandle;
#region 定义标准的串口波特率
/// <summary>
/// 标准的波特率
/// </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 定义方法
/// <summary>
/// 构造函数
/// </summary>
public IbmsSerialPort()
{
portHandle = (IntPtr)0;
_handleDataFunc = new HandleFunc(OnDllRecvData);
}
/// <summary>
/// 打开串口
/// </summary>
/// <param name="nPort">串口号</param>
/// <param name="nRate">波特率</param>
/// /// <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;
}
/// <summary>
/// 关闭串口
/// </summary>
public void Close()
{
if( openStatus )
{
Ibms_Close( portHandle);
}
openStatus = false;
}
/// <summary>
/// 发送数据
/// </summary>
/// <param name="sendData">数据内容</param>
/// <exception cref="ApplicationException">抛出应用程序异常,包换错误描述</exception>
public void SendData( byte[] data )
{
if( !openStatus )
{
throw( new ApplicationException("串口没有打开,发送数据失败") );
}
if( !Ibms_SendData( portHandle, data, data.Length ) )
{
throw( new ApplicationException("串口发送数据失败") );
}
}
/// <summary>
/// 处理接收到的串口数据
/// </summary>
/// <param name="pData">串口数据接收缓冲区首地址</param>
/// <param name="nDataSize">数据大小,一般数据大小不超过2K</param>
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<dataSize; i++)
{
data[i]= pData[i];
}
//激发事件
OnRecvData( this, new SPRecvDataArgs(data) );
}
#endregion
#region 定义属性
/// <summary>
/// 返回当前的串口号
/// </summary>
public int Port
{
get
{
return port;
}
}
/// <summary>
/// 返回当前串口的波特率
/// </summary>
public StanderdRate Rate
{
get
{
return rate;
}
}
/// <summary>
/// 返回当前串口的状态
/// </summary>
public bool OpenStatus
{
get
{
return openStatus;
}
}
#endregion
#region 非托管资源的及时释放
/// <summary>
/// 因为包含了非托管的资源(占用系统串口),必须实现IDisposable接口
/// 在使用完该类的时候,必须记得调用Dispose(),回收系统资源
/// <example>
///
/// 方法1
/// {
///SerialPort port =new SerialPort();
///...
/////在try-catch-finaly的finaly中释放资源
///
///port.Dispose();
/// }
///
/// 方法2
/// using( SerialPort port = new SerialPort())
/// {
///...
/// }
/// 变量超出作用域时会自动调用其Dispose()方法
///
/// </example>
/// </summary>
~IbmsSerialPort()
{
Dispose( false );
}
protected virtual void Dispose( bool disposing )
{
if( disposing )
{
//清理托管的对象
}
//清理非托管的资源
Close();
}
#region IDisposable 成员
public void Dispose()
{
// TODO: 添加 SerialPort.Dispose 实现
Dispose( true );
GC.SuppressFinalize(this);
}
#endregion
#endregion
}
}
相关推荐
使用C#调用传统32位API实现串口操作,整个结构特别的简单,完整代码,下载即可使用!
包含串口通信(Serial Communications),C#串口编程,SerialPort类的使用,定义3个事件,用来通知数据接收完成、数据发送完成、每次接收数据。支持串口大量数据读写操作,能一次性读取数据,通过设置超时大小控制一...
273 实例190 获取窗口文本 273 实例191 判断文件是否正在被使用 274 实例192 在程序中调用.HLP文件 275 实例193 C#中实现文件拖放 276 实例194 文件比较 276 第7章 操作系统与Windows...
实例103 BackgroundWorker组件执行异步操作 148 3.2 ErrorProvider组件 150 实例104 使用ErrorProvider组件验证文本框输入 150 3.3 EventLog组件 151 实例105 使用EventLog组件读写Windows系统事件日志 151 ...
实例103 BackgroundWorker组件执行异步操作 148 3.2 ErrorProvider组件 150 实例104 使用ErrorProvider组件验证文本框输入 150 3.3 EventLog组件 151 实例105 使用EventLog组件读写Windows系统事件日志 151 ...
实例103 BackgroundWorker组件执行异步操作 148 3.2 ErrorProvider组件 150 实例104 使用ErrorProvider组件验证文本框输入 150 3.3 EventLog组件 151 实例105 使用EventLog组件读写Windows系统事件日志 151 ...
实例103 BackgroundWorker组件执行异步操作 148 3.2 ErrorProvider组件 150 实例104 使用ErrorProvider组件验证文本框输入 150 3.3 EventLog组件 151 实例105 使用EventLog组件读写Windows系统事件日志 151 ...
实现了自绘控件,云端控制主要在CnComm类多线程串口通讯库, camerads-DirectShow使用示例 演示了摄像头的使用 CatListBoxDemo ListBox控件与其它控件阙套使用方法 CCAMS系统是一种用于局域网下的CS模式的软件...