不使用 .NET SerialPort 類別,直接透過 P/Invoke 呼叫 Win32 API (kernel32.dll) 進行串口操作,提供更底層的控制能力。
對應 Win32 DCB 結構,包含完整通訊參數:
BaudRate)、資料位 (ByteSize)、奇偶校驗 (Parity)、停止位 (StopBits)fBinary、fParity、fOutxCtsFlow、fOutxDsrFlow、fDtrControl、fRtsControl 等XonChar、XoffChar、XonLim、XoffLimErrorChar、EofChar、EvtCharReadIntervalTimeout
ReadTotalTimeoutMultiplier
ReadTotalTimeoutConstant
WriteTotalTimeoutMultiplier
WriteTotalTimeoutConstant
支援重疊 I/O (非同步) 操作。
[DllImport("kernel32.dll")]
static extern int CreateFile(string lpFileName, uint dwDesiredAccess,
int dwShareMode, int lpSecurityAttributes, int dwCreationDisposition,
int dwFlagsAndAttributes, int hTemplateFile);
[DllImport("kernel32.dll")]
static extern bool GetCommState(int hFile, ref DCB lpDCB);
[DllImport("kernel32.dll")]
static extern bool BuildCommDCB(string lpDef, ref DCB lpDCB);
[DllImport("kernel32.dll")]
static extern bool SetCommState(int hFile, ref DCB lpDCB);
[DllImport("kernel32.dll")]
static extern bool GetCommTimeouts(int hFile, ref COMMTIMEOUTS lpCommTimeouts);
[DllImport("kernel32.dll")]
static extern bool SetCommTimeouts(int hFile, ref COMMTIMEOUTS lpCommTimeouts);
[DllImport("kernel32.dll")]
static extern bool ReadFile(int hFile, byte[] lpBuffer, int nNumberOfBytesToRead,
ref int lpNumberOfBytesRead, ref OVERLAPPED lpOverlapped);
[DllImport("kernel32.dll")]
static extern bool WriteFile(int hFile, byte[] lpBuffer, int nNumberOfBytesToWrite,
ref int lpNumberOfBytesWritten, ref OVERLAPPED lpOverlapped);
[DllImport("kernel32.dll")]
static extern bool CloseHandle(int hObject);
[DllImport("kernel32.dll")]
static extern uint GetLastError();
CreateFile 取得通訊裝置控制代碼 (GENERIC_READ | GENERIC_WRITE、OPEN_EXISTING、FILE_FLAG_OVERLAPPED)GetCommTimeouts 取得目前逾時設定,修改 ReadTotalTimeoutConstant 後 SetCommTimeoutsGetCommState 取得目前 DCB,填入鮑率、旗標、資料位、奇偶、停止位SetCommState 套用設定public byte[] Read(int numBytes)
{
byte[] buf = new byte[numBytes];
OVERLAPPED ovl = new OVERLAPPED();
int bytesRead = 0;
ReadFile(hComm, buf, numBytes, ref bytesRead, ref ovl);
byte[] result = new byte[bytesRead];
Array.Copy(buf, result, bytesRead);
return result;
}
public void Write(byte[] writeBytes)
{
OVERLAPPED ovl = new OVERLAPPED();
int bytesWritten = 0;
WriteFile(hComm, writeBytes, writeBytes.Length, ref bytesWritten, ref ovl);
}
提供位元組陣列與十六進位字串雙向轉換。
SerialPort 類別限制的進階應用