串列埠通訊類JustinIO.CommPort及使用方法
- using System;
- using System.Runtime.InteropServices;
- using System.Text;
- namespace JustinIO
- {
- publicclass CommPort
- {
- publicstring PortName;
- publicint BaudRate;
- publicbyte DataBits;
- publicbyte Parity; // 0-4=no,odd,even,mark,space
- publicbyte StopBits; // 0,1,2 = 1, 1.5, 2
- publicint ReadTimeout;
- //comm port win32 file handle
- privateint hComm = -1;
- publicbool Opened = false;
- publicbool IsOpen = false;
- //win32 api constants
- privateconstuint GENERIC_READ = 0x80000000;
- privateconstuint GENERIC_WRITE = 0x40000000;
- privateconstint OPEN_EXISTING = 3;
- privateconstint INVALID_HANDLE_VALUE = -1;
- [StructLayout(LayoutKind.Sequential)]
- publicstruct DCB
- {
- //taken from c struct in platform sdk
- publicint DCBlength; // sizeof(DCB)
- publicint BaudRate; // 指定當前波特率 current baud rate
- // these are the c struct bit fields, bit twiddle flag to set
- publicint fBinary; // 指定是否允許二進位制模式,在windows95中必須主TRUE binary mode, no EOF check
- public
- publicint fOutxCtsFlow; // 指定CTS是否用於檢測傳送控制,當為TRUE是CTS為OFF,傳送將被掛起。 CTS output flow control
- publicint fOutxDsrFlow; // 指定CTS是否用於檢測傳送控制 DSR output flow control
- publicint fDtrControl; // DTR_CONTROL_DISABLE值將DTR置為OFF, DTR_CONTROL_ENABLE值將DTR置為ON, DTR_CONTROL_HANDSHAKE允許DTR"握手" DTR flow control type
- publicint fDsrSensitivity; // 當該值為TRUE時DSR為OFF時接收的位元組被忽略 DSR sensitivity
- publicint fTXContinueOnXoff; // 指定當接收緩衝區已滿,並且驅動程式已經發送出XoffChar字元時傳送是否停止。TRUE時,在接收緩衝區接收到緩衝區已滿的位元組XoffLim且驅動程式已經發送出XoffChar字元中止接收位元組之後,傳送繼續進行。 FALSE時,在接收緩衝區接收到代表緩衝區已空的位元組XonChar且驅動程式已經發送出恢復傳送的XonChar之後,傳送繼續進行。XOFF continues Tx
- publicint fOutX; // TRUE時,接收到XoffChar之後便停止傳送接收到XonChar之後將重新開始 XON/XOFF out flow control
- publicint fInX; // TRUE時,接收緩衝區接收到代表緩衝區滿的XoffLim之後,XoffChar傳送出去接收緩衝區接收到代表緩衝區空的XonLim之後,XonChar傳送出去 XON/XOFF in flow control
- publicint fErrorChar; // 該值為TRUE且fParity為TRUE時,用ErrorChar 成員指定的字元代替奇偶校驗錯誤的接收字元 enable error replacement
- publicint fNull; // eTRUE時,接收時去掉空(0值)位元組 enable null stripping
- publicint fRtsControl; // RTS flow control
- /*RTS_CONTROL_DISABLE時,RTS置為OFF
- RTS_CONTROL_ENABLE時, RTS置為ON
- RTS_CONTROL_HANDSHAKE時,
- 當接收緩衝區小於半滿時RTS為ON
- 當接收緩衝區超過四分之三滿時RTS為OFF
- RTS_CONTROL_TOGGLE時,
- 當接收緩衝區仍有剩餘位元組時RTS為ON ,否則預設為OFF*/
- publicint fAbortOnError; // TRUE時,有錯誤發生時中止讀和寫操作 abort on error
- publicint fDummy2; // 未使用 reserved
- publicuint flags;
- publicushort wReserved; // 未使用,必須為0 not currently used
- publicushort XonLim; // 指定在XON字元傳送這前接收緩衝區中可允許的最小位元組數 transmit XON threshold
- publicushort XoffLim; // 指定在XOFF字元傳送這前接收緩衝區中可允許的最小位元組數 transmit XOFF threshold
- publicbyte ByteSize; // 指定埠當前使用的資料位 number of bits/byte, 4-8
- publicbyte Parity; // 指定埠當前使用的奇偶校驗方法,可能為:EVENPARITY,MARKPARITY,NOPARITY,ODDPARITY 0-4=no,odd,even,mark,space
- publicbyte StopBits; // 指定埠當前使用的停止位數,可能為:ONESTOPBIT,ONE5STOPBITS,TWOSTOPBITS 0,1,2 = 1, 1.5, 2
- publicchar XonChar; // 指定用於傳送和接收字元XON的值 Tx and Rx XON character
- publicchar XoffChar; // 指定用於傳送和接收字元XOFF值 Tx and Rx XOFF character
- publicchar ErrorChar; // 本字元用來代替接收到的奇偶校驗發生錯誤時的值 error replacement character
- publicchar EofChar; // 當沒有使用二進位制模式時,本字元可用來指示資料的結束 end of input character
- publicchar EvtChar; // 當接收到此字元時,會產生一個事件 received event character
- publicushort wReserved1; // 未使用 reserved; do not use
- }
- [StructLayout(LayoutKind.Sequential)]
- privatestruct COMMTIMEOUTS
- {
- publicint ReadIntervalTimeout;
- publicint ReadTotalTimeoutMultiplier;
- publicint ReadTotalTimeoutConstant;
- publicint WriteTotalTimeoutMultiplier;
- publicint WriteTotalTimeoutConstant;
- }
- [StructLayout(LayoutKind.Sequential)]
- privatestruct OVERLAPPED
- {
- publicint Internal;
- publicint InternalHigh;
- publicint Offset;
- publicint OffsetHigh;
- publicint hEvent;
- }
- [DllImport("kernel32.dll")]
- privatestaticexternint CreateFile(
- string lpFileName, // 要開啟的串列埠名稱
- uint dwDesiredAccess, // 指定串列埠的訪問方式,一般設定為可讀可寫方式
- int dwShareMode, // 指定串列埠的共享模式,串列埠不能共享,所以設定為0
- int lpSecurityAttributes, // 設定串列埠的安全屬性,WIN9X下不支援,應設為NULL
- int dwCreationDisposition, // 對於串列埠通訊,建立方式只能為OPEN_EXISTING
- int dwFlagsAndAttributes, // 指定串列埠屬性與標誌,設定為FILE_FLAG_OVERLAPPED(重疊I/O操作),指定串列埠以非同步方式通訊
- int hTemplateFile // 對於串列埠通訊必須設定為NULL
- );
- [DllImport("kernel32.dll")]
- privatestaticexternbool GetCommState(
- int hFile, //通訊裝置控制代碼
- ref DCB lpDCB // 裝置控制塊DCB
- );
- [DllImport("kernel32.dll")]
- privatestaticexternbool BuildCommDCB(
- string lpDef, // 裝置控制字串
- ref DCB lpDCB // 裝置控制塊
- );
- [DllImport("kernel32.dll")]
- privatestaticexternbool SetCommState(
- int hFile, // 通訊裝置控制代碼
- ref DCB lpDCB // 裝置控制塊
- );
- [DllImport("kernel32.dll")]
- privatestaticexternbool GetCommTimeouts(
- int hFile, // 通訊裝置控制代碼 handle to comm device
- ref COMMTIMEOUTS lpCommTimeouts // 超時時間 time-out values
- );
- [DllImport("kernel32.dll")]
- privatestaticexternbool SetCommTimeouts(
- int hFile, // 通訊裝置控制代碼 handle to comm device
- ref COMMTIMEOUTS lpCommTimeouts // 超時時間 time-out values
- );
- [DllImport("kernel32.dll")]
- privatestaticexternbool ReadFile(
- int hFile, // 通訊裝置控制代碼 handle to file
- byte[] lpBuffer, // 資料緩衝區 data buffer
- int nNumberOfBytesToRead, // 多少位元組等待讀取 number of bytes to read
- refint lpNumberOfBytesRead, // 讀取多少位元組 number of bytes read
- ref OVERLAPPED lpOverlapped // 溢位緩衝區 overlapped buffer
- );
- [DllImport("kernel32.dll")]
- privatestaticexternbool WriteFile(
- int hFile, // 通訊裝置控制代碼 handle to file
- byte[] lpBuffer, // 資料緩衝區 data buffer
- int nNumberOfBytesToWrite, // 多少位元組等待寫入 number of bytes to write
- refint lpNumberOfBytesWritten, // 已經寫入多少位元組 number of bytes written
- ref OVERLAPPED lpOverlapped // 溢位緩衝區 overlapped buffer
- );
- [DllImport("kernel32.dll")]
- privatestaticexternbool CloseHandle(
- int hObject // handle to object
- );
- [DllImport("kernel32.dll")]
- privatestaticexternuint GetLastError();
- publicvoid Open()
- {
- DCB dcbCommPort = new DCB();
- COMMTIMEOUTS ctoCommPort = new COMMTIMEOUTS();
- // 開啟串列埠 OPEN THE COMM PORT.
- string num = PortName.Replace("COM", "");
- if (int.Parse(num) >= 10)
- hComm = CreateFile("//./"" + PortName, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0);
- else
- hComm = CreateFile(PortName, 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 Exception("非法操作,不能開啟串列埠!"));
- }
- // 設定通訊超時時間 SET THE COMM TIMEOUTS.
- GetCommTimeouts(hComm, ref ctoCommPort);
- ctoCommPort.ReadTotalTimeoutConstant = ReadTimeout;
- ctoCommPort.ReadTotalTimeoutMultiplier = 0;
- ctoCommPort.WriteTotalTimeoutMultiplier = 0;
- ctoCommPort.WriteTotalTimeoutConstant = 0;
- SetCommTimeouts(hComm, ref ctoCommPort);
- // 設定串列埠 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 = DataBits;
- 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;
- IsOpen = true;
- }
- publicvoid Close()
- {
- if (hComm != INVALID_HANDLE_VALUE)
- {
- CloseHandle(hComm);
- }
- }
- publicbyte[] Read(int NumBytes)
- {
- byte[] BufBytes;
- byte[] OutBytes;
- BufBytes = newbyte[NumBytes];
- if (hComm != INVALID_HANDLE_VALUE)
- {
- OVERLAPPED ovlCommPort = new OVERLAPPED();
- int BytesRead = 0;
- ReadFile(hComm, BufBytes, NumBytes, ref BytesRead, ref ovlCommPort);
- OutBytes = newbyte[BytesRead];
- Array.Copy(BufBytes, OutBytes, BytesRead);
- }
- else
- {
- throw (new ApplicationException("串列埠未開啟!"));
- }
- return OutBytes;
- }
- publicstring ReadExisting()
- {
- return Encoding.ASCII.GetString(Read(128));
- }
- publicvoid 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("串列埠未開啟!"));
- }
- }
- publicvoid Write(string WriteString, Encoding CoderType)
- {
- Write(CoderType.GetBytes(WriteString));
- }
- publicvoid Write(string WriteString)
- {
- Write(Encoding.ASCII.GetBytes(WriteString));
- }
- }
- }
介紹JustinIO的使用方法:
開啟串列埠:
函式原型:public void Open()
說明:開啟事先設定好的埠
示例:
using JustinIO;
static JustinIO.CommPort ss_port = new JustinIO.CommPort();
ss_port.PortNum = COM1; //埠號
ss_port.BaudRate = 19200; //串列埠通訊波特率
ss_port.ByteSize = 8; //資料位
ss_port.Parity = 0; //奇偶校驗
ss_port.StopBits = 1;//停止位
ss_port.ReadTimeout = 1000; //讀超時
try
{
if (ss_port.Opened)
{
ss_port.Close();
ss_port.Open(); //開啟串列埠
}
else
{
ss_port.Open();//開啟串列埠
}
return true;
}
catch(Exception e)
{
MessageBox.Show("錯誤:" + e.Message);
return false;
}
寫串列埠:
函式原型:public void Write(byte[] WriteBytes)
WriteBytes 就是你的寫入的位元組,注意,字串要轉換成位元組陣列才能進行通訊
示例:
ss_port.Write(Encoding.ASCII.GetBytes("AT+CGMI/r")); //獲取手機品牌
讀串列埠:
函式原型:public byte[] Read(int NumBytes)
NumBytes 讀入快取數,注意讀取來的是位元組陣列,要實際應用中要進行字元轉換
示例:
string response = Encoding.ASCII.GetString(ss_port.Read(128)); //讀取128個位元組快取
關閉串列埠:
函式原型:ss_port.Close()
示例:
ss_port.Close();