Imports System
Imports System.Runtime.InteropServices
Namespace JustinIO
Class CommPort
Public PortNum As String
Public BaudRate As Integer
Public ByteSize As Byte
Public Parity As Byte '// 0-4=no,odd,even,mark,space
Public StopBits As Byte '// 0,1,2 = 1, 1.5, 2
Public ReadTimeout As Integer '//comm port win32 file handle
Private hComm As Integer = -1
Public Opened As Boolean = False
'//win32 api constants
Private Const GENERIC_READ As Int64 = &H80000000
Private Const GENERIC_WRITE As Int64 = &H40000000
Private Const OPEN_EXISTING As Integer = 3
Private Const INVALID_HANDLE_VALUE As Integer = -1
#Region "struct"
<StructLayout(LayoutKind.Sequential)> _
Public Structure DCB
'//taken from c struct in platform sdk
Public DCBlength As Integer '// sizeof(DCB)
Public BaudRate As Integer '// 指定當前傳輸速率 current baud rate
'// these are the c struct bit fields, bit twiddle flag to set
Public fBinary As Integer '// 指定是否允許二進位模式,在windows95中必須主TRUE binary mode, no EOF check
Public fParity As Integer '// 指定是否允許同位 enable parity checking
Public fOutxCtsFlow As Integer '// 指定CTS是否用於檢測發送控制,當為TRUE是CTS為OFF,發送將被掛起。 CTS output flow control
Public fOutxDsrFlow As Integer '// 指定CTS是否用於檢測發送控制 DSR output flow control
Public fDtrControl As Integer '// DTR_CONTROL_DISABLE值將DTR置為OFF, DTR_CONTROL_ENABLE值將DTR置為ON, DTR_CONTROL_HANDSHAKE允許DTR"握手" DTR flow control type
Public fDsrSensitivity As Integer '// 當該值為TRUE時DSR為OFF時接收的位元組被忽略 DSR sensitivity
Public fTXContinueOnXoff As Integer '// 指定當接收緩衝區已滿,並且驅動程式已經發送出XoffChar字元時發送是否停止。TRUE時,在接收緩衝區接收到緩衝區已滿的位元組XoffLim且驅動程式已經發送出XoffChar字元中止接收位元組之後,發送繼續進行。 FALSE時,在接收緩衝區接收到代表緩衝區已空的位元組XonChar且驅動程式已經發送出恢複發送的XonChar之後,發送繼續進行。XOFF continues Tx
Public fOutX As Integer '// TRUE時,接收到XoffChar之後便停止發送接收到XonChar之後將重新開始 XON/XOFF out flow control
Public fInX As Integer '// TRUE時,接收緩衝區接收到代表緩衝區滿的XoffLim之後,XoffChar發送出去接收緩衝區接收到代表緩衝區空的XonLim之後,XonChar發送出去 XON/XOFF in flow control
Public fErrorChar As Integer '// 該值為TRUE且fParity為TRUE時,用ErrorChar 成員指定的字元代替同位錯誤的接收字元 enable error replacement
Public fNull As Integer '// eTRUE時,接收時去掉空(0值)位元組 enable null stripping
Public fRtsControl As Integer '// 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*/
Public fAbortOnError As Integer '// TRUE時,有錯誤發生時中止讀和寫操作 abort on error
Public fDummy2 As Integer '// 未使用 reserved
Public flags As Int64
Public wReserved As UInt16 '// 未使用,必須為0 not currently used
Public XonLim As UInt16 '// 指定在XON字元發送這前接收緩衝區中可允許的最小位元組數 transmit XON threshold
Public XoffLim As UInt16 '// 指定在XOFF字元發送這前接收緩衝區中可允許的最小位元組數 transmit XOFF threshold
Public ByteSize As Byte '// 指定連接埠當前使用的資料位元 number of bits/byte, 4-8
Public Parity As Byte '// 指定連接埠當前使用的同位方法,可能為:EVENPARITY,MARKPARITY,NOPARITY,ODDPARITY 0-4=no,odd,even,mark,space
Public StopBits As Byte '// 指定連接埠當前使用的停止位元,可能為:ONESTOPBIT,ONE5STOPBITS,TWOSTOPBITS 0,1,2 = 1, 1.5, 2
Public XonChar As Char '// 指定用於發送和接收字元XON的值 Tx and Rx XON character
Public XoffChar As Char '// 指定用於發送和接收字元XOFF值 Tx and Rx XOFF character
Public ErrorChar As Char '// 本字元用來代替接收到的同位發生錯誤時的值 error replacement character
Public EofChar As Char '// 當沒有使用二進位模式時,本字元可用來指示資料的結束 end of input character
Public EvtChar As Char '// 當接收到此字元時,會產生一個事件 received event character
Public wReserved1 As UInt16 '// 未使用 reserved; do not use
End Structure
<StructLayout(LayoutKind.Sequential)> _
Private Structure COMMTIMEOUTS
Public ReadIntervalTimeout As Integer
Public ReadTotalTimeoutMultiplier As Integer
Public ReadTotalTimeoutConstant As Integer
Public WriteTotalTimeoutMultiplier As Integer
Public WriteTotalTimeoutConstant As Integer
End Structure
<StructLayout(LayoutKind.Sequential)> _
Private Structure OVERLAPPED
Public Internal As Integer
Public InternalHigh As Integer
Public Offset As Integer
Public OffsetHigh As Integer
Public hEvent As Integer
End Structure
#End Region
#Region "Windows API"
<DllImport("kernel32.dll", CharSet:=CharSet.Auto)> _
Private Shared Function CreateFile( _
ByVal lpFileName As String, _
ByVal dwDesiredAccess As UInt32, _
ByVal dwShareMode As Integer, _
ByVal lpSecurityAttributes As Integer, _
ByVal dwCreationDisposition As Integer, _
ByVal dwFlagsAndAttributes As Integer, _
ByVal hTemplateFile As Integer) As Integer
End Function
'參數介紹:
'lpFileName 要開啟的串口名稱
'dwDesiredAccess 指定串口的訪問方式,一般設定為可讀可寫方式
'dwShareMode 指定串口的共用模式,串口不能共用,所以設定為0
'lpSecurityAttributes 設定串口的安全屬性,WIN9X下不支援,應設為NULL
'dwCreationDisposition 對於串口通訊,建立方式只能為OPEN_EXISTING
'dwFlagsAndAttributes 指定串口屬性與標誌,設定為FILE_FLAG_OVERLAPPED(重疊I/O操作),指定串口以非同步方式通訊
'hTemplateFile 對於串口通訊必須設定為NULL
<DllImport("kernel32.dll")> _
Private Shared Function GetCommState(ByVal hFile As Integer, ByRef lpDCB As DCB) As Boolean
End Function
'參數介紹
'hFile 通訊裝置控制代碼
'DCB lpDCB 裝置控制塊DCB
<DllImport("kernel32.dll")> _
Private Shared Function BuildCommDCB(ByVal lpDef As String, ByRef lpDCB As DCB) As Boolean
End Function
'參數介紹
'lpDef 裝置控制字元串
'lpDCB 裝置控制塊DCB
<DllImport("kernel32.dll")> _
Private Shared Function SetCommState(ByVal hfile As Integer, ByRef lpDCB As DCB) As Boolean
End Function
'參數說明
'hFile 通訊裝置控制代碼
'lpDCB 裝置控制塊
<DllImport("kernel32.dll")> _
Private Shared Function GetCommTimeouts(ByVal hfile As Integer, ByRef lpCommTimeouts As COMMTIMEOUTS) As Boolean
End Function
'參數說明
'hFile 通訊裝置控制代碼 handle to comm device
'lpCommTimeouts 逾時時間 time-out values
<DllImport("kernel32.dll")> _
Private Shared Function SetCommTimeouts(ByVal hfile As Integer, ByRef lpCommTimeouts As COMMTIMEOUTS) As Boolean
End Function
'參數說明
'hFile 通訊裝置控制代碼 handle to comm device
'lpCommTimeouts 逾時時間 time-out values
<DllImport("kernel32.dll")> _
Private Shared Function ReadFile(ByVal hFile As Integer, ByVal lpBuffer() As Byte, _
ByVal nNumberOfBytesToRead As Integer, ByRef lpNumberOfBytesRead As Integer, _
ByRef lpOverlapped As OVERLAPPED) As Boolean
End Function
'參數說明
'hFile 通訊裝置控制代碼 handle to file
'lpBuffer 資料緩衝區 data buffer
'nNumberOfBytesToRead 多少位元組等待讀取 number of bytes to read
'lpNumberOfBytesRead 讀取多少位元組 number of bytes read
'lpOverlapped 溢出緩衝區 overlapped buffer
<DllImport("kernel32.dll")> _
Private Shared Function WriteFile(ByVal hFile As Integer, ByVal lpBuffer() As Byte, _
ByVal nNumberOfBytesToRead As Integer, ByRef lpNumberOfBytesWritten As Integer, _
ByRef lpOverlapped As OVERLAPPED) As Boolean
End Function
'參數介紹
'hFile 通訊裝置控制代碼 handle to file
'lpBuffer 資料緩衝區 data buffer
'nNumberOfBytesToWrite 多少位元組等待寫入 number of bytes to write
'lpNumberOfBytesWritten 已經寫入多少位元組 number of bytes written
'lpOverlapped 溢出緩衝區 overlapped buffer
<DllImport("kernel32.dll")> _
Private Shared Function CloseHandle(ByVal hObject As Integer) As Boolean
End Function
'參數hObject 要被關閉的控制代碼 handle to object
<DllImport("kernel32.dll")> _
Private Shared Function GetLastError() As UInt32
End Function
#End Region
Public Sub open()
Dim dcbCommPort As New DCB
Dim ctoCommPort As New COMMTIMEOUTS
'// 開啟串口 OPEN THE COMM PORT.
hComm = CreateFile(PortNum, UInt32.Parse(GENERIC_READ Or GENERIC_WRITE), 0, 0, OPEN_EXISTING, 0, 0)
'// 如果串口沒有開啟,就開啟 IF THE PORT CANNOT BE OPENED, BAIL OUT.
If hComm = INVALID_HANDLE_VALUE Then
Throw (New ApplicationException("非法操作,不能開啟串口!"))
End If
'// 設定通訊逾時時間 SET THE COMM TIMEOUTS.
GetCommTimeouts(hComm, ctoCommPort) 'ref
ctoCommPort.ReadTotalTimeoutConstant = ReadTimeout
ctoCommPort.ReadTotalTimeoutMultiplier = 0
ctoCommPort.WriteTotalTimeoutMultiplier = 0
ctoCommPort.WriteTotalTimeoutConstant = 0
SetCommTimeouts(hComm, ctoCommPort) 'ref
'// 設定串口 SET BAUD RATE, PARITY, WORD SIZE, AND STOP BITS.
GetCommState(hComm, dcbCommPort) 'ref
dcbCommPort.BaudRate = BaudRate
dcbCommPort.flags = 0
'//dcb.fBinary=1;
dcbCommPort.flags = dcbCommPort.flags Or (1)
If Parity > 0 Then
'//dcb.fParity=1
dcbCommPort.flags = dcbCommPort.flags Or (2)
End If
dcbCommPort.Parity = Parity
dcbCommPort.ByteSize = ByteSize
dcbCommPort.StopBits = StopBits
If SetCommState(hComm, dcbCommPort) = False Then
'//uint ErrorNum=GetLastError();
Throw (New ApplicationException("非法操作,不能開啟串口!"))
End If
'//unremark to see if setting took correctly
'//DCB dcbCommPort2 = new DCB();
'//GetCommState(hComm, ref dcbCommP