using system;
using system.runtime.interopservices;
namespace nativedll
{
/// <summary>
/// serialport 的摘要说明。
/// </summary>
public class serialport
{
#region 申明要引用的和串口调用有关的api
//win32 api constants
private const uint generic_read = 0x80000000;
private const uint generic_write = 0x40000000;
private const int open_existing = 3;
private const int invalid_handle_value = -1;
private const int maxblock = 4096;
private const uint purge_txabort = 0x0001; // kill the pending/current writes to the comm port.
private const uint purge_rxabort = 0x0002; // kill the pending/current reads to the comm port.
private const uint purge_txclear = 0x0004; // kill the transmit queue if there.
private const uint purge_rxclear = 0x0008; // kill the typeahead buffer if there.
[structlayout(layoutkind.sequential)]
private struct dcb
{
//taken from c struct in platform sdk
public int dcblength; // sizeof(dcb)
public int baudrate; // current baud rate
public int fbinary; // binary mode, no eof check
public int fparity; // enable parity checking
public int foutxctsflow; // cts output flow control
public int foutxdsrflow; // dsr output flow control
public int fdtrcontrol; // dtr flow control type
public int fdsrsensitivity; // dsr sensitivity
public int ftxcontinueonxoff; // xoff continues tx
public int foutx; // xon/xoff out flow control
public int finx; // xon/xoff in flow control
public int ferrorchar; // enable error replacement
public int fnull; // enable null stripping
public int frtscontrol; // rts flow control
public int fabortonerror; // abort on error
public int fdummy2; // reserved
public ushort wreserved; // not currently used
public ushort xonlim; // transmit xon threshold
public ushort xofflim; // transmit xoff threshold
public byte bytesize; // number of bits/byte, 4-8
public byte parity; // 0-4=no,odd,even,mark,space
public byte stopbits; // 0,1,2 = 1, 1.5, 2
public char xonchar; // tx and rx xon character
public char xoffchar; // tx and rx xoff character
public char errorchar; // error replacement character
public char eofchar; // end of input character
public char evtchar; // received event character
public ushort wreserved1; // reserved; do not use
}
[structlayout(layoutkind.sequential)]
private struct commtimeouts
{
public int readintervaltimeout;
public int readtotaltimeoutmultiplier;
public int readtotaltimeoutconstant;
public int writetotaltimeoutmultiplier;
public int writetotaltimeoutconstant;
}
[structlayout(layoutkind.sequential)]
private struct overlapped
{
public int internal;
public int internalhigh;
public int offset;
public int offsethigh;
public int hevent;
}
[structlayout(layoutkind.sequential)]
private struct comstat
{
/*public int fctshold;
public int fdsrhold;
public int frlsdhold;
public int fxoffhold;
public int fxoffsent;
public int feof;
public int ftxim;
public int freserved;
public int cbinque;
public int cboutque;*/
// should have a reverse, i don't know why!!!!!
public int cboutque;
public int cbinque;
public int freserved;
public int ftxim;
public int feof;
public int fxoffsent;
public int fxoffhold;
public int frlsdhold;
public int fdsrhold;
public int fctshold;
}
#if fullframework
[dllimport("kernel32")]
private static extern int createfile(
string lpfilename, // file name
uint dwdesiredaccess, // access mode
int dwsharemode, // share mode
int lpsecurityattributes, // sd
int dwcreationdisposition, // how to create
int dwflagsandattributes, // file attributes
int htemplatefile // handle to template file
);
#else
[dllimport("coredll")]
private static extern int createfile(
string lpfilename, // file name
uint dwdesiredaccess, // access mode
int dwsharemode, // share mode
int lpsecurityattributes, // sd
int dwcreationdisposition, // how to create
int dwflagsandattributes, // file attributes
int htemplatefile // handle to template file
);
#endif
#if fullframework
[dllimport("kernel32")]
private static extern bool getcommstate(
int hfile, // handle to communications device
ref dcb lpdcb // device-control block
);
#else
[dllimport("coredll")]
private static extern bool getcommstate(
int hfile, // handle to communications device
ref dcb lpdcb // device-control block
);
#endif
#if fullframework
[dllimport("kernel32")]
private static extern bool buildcommdcb(
string lpdef, // device-control string
ref dcb lpdcb // device-control block
);
#else
[dllimport("coredll")]
private static extern bool buildcommdcb(
string lpdef, // device-control string
ref dcb lpdcb // device-control block
);
#endif
#if fullframework
[dllimport("kernel32")]
private static extern bool setcommstate(
int hfile, // handle to communications device
ref dcb lpdcb // device-control block
);
#else
[dllimport("coredll")]
private static extern bool setcommstate(
int hfile, // handle to communications device
ref dcb lpdcb // device-control block
);
#endif
#if fullframework
[dllimport("kernel32")]
private static extern bool getcommtimeouts(
int hfile, // handle to comm device
ref commtimeouts lpcommtimeouts // time-out values
);
#else
[dllimport("coredll")]
private static extern bool getcommtimeouts(
int hfile, // handle to comm device
ref commtimeouts lpcommtimeouts // time-out values
);
#endif
#if fullframework
[dllimport("kernel32")]
private static extern bool setcommtimeouts(
int hfile, // handle to comm device
ref commtimeouts lpcommtimeouts // time-out values
);
#else
[dllimport("coredll")]
private static extern bool setcommtimeouts(
int hfile, // handle to comm device
ref commtimeouts lpcommtimeouts // time-out values
);
#endif
#if fullframework
[dllimport("kernel32")]
private static extern bool readfile(
int hfile, // handle to file
byte[] lpbuffer, // data buffer
int nnumberofbytestoread, // number of bytes to read
ref int lpnumberofbytesread, // number of bytes read
ref overlapped lpoverlapped // overlapped buffer
);
#else
[dllimport("coredll")]
private static extern bool readfile(
int hfile, // handle to file
byte[] lpbuffer, // data buffer
int nnumberofbytestoread, // number of bytes to read
ref int lpnumberofbytesread, // number of bytes read
ref overlapped lpoverlapped // overlapped buffer
);
#endif
#if fullframework
[dllimport("kernel32")]
private static extern bool writefile(
int hfile, // handle to file
byte[] lpbuffer, // data buffer
int nnumberofbytestowrite, // number of bytes to write
ref int lpnumberofbyteswritten, // number of bytes written
ref overlapped lpoverlapped // overlapped buffer
);
#else
[dllimport("coredll")]
private static extern bool writefile(
int hfile, // handle to file
byte[] lpbuffer, // data buffer
int nnumberofbytestowrite, // number of bytes to write
ref int lpnumberofbyteswritten, // number of bytes written
ref overlapped lpoverlapped // overlapped buffer
);
#endif
#if fullframework
[dllimport("kernel32")]
private static extern bool closehandle(
int hobject // handle to object
);
#else
[dllimport("coredll")]
private static extern bool closehandle(
int hobject // handle to object
);
#endif
#if fullframework
[dllimport("kernel32")]
private static extern bool clearcommerror(
int hfile, // handle to file
ref int lperrors,
ref comstat lpstat
);
#else
[dllimport("coredll")]
private static extern bool clearcommerror(
int hfile, // handle to file
ref int lperrors,
ref comstat lpstat
);
#endif
#if fullframework
[dllimport("kernel32")]
private static extern bool purgecomm(
int hfile, // handle to file
uint dwflags
);
#else
[dllimport("coredll")]
private static extern bool purgecomm(
int hfile, // handle to file
uint dwflags
);
#endif
#if fullframework
[dllimport("kernel32")]
private static extern bool setupcomm(
int hfile,
int dwinqueue,
int dwoutqueue
);
#else
[dllimport("coredll")]
private static extern bool setupcomm(
int hfile,
int dwinqueue,
int dwoutqueue
);
#endif
#endregion
// serialport的成员变量
private int hcomm = invalid_handle_value;
private bool bopened = false;
public bool opened
{
get
{
return bopened;
}
}
/// <summary>
///串口的初始化函数
///lpfilename 端口名
///baudrate 波特率
///parity 校验位
///bytesize 数据位
///stopbits 停止位
/// <summary>
public bool openport(string lpfilename,int baudrate,byte parity, byte bytesize, byte stopbits)
{
// open the comm port.
hcomm = createfile(lpfilename ,generic_read | generic_write, 0, 0, open_existing, 0, 0);
// if the port cannot be opened, bail out.
if(hcomm == invalid_handle_value)
{
return false;
}
setupcomm(hcomm, maxblock, maxblock);
// set the comm timeouts.
commtimeouts ctocommport = new commtimeouts();
getcommtimeouts(hcomm,ref ctocommport);
ctocommport.readintervaltimeout = int32.maxvalue;
ctocommport.readtotaltimeoutconstant = 0;
ctocommport.readtotaltimeoutmultiplier = 0;
ctocommport.writetotaltimeoutmultiplier = 10;
ctocommport.writetotaltimeoutconstant = 1000;
setcommtimeouts(hcomm,ref ctocommport);
// set baud rate, parity, word size, and stop bits.
// there are other ways of doing setting these but this is the easiest.
// if you want to later add code for other baud rates, remember
// that the argument for buildcommdcb must be a pointer to a string.
// also note that buildcommdcb() defaults to no handshaking.
dcb dcbcommport = new dcb();
dcbcommport.dcblength = marshal.sizeof(dcbcommport);
getcommstate(hcomm, ref dcbcommport);
dcbcommport.baudrate = baudrate;
dcbcommport.parity = parity;
dcbcommport.bytesize = bytesize;
dcbcommport.stopbits = stopbits;
setcommstate(hcomm, ref dcbcommport);
purgecomm(hcomm, purge_rxclear | purge_rxabort);
purgecomm(hcomm, purge_txclear | purge_txabort);
bopened = true;
return true;
}
// 关闭串口
public bool closeport()
{
if (hcomm == invalid_handle_value)
{
return false;
}
if (closehandle(hcomm))
{
hcomm = invalid_handle_value;
bopened = false;
return true;
}
else
{
return false;
}
}
// 往串口写数据
public bool writeport(byte[] writebytes)
{
if (hcomm == invalid_handle_value)
{
return false;
}
comstat comstat = new comstat();
int dwerrorflags = 0;
clearcommerror(hcomm, ref dwerrorflags, ref comstat);
if (dwerrorflags != 0)
purgecomm(hcomm, purge_txclear | purge_txabort);
overlapped ovlcommport = new overlapped();
int byteswritten = 0;
return writefile(hcomm, writebytes, writebytes.length, ref byteswritten, ref ovlcommport);
}
// 从串口读数据
public bool readport(int numbytes, ref byte[] commread)
{
if (hcomm == invalid_handle_value)
{
return false;
}
comstat comstat = new comstat();
int dwerrorflags = 0;
clearcommerror(hcomm, ref dwerrorflags, ref comstat);
if (dwerrorflags != 0)
purgecomm(hcomm, purge_rxclear | purge_rxabort);
if (comstat.cbinque > 0)
{
overlapped ovlcommport = new overlapped();
int bytesread = 0;
return readfile(hcomm, commread, numbytes, ref bytesread, ref ovlcommport);
}
else
{
return false;
}
}
}
}
本文来源于网页设计爱好者web开发社区http://www.html.org.cn收集整理,欢迎访问。