C# 用API操作读写串口.docx
《C# 用API操作读写串口.docx》由会员分享,可在线阅读,更多相关《C# 用API操作读写串口.docx(14页珍藏版)》请在冰豆网上搜索。
C#用API操作读写串口
usingSystem;
usingSystem.Runtime.InteropServices;
usingSystem.Threading;
usingSystem.Windows.Forms;
namespaceDataGate//
{
publicclassComBase
{
publicComBase(stringPortNum,intBaudRate,byteByteSize,byteParity,byteStopBits,intReadTimeout)
{
this.PortNum=PortNum;
this.BaudRate=BaudRate;
this.ByteSize=ByteSize;
this.Parity=Parity;
this.StopBits=StopBits;
this.ReadTimeout=ReadTimeout;
this.Opened=false;
this.m_ovWrite.hEvent=CreateEvent(0,true,false,0);
this.m_ovWrite.Internal=0;
this.m_ovWrite.InternalHigh=0;
this.m_ovWrite.Offset=0;
this.m_ovWrite.OffsetHigh=0;
this.m_ovRead.hEvent=CreateEvent(0,true,false,0);
this.m_ovRead.Internal=0;
this.m_ovRead.InternalHigh=0;
this.m_ovRead.Offset=0;
this.m_ovRead.OffsetHigh=0;
}
publicstringPortNum;//COM1COM2COM3COM4
publicintBaudRate;//1200,2400,4800,9600
publicbyteByteSize;//8bits
publicbyteParity;//0-4=no,odd,even,mark,space
publicbyteStopBits;//0,1,2=1,1.5,2
publicintReadTimeout;//10
//commportwin32filehandle
privateinthComm=-1;
publicboolOpened=false;
OVERLAPPEDm_ovWrite=newOVERLAPPED();
OVERLAPPEDm_ovRead=newOVERLAPPED();
//win32apiconstants
privateconstuintGENERIC_READ=0x80000000;
privateconstuintGENERIC_WRITE=0x40000000;
privateconstintOPEN_EXISTING=3;
privateconstintINVALID_HANDLE_VALUE=-1;
[StructLayout(LayoutKind.Sequential)]
/*
privatestructDCB貌似设置有错误位域没设置对
{
//takenfromcstructinplatformsdk
publicintDCBlength;//sizeof(DCB)
publicintBaudRate;//currentbaudrate
publicintfBinary;//binarymode,noEOFcheck
publicintfParity;//enableparitychecking
publicintfOutxCtsFlow;//CTSoutputflowcontrol
publicintfOutxDsrFlow;//DSRoutputflowcontrol
publicintfDtrControl;//DTRflowcontroltype
publicintfDsrSensitivity;//DSRsensitivity
publicintfTXContinueOnXoff;//XOFFcontinuesTx
publicintfOutX;//XON/XOFFoutflowcontrol
publicintfInX;//XON/XOFFinflowcontrol
publicintfErrorChar;//enableerrorreplacement
publicintfNull;//enablenullstripping
publicintfRtsControl;//RTSflowcontrol
publicintfAbortOnError;//abortonerror
publicintfDummy2;//reserved
publicushortwReserved;//notcurrentlyused
publicushortXonLim;//transmitXONthreshold
publicushortXoffLim;//transmitXOFFthreshold
publicbyteByteSize;//numberofbits/byte,4-8
publicbyteParity;//0-4=no,odd,even,mark,space
publicbyteStopBits;//0,1,2=1,1.5,2
publiccharXonChar;//TxandRxXONcharacter
publiccharXoffChar;//TxandRxXOFFcharacter
publiccharErrorChar;//errorreplacementcharacter
publiccharEofChar;//endofinputcharacter
publiccharEvtChar;//receivedeventcharacter
publicushortwReserved1;//reserved;donotuse
}
*/
privatestructDCB
{
//takenfromcstructinplatformsdk
publicintDCBlength;//sizeof(DCB)
publicintBaudRate;//currentbaudrate
publicintxData;//x值一个32位
publicushortwReserved;//notcurrentlyused
publicushortXonLim;//transmitXONthreshold
publicushortXoffLim;//transmitXOFFthreshold
publicbyteByteSize;//numberofbits/byte,4-8
publicbyteParity;//0-4=no,odd,even,mark,space
publicbyteStopBits;//0,1,2=1,1.5,2
publiccharXonChar;//TxandRxXONcharacter
publiccharXoffChar;//TxandRxXOFFcharacter
publiccharErrorChar;//errorreplacementcharacter
publiccharEofChar;//endofinputcharacter
publiccharEvtChar;//receivedeventcharacter
publicushortwReserved1;//reserved;donotuse
}
[StructLayout(LayoutKind.Sequential)]
privatestructCOMMTIMEOUTS
{
publicintReadIntervalTimeout;
publicintReadTotalTimeoutMultiplier;
publicintReadTotalTimeoutConstant;
publicintWriteTotalTimeoutMultiplier;
publicintWriteTotalTimeoutConstant;
}
[StructLayout(LayoutKind.Sequential)]
privatestructOVERLAPPED
{
publicintInternal;
publicintInternalHigh;
publicintOffset;
publicintOffsetHigh;
publicinthEvent;
}
[DllImport("kernel32.dll")]
privatestaticexternintCreateFile(
stringlpFileName,//filename
uintdwDesiredAccess,//accessmode
intdwShareMode,//sharemode
intlpSecurityAttributes,//SD
intdwCreationDisposition,//howtocreate
intdwFlagsAndAttributes,//fileattributes
inthTemplateFile//handletotemplatefile
);
[DllImport("kernel32.dll")]
privatestaticexternboolGetCommTimeouts(
inthFile,//handletocommdevice
refCOMMTIMEOUTSlpCommTimeouts//time-outvalues
);
[DllImport("kernel32.dll")]
privatestaticexternboolGetCommState(
inthFile,//handletocommunicationsdevice
refDCBlpDCB//device-controlblock
);
[DllImport("kernel32.dll")]
privatestaticexternboolSetCommState(
inthFile,//handletocommunicationsdevice
refDCBlpDCB//device-controlblock
);
[DllImport("kernel32.dll")]
privatestaticexternboolSetCommTimeouts(
inthFile,//handletocommdevice
refCOMMTIMEOUTSlpCommTimeouts//time-outvalues
);
[DllImport("kernel32.dll")]
privatestaticexternboolReadFile(
inthFile,//handletofile
byte[]lpBuffer,//databuffer
intnNumberOfBytesToRead,//numberofbytestoread
refintlpNumberOfBytesRead,//numberofbytesread
refOVERLAPPEDlpOverlapped//overlappedbuffer
);
[DllImport("kernel32.dll")]
privatestaticexternboolWriteFile(
inthFile,//handletofile
byte[]lpBuffer,//databuffer
intnNumberOfBytesToWrite,//numberofbytestowrite
refintlpNumberOfBytesWritten,//numberofbyteswritten
refOVERLAPPEDlpOverlapped//overlappedbuffer
);
[DllImport("kernel32.dll")]
privatestaticexternboolCloseHandle(
inthObject//handletoobject
);
[DllImport("kernel32.dll")]
privatestaticexternintGetLastError(
);
[DllImport("kernel32.dll")]
privatestaticexternintWaitForSingleObject(
inthHandle,
intdwMilliseconds
);
[DllImport("kernel32.dll")]
privatestaticexternboolGetOverlappedResult(
inthFile,//handletofile,pipe,orcommdevice
refOVERLAPPEDlpOverlapped,//pointertooverlappedstructure
refintlpNumberOfBytesTransferred,//pointertoactualbytescount
boolbWait//waitflag
);
[DllImport("kernel32.dll")]
privatestaticexternboolPurgeComm(
inthFile,//handletocommunicationsresource
intdwFlags//actiontoperform
);
[DllImport("kernel32.dll")]
privatestaticexternboolSetupComm(
inthFile,//handletocommunicationsdevice
intdwInQueue,//sizeofinputbuffer
intdwOutQueue//sizeofoutputbuffer
);
[DllImport("kernel32.dll")]
privatestaticexternintCreateEvent(
intlpSECURITY_ATTRIBUTES,//传递个NULL就是0
//pointertosecurityattributes
boolbManualReset,//flagformanual-resetevent
boolbInitialState,//flagforinitialstate
intlpName//pointertoevent-objectname
);
publicvoidOpen()
{
DCBdcbCommPort=newDCB();
COMMTIMEOUTSctoCommPort=newCOMMTIMEOUTS();
//OPENTHECOMMPORT.
intFILE_FLAG_OVERLAPPED=0x40000000;
hComm=CreateFile(PortNum,GENERIC_READ|GENERIC_WRITE,0,0,OPEN_EXISTING,FILE_FLAG_OVERLAPPED,0);
//IFTHEPORTCANNOTBEOPENED,BAILOUT.
if(hComm==INVALID_HANDLE_VALUE)
{
throw(newApplicationException(this.PortNum+"串口打开失败"));
}
//SETBAUDRATE,PARITY,WORDSIZE,ANDSTOPBITS.
//THEREAREOTHERWAYSOFDOINGSETTINGTHESEBUTTHISISTHEEASIEST.
//IFYOUWANTTOLATERADDCODEFOROTHERBAUDRATES,REMEMBER
//THATTHEARGUMENTFORBuildCommDCBMUSTBEAPOINTERTOASTRING.
//ALSONOTETHATBuildCommDCB()DEFAULTSTONOHANDSHAKING.
dcbCommPort.DCBlength=Marshal.SizeOf(dcbCommPort);
GetCommState(hComm,refdcbCommPort);
dcbCommPort.BaudRate=BaudRate;
dcbCommPort.Parity=Parity;
dcbCommPort.ByteSize=ByteSize;
dcbCommPort.StopBits=StopBits;
dcbCommPort.wReserved1=0;
SetCommState(hComm,refdcbCommPort);
boolret=SetupComm(hComm,200,200);//十分重要不然会写进去字节过多发不出去那么多
if(!
ret)
{
MessageBox.Show("设置缓冲区失败");
}
//SETTHECOMMTIMEOUTS.
GetCommTimeouts(hComm,refctoCommPort);
ctoCommPort.ReadIntervalTimeout=10*9600/this.BaudRate+100;//9600:
110
ctoCommPort.ReadTotalTimeoutConstant=ReadTimeout;
ctoCommPort.ReadTotalTimeoutMultiplier=10*9600/this.BaudRate;
ctoCommPort.WriteTotalTimeoutMultiplier=0;
ctoCommPort.WriteTotalTimeoutConstant=2*9600/this.BaudRate;
SetCommTimeouts(hComm,refctoCommPort);
Opened=true;
this.ClearInOut();
}
publicvoidClose()
{
if(hComm!
=INVALID_HANDLE_VALUE)
{
CloseHandle(hComm);
Opened=false;
CloseHandle(m_ovRead.hEvent);
CloseHandle(m_ovWrite.hEvent);
}
}
publicvoidClearInOut()
{
if(this.hComm==INVALID_HANDLE_VALUE)
return;
intPURGE_TXABORT=0x0001;//Killthepending/currentwritestothecommport.
intPURGE_RXABORT=0x0002;//Killthepending/currentreadstothecommport.
intPURGE_TXCLEAR=0x0004;//Killthetransmitqueueifthere.
intPURGE_RXCLEAR=0x0008;//Killthetypeaheadbufferifthere.
PurgeComm(hComm,PURGE_TXABORT|PURGE_RXABORT|PURGE_TXCLEAR|PURGE_RXCLEAR);
}
publicbyte[]Read(intNumBytes)
{
byte[]BufBytes;
byte[]OutBytes=null;
BufBytes=newbyte[NumBytes];
intERROR_IO_PENDING=997;
if(hComm!
=INVALID_HANDLE_VALUE)
{
intBytesRead=0;
boolbOK=ReadFile(hComm,BufBytes,NumBytes,refBytesRead,refm_ovRead);
if(bOK==true)
{
OutBytes=newbyte[BytesRead];
Array.Copy(BufBytes,OutBytes,BytesRead);
}
else
{