網(wǎng)上的原版串口通訊類:
using System; using System.Runtime.InteropServices; namespace JustinIO { class CommPort { public string PortNum; public int BaudRate; public byte ByteSize; public byte Parity; // 0-4=no,odd,even,mark,space public byte StopBits; // 0,1,2 = 1, 1.5, 2 public int ReadTimeout; //comm port win32 file handle private int hComm = -1; public bool Opened = false; //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; [StructLayout(LayoutKind.Sequential)] public struct DCB { //taken from c struct in platform sdk public int DCBlength; // sizeof(DCB) public int BaudRate; // 指定當(dāng)前波特率 current baud rate // these are the c struct bit fields, bit twiddle flag to set public int fBinary; // 指定是否允許二進(jìn)制模式,在windows95中必須主TRUE binary mode, no EOF check public int fParity; // 指定是否允許奇偶校驗(yàn) enable parity checking public int fOutxCtsFlow; // 指定CTS是否用于檢測發(fā)送控制,,當(dāng)為TRUE是CTS為OFF,發(fā)送將被掛起,。 CTS output flow control public int fOutxDsrFlow; // 指定CTS是否用于檢測發(fā)送控制 DSR output flow control public int fDtrControl; // DTR_CONTROL_DISABLE值將DTR置為OFF, DTR_CONTROL_ENABLE值將DTR置為ON, DTR_CONTROL_HANDSHAKE允許DTR"握手" DTR flow control type public int fDsrSensitivity; // 當(dāng)該值為TRUE時(shí)DSR為OFF時(shí)接收的字節(jié)被忽略 DSR sensitivity public int fTXContinueOnXoff; // 指定當(dāng)接收緩沖區(qū)已滿,并且驅(qū)動(dòng)程序已經(jīng)發(fā)送出XoffChar字符時(shí)發(fā)送是否停止。TRUE時(shí),,在接收緩沖區(qū)接收到緩沖區(qū)已滿的字節(jié)XoffLim且驅(qū)動(dòng)程序已經(jīng)發(fā)送出XoffChar字符中止接收字節(jié)之后,,發(fā)送繼續(xù)進(jìn)行?!ALSE時(shí),,在接收緩沖區(qū)接收到代表緩沖區(qū)已空的字節(jié)XonChar且驅(qū)動(dòng)程序已經(jīng)發(fā)送出恢復(fù)發(fā)送的XonChar之后,發(fā)送繼續(xù)進(jìn)行,。XOFF continues Tx public int fOutX; // TRUE時(shí),,接收到XoffChar之后便停止發(fā)送接收到XonChar之后將重新開始 XON/XOFF out flow control public int fInX; // TRUE時(shí),接收緩沖區(qū)接收到代表緩沖區(qū)滿的XoffLim之后,,XoffChar發(fā)送出去接收緩沖區(qū)接收到代表緩沖區(qū)空的XonLim之后,XonChar發(fā)送出去 XON/XOFF in flow control public int fErrorChar; // 該值為TRUE且fParity為TRUE時(shí),,用ErrorChar 成員指定的字符代替奇偶校驗(yàn)錯(cuò)誤的接收字符 enable error replacement public int fNull; // eTRUE時(shí),,接收時(shí)去掉空(0值)字節(jié) enable null stripping public int fRtsControl; // RTS flow control /*RTS_CONTROL_DISABLE時(shí),RTS置為OFF RTS_CONTROL_ENABLE時(shí), RTS置為ON RTS_CONTROL_HANDSHAKE時(shí), 當(dāng)接收緩沖區(qū)小于半滿時(shí)RTS為ON 當(dāng)接收緩沖區(qū)超過四分之三滿時(shí)RTS為OFF RTS_CONTROL_TOGGLE時(shí), 當(dāng)接收緩沖區(qū)仍有剩余字節(jié)時(shí)RTS為ON ,否則缺省為OFF*/ public int fAbortOnError; // TRUE時(shí),有錯(cuò)誤發(fā)生時(shí)中止讀和寫操作 abort on error public int fDummy2; // 未使用 reserved public uint flags; public ushort wReserved; // 未使用,必須為0 not currently used public ushort XonLim; // 指定在XON字符發(fā)送這前接收緩沖區(qū)中可允許的最小字節(jié)數(shù) transmit XON threshold public ushort XoffLim; // 指定在XOFF字符發(fā)送這前接收緩沖區(qū)中可允許的最小字節(jié)數(shù) transmit XOFF threshold public byte ByteSize; // 指定端口當(dāng)前使用的數(shù)據(jù)位 number of bits/byte, 4-8 public byte Parity; // 指定端口當(dāng)前使用的奇偶校驗(yàn)方法,可能為:EVENPARITY,MARKPARITY,NOPARITY,ODDPARITY 0-4=no,odd,even,mark,space public byte StopBits; // 指定端口當(dāng)前使用的停止位數(shù),可能為:ONESTOPBIT,ONE5STOPBITS,TWOSTOPBITS 0,1,2 = 1, 1.5, 2 public char XonChar; // 指定用于發(fā)送和接收字符XON的值 Tx and Rx XON character public char XoffChar; // 指定用于發(fā)送和接收字符XOFF值 Tx and Rx XOFF character public char ErrorChar; // 本字符用來代替接收到的奇偶校驗(yàn)發(fā)生錯(cuò)誤時(shí)的值 error replacement character public char EofChar; // 當(dāng)沒有使用二進(jìn)制模式時(shí),本字符可用來指示數(shù)據(jù)的結(jié)束 end of input character public char EvtChar; // 當(dāng)接收到此字符時(shí),會產(chǎn)生一個(gè)事件 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; } [DllImport("kernel32.dll")] private static extern int CreateFile( string lpFileName, // 要打開的串口名稱 uint dwDesiredAccess, // 指定串口的訪問方式,一般設(shè)置為可讀可寫方式 int dwShareMode, // 指定串口的共享模式,,串口不能共享,,所以設(shè)置為0 int lpSecurityAttributes, // 設(shè)置串口的安全屬性,WIN9X下不支持,,應(yīng)設(shè)為NULL int dwCreationDisposition, // 對于串口通信,,創(chuàng)建方式只能為OPEN_EXISTING int dwFlagsAndAttributes, // 指定串口屬性與標(biāo)志,設(shè)置為FILE_FLAG_OVERLAPPED(重疊I/O操作),,指定串口以異步方式通信 int hTemplateFile // 對于串口通信必須設(shè)置為NULL ); [DllImport("kernel32.dll")] private static extern bool GetCommState( int hFile, //通信設(shè)備句柄 ref DCB lpDCB // 設(shè)備控制塊DCB ); [DllImport("kernel32.dll")] private static extern bool BuildCommDCB( string lpDef, // 設(shè)備控制字符串 ref DCB lpDCB // 設(shè)備控制塊 ); [DllImport("kernel32.dll")] private static extern bool SetCommState( int hFile, // 通信設(shè)備句柄 ref DCB lpDCB // 設(shè)備控制塊 ); [DllImport("kernel32.dll")] private static extern bool GetCommTimeouts( int hFile, // 通信設(shè)備句柄 handle to comm device ref COMMTIMEOUTS lpCommTimeouts // 超時(shí)時(shí)間 time-out values ); [DllImport("kernel32.dll")] private static extern bool SetCommTimeouts( int hFile, // 通信設(shè)備句柄 handle to comm device ref COMMTIMEOUTS lpCommTimeouts // 超時(shí)時(shí)間 time-out values ); [DllImport("kernel32.dll")] private static extern bool ReadFile( int hFile, // 通信設(shè)備句柄 handle to file byte[] lpBuffer, // 數(shù)據(jù)緩沖區(qū) data buffer int nNumberOfBytesToRead, // 多少字節(jié)等待讀取 number of bytes to read ref int lpNumberOfBytesRead, // 讀取多少字節(jié) number of bytes read ref OVERLAPPED lpOverlapped // 溢出緩沖區(qū) overlapped buffer ); [DllImport("kernel32.dll")] private static extern bool WriteFile( int hFile, // 通信設(shè)備句柄 handle to file byte[] lpBuffer, // 數(shù)據(jù)緩沖區(qū) data buffer int nNumberOfBytesToWrite, // 多少字節(jié)等待寫入 number of bytes to write ref int lpNumberOfBytesWritten, // 已經(jīng)寫入多少字節(jié) number of bytes written ref OVERLAPPED lpOverlapped // 溢出緩沖區(qū) overlapped buffer ); [DllImport("kernel32.dll")] private static extern bool CloseHandle( int hObject // handle to object ); [DllImport("kernel32.dll")] private static extern uint GetLastError(); public void Open() { DCB dcbCommPort = new DCB(); COMMTIMEOUTS ctoCommPort = new COMMTIMEOUTS(); // 打開串口 OPEN THE COMM PORT. hComm = CreateFile(PortNum ,GENERIC_READ | GENERIC_WRITE,0, 0,OPEN_EXISTING,0,0); // 如果串口沒有打開,,就打開 IF THE PORT CANNOT BE OPENED, BAIL OUT. if(hComm == INVALID_HANDLE_VALUE) { throw(new ApplicationException("非法操作,不能打開串口,!")); } // 設(shè)置通信超時(shí)時(shí)間 SET THE COMM TIMEOUTS. GetCommTimeouts(hComm,ref ctoCommPort); ctoCommPort.ReadTotalTimeoutConstant = ReadTimeout; ctoCommPort.ReadTotalTimeoutMultiplier = 0; ctoCommPort.WriteTotalTimeoutMultiplier = 0; ctoCommPort.WriteTotalTimeoutConstant = 0; SetCommTimeouts(hComm,ref ctoCommPort); // 設(shè)置串口 SET BAUD RATE, PARITY, WORD SIZE, AND STOP BITS. GetCommState(hComm, ref dcbCommPort); 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, ref dcbCommPort)) { //uint ErrorNum=GetLastError(); throw(new ApplicationException("非法操作,,不能打開串口!")); } //unremark to see if setting took correctly //DCB dcbCommPort2 = new DCB(); //GetCommState(hComm, ref dcbCommPort2); Opened = true; } public void Close() { if (hComm!=INVALID_HANDLE_VALUE) { CloseHandle(hComm); } } public byte[] Read(int NumBytes) { byte[] BufBytes; byte[] OutBytes; BufBytes = new byte[NumBytes]; if (hComm!=INVALID_HANDLE_VALUE) { OVERLAPPED ovlCommPort = new OVERLAPPED(); int BytesRead=0; ReadFile(hComm,BufBytes,NumBytes,ref BytesRead,ref ovlCommPort); OutBytes = new byte[BytesRead]; Array.Copy(BufBytes,OutBytes,BytesRead); } else { throw(new ApplicationException("串口未打開,!")); } return OutBytes; } public void Write(byte[] WriteBytes) { if (hComm!=INVALID_HANDLE_VALUE) { OVERLAPPED ovlCommPort = new OVERLAPPED(); int BytesWritten = 0; WriteFile(hComm,WriteBytes,WriteBytes.Length,ref BytesWritten,ref ovlCommPort); } else { throw(new ApplicationException("串口未打開,!")); } } } class HexCon { // 把十六進(jìn)制字符串轉(zhuǎn)換成字節(jié)型和把字節(jié)型轉(zhuǎn)換成十六進(jìn)制字符串 converter hex string to byte and byte to hex string public static string ByteToString(byte[] InBytes) { string StringOut=""; foreach (byte InByte in InBytes) { StringOut=StringOut + String.Format("{0:X2} ",InByte); } return StringOut; } public static byte[] StringToByte(string InString) { string[] ByteStrings; ByteStrings = InString.Split(" ".ToCharArray()); byte[] ByteOut; ByteOut = new byte[ByteStrings.Length-1]; for (int i = 0;i==ByteStrings.Length-1;i++) { ByteOut[i] = Convert.ToByte(("0x" + ByteStrings[i])); } return ByteOut; } } } ---------------------------------------------------------------------
|
|