使用c#调用传统32位api实现串口操作,整个结构特别的简单。接收数据只需要定义数据接收事件即可。
上传源代码我不会,需要源代码的请与我([email protected])联系。你也可以教我怎么上传源代码。
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
 }
 
}