-
c#串口通讯类
串口通讯类:
usingSystem;
usingSystem.Runtime.InteropServices;
namespaceJustinIO{
classCommPort{
publicstringPortNum;
publicintBaudRate;
publicbyteByteSize;
publicbyteParity;//0-4=no,odd,even,mark,space
publicbyteStopBits;//0,1,2=1,1.5,2
publicintReadTimeout;
//commportwin32filehandle
privateinthComm=-1;
publicboolOpened=false;
//win32apiconstants
privateconstuintGENERIC_READ=0x80000000;
privateconstuintGENERIC_WRITE=0x40000000;
privateconstintOPEN_EXISTING=3;
privateconstintINVALID_HANDLE_VALUE=-1;
[StructLayout(LayoutKind.Sequential)]
publicstructDCB{
//takenfromcstructinplatformsdk
publicintDCBlength; //sizeof(DCB)
publicintBaudRate; //指定当前波特率currentbaudrate
//thesearethecstructbitfields,bittwiddleflagtoset
publicintfBinary; //指定是否允许二进制模式,在windows95中必须主TRUEbinarymode,noEOFcheck
publicintfParity; //指定是否允许奇偶校验enableparitychecking
publicintfOutxCtsFlow; //指定CTS是否用于检测发送控制,当为TRUE是CTS为OFF,发送将被挂起。CTSoutputflowcontrol
publicintfOutxDsrFlow; //指定CTS是否用于检测发送控制DSRoutputflowcontrol
publicintfDtrControl; //DTR_CONTROL_DISABLE值将DTR置为OFF,DTR_CONTROL_ENABLE值将DTR置为ON,DTR_CONTROL_HANDSHAKE允许DTR"握手"DTRflowcontroltype
publicintfDsrSensitivity; //当该值为TRUE时DSR为OFF时接收的字节被忽略DSRsensitivity
publicintfTXContinueOnXoff;//指定当接收缓冲区已满,并且驱动程序已经发送出XoffChar字符时发送是否停止。TRUE时,在接收缓冲区接收到缓冲区已满的字节XoffLim且驱动程序已经发送出XoffChar字符中止接收字节之后,发送继续进行。 FALSE时,在接收缓冲区接收到代表缓冲区已空的字节XonChar且驱动程序已经发送出恢复发送的XonChar之后,发送继续进行。XOFFcontinuesTx
publicintfOutX; //TRUE时,接收到XoffChar之后便停止发送接收到XonChar之后将重新开始XON/XOFFoutflowcontrol
publicintfInX; //TRUE时,接收缓冲区接收到代表缓冲区满的XoffLim之后,XoffChar发送出去接收缓冲区接收到代表缓冲区空的XonLim之后,XonChar发送出去XON/XOFFinflowcontrol
publicintfErrorChar; //该值为TRUE且fParity为TRUE时,用ErrorChar成员指定的字符代替奇偶校验错误的接收字符enableerrorreplacement
publicintfNull; //eTRUE时,接收时去掉空(0值)字节enablenullstripping
publicintfRtsControl; //RTSflowcontrol
/*RTS_CONTROL_DISABLE时,RTS置为OFF
RTS_CONTROL_ENABLE时,RTS置为ON
RTS_CONTROL_HANDSHAKE时,
当接收缓冲区小于半满时RTS为ON
当接收缓冲区超过四分之三满时RTS为OFF
RTS_CONTROL_TOGGLE时,
当接收缓冲区仍有剩余字节时RTS为ON,否则缺省为OFF*/
publicintfAbortOnError; //TRUE时,有错误发生时中止读和写操作abortonerror
publicintfDummy2; //未使用reserved
publicuintflags;
publicushortwReserved; //未使用,必须为0notcurrentlyused
publicushortXonLim; //指定在XON字符发送这前接收缓冲区中可允许的最小字节数transmitXONthreshold
publicushortXoffLim; //指定在XOFF字符发送这前接收缓冲区中可允许的最小字节数transmitXOFFthreshold
publicbyteByteSize; //指定端口当前使用的数据位 numberofbits/byte,4-8
publicbyteParity; //指定端口当前使用的奇偶校验方法,可能为:EVENPARITY,MARKPARITY,NOPARITY,ODDPARITY 0-4=no,odd,even,mark,space
publicbyteStopBits; //指定端口当前使用的停止位数,可能为:ONESTOPBIT,ONE5STOPBITS,TWOSTOPBITS 0,1,2=1,1.5,2
publiccharXonChar; //指定用于发送和接收字符XON的值TxandRxXONcharacter
publiccharXoffChar; //指定用于发送和接收字符XOFF值TxandRxXOFFcharacter
publiccharErrorChar; //本字符用来代替接收到的奇偶校验发生错误时的值errorreplacementcharacter
publiccharEofChar; //当没有使用二进制模式时,本字符可用来指示数据的结束endofinputcharacter
publiccharEvtChar; //当接收到此字符时,会产生一个事件receivedeventcharacter
publicushortwReserved1; //未使用reserved;donotuse
}
[StructLayout(LayoutKind.Sequential)]
privatestructCOMMTIMEOUTS{
publicintReadIntervalTimeout;
publicintReadTotalTimeoutMultiplier;
publicintReadTotalTimeoutConstant;
publicintWriteTotalTimeoutMultiplier;
publicintWriteTotalTimeoutConstant;
}
[StructLayout(LayoutKind.Sequential)]
privatestructOVERLAPPED{
publicint Internal;
publicint InternalHigh;
publicint Offset;
publicint OffsetHigh;
publicinthEvent;
}
[DllImport("kernel32.dll")]
privatestaticexternintCreateFile(
stringlpFileName, //要打开的串口名称
uintdwDesiredAccess, //指定串口的访问方式,一般设置为可读可写方式
intdwShareMode, //指定串口的共享模式,串口不能共享,所以设置为0
intlpSecurityAttributes,//设置串口的安全属性,WIN9X下不支持,应设为NULL
intdwCreationDisposition, //对于串口通信,创建方式只能为OPEN_EXISTING
intdwFlagsAndAttributes, //指定串口属性与标志,设置为FILE_FLAG_OVERLAPPED(重叠I/O操作),指定串口以异步方式通信
inthTemplateFile //对于串口通信必须设置为NULL
);
[DllImport("kernel32.dll")]
privatestaticexternboolGetCommState(
inthFile, //通信设备句柄
refDCBlpDCB //设备控制块DCB
);
[DllImport("kernel32.dll")]
privatestaticexternboolBuildCommDCB(
stringlpDef, //设备控制字符串
refDCBlpDCB //设备控制块
);
[DllImport("kernel32.dll")]
privatestaticexternboolSetCommState(
inthFile, //通信设备句柄
refDCBlpDCB //设备控制块
);
[DllImport("kernel32.dll")]
privatestaticexternboolGetCommTimeouts(
inthFile, //通信设备句柄handletocommdevice
refCOMMTIMEOUTSlpCommTimeouts //超时时间time-outvalues
);
[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")]
privatestaticexternuintGetLastError();
publicvoidOpen()
{
DCBdcbCommPort=newDCB();
COMMTIMEOUTSctoCommPort=newCOMMTIMEOUTS();
//打开串口OPENTHECOMMPORT.
hComm=CreateFile(PortNum,GENERIC_READ|GENERIC_WRITE,0,0,OPEN_EXISTING,0,0);
//如果串口没有打开,就打开IFTHEPORTCANNOTBEOPENED,BAILOUT.
if(hComm==INVALID_HANDLE_VALUE)
{
throw(newApplicationException("非法操作,不能打开串口!"));
}
//设置通信超时时间SETTHECOMMTIMEOUTS.
GetCommTimeouts(hComm,refctoCommPort);
ctoCommPort.ReadTotalTimeoutConstant=ReadTimeout;
ctoCommPort.ReadTotalTimeoutMultiplier=0;
ctoCommPort.WriteTotalTimeoutMultiplier=0;
ctoCommPort.WriteTotalTimeoutConstant=0;
SetCommTimeouts(hComm,refctoCommPort);
//设置串口SETBAUDRATE,PARITY,WORDSIZE,ANDSTOPBITS.
GetCommState(hComm,refdcbCommPort);
dcbCommPort.BaudRate=BaudRate;
dcbCommPort.flags=0;
//dcb.fBinary=1;
dcbCommPort.flags|=1;
if(Parity>0)
{
//dcb.fParity=1
dcbCommPort.flags|=2;
}
dcbCommPort.Parity=Parity;
dcbCommPort.ByteSize=ByteSize;
dcbCommPort.StopBits=StopBits;
if(!SetCommState(hComm,refdcbCommPort))
{
//uintErrorNum=GetLastError();
throw(newApplicationException("非法操作,不能打开串口!"));
}
//unremarktoseeifsettingtookcorrectly
//DCBdcbCommPort2=newDCB();
//GetCommState(hComm,refdcbCommPort2);
Opened=true;
}
publicvoidClose(){
if(hComm!=INVALID_HANDLE_VALUE){
CloseHandle(hComm);
}
}
publicbyte[]Read(intNumBytes){
byte[]BufBytes;
byte[]OutBytes;
BufBytes=newbyte[NumBytes];
if(hComm!=INVALID_HANDLE_VALUE){
OVERLAPPEDovlCommPort=newOVERLAPPED();
intBytesRead=0;
ReadFile(hComm,BufBytes,NumBytes,refBytesRead,refovlCommPort);
OutBytes=newbyte[BytesRead];
Array.Copy(BufBytes,OutBytes,BytesRead);
}
else{
throw(newApplicationException("串口未打开!"));
}
returnOutBytes;
}
publicvoidWrite(byte[]WriteBytes){
if(hComm!=INVALID_HANDLE_VALUE){
OVERLAPPEDovlCommPort=newOVERLAPPED();
intBytesWritten=0;
WriteFile(hComm,WriteBytes,WriteBytes.Length,refBytesWritten,refovlCommPort);
}
else{
throw(newApplicationException("串口未打开!"));
}
}
}
classHexCon{
//把十六进制字符串转换成字节型和把字节型转换成十六进制字符串converterhexstringtobyteandbytetohexstring
publicstaticstringByteToString(byte[]InBytes){
stringStringOut="";
foreach(byteInByteinInBytes){
StringOut=StringOut+String.Format("{0:X2}",InByte);
}
returnStringOut;
}
publicstaticbyte[]StringToByte(stringInString){
string[]ByteStrings;
ByteStrings=InString.Split("".ToCharArray());
byte[]ByteOut;
ByteOut=newbyte[ByteStrings.Length-1];
for(inti=0;i==ByteStrings.Length-1;i++){
ByteOut[i]=Convert.ToByte(("0x"+ByteStrings[i]));
}
returnByteOut;
}
}
}