VB6.0 API串口接收/發送數據及串口設置


Option Explicit

Public PortMemory As String Public AllBlueMemory As String Public BlueMemory As String

Private Type COMSTAT

    fBitFields As Long

   COMSTAT   cbInQue As Long

   cbOutQue As Long

End Type

Private Type COMMTIMEOUTS

    ReadIntervalTimeout As Long

    ReadTotalTimeoutMultiplier As Long

    ReadTotalTimeoutConstant As Long

    WriteTotalTimeoutMultiplier As Long

    WriteTotalTimeoutConstant As Long

End Type

Private Type DCB

    DCBlength As Long

    BaudRate As Long

    fBitFields As Long

    wReserved As Integer

    XonLim As Integer

    XoffLim As Integer

    ByteSize As Byte

    Parity As Byte

    StopBits As Byte

    XonChar As Byte

    XoffChar As Byte

    ErrorChar As Byte

    EOFChar As Byte

    EvtChar As Byte

    wReserved1 As Integer

End Type

Private Type OVERLAPPED

    Internal As Long

    InternalHigh As Long

    offset As Long

    OffsetHigh As Long

    hEvent As Long

End Type

Private Type SECURITY_ATTRIBUTES

    nLength As Long

    lpSecurityDescriptor As Long

    bInheritHandle As Long

End Type

Public Declare Function OpenProcess Lib "kernel32" (ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal dwProcessId As Long) As Long

Public Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long

Public Declare Function TerminateProcess Lib "kernel32" (ByVal hProcess As Long, ByVal uExitCode As Long) As Long

Private Declare Function GetLastError Lib "kernel32" () As Long

Private Declare Function ReadFile Lib "kernel32" (ByVal hFile As Long, lpBuffer As Any, ByVal nNumberOfBytesToRead As Long, lpNumberOfBytesRead As Long, lpOverlapped As OVERLAPPED) As Long

Private Declare Function WriteFile Lib "kernel32" (ByVal hFile As Long, lpBuffer As Any, ByVal nNumberOfBytesToWrite As Long, lpNumberOfBytesWritten As Long, lpOverlapped As OVERLAPPED) As Long 'OVERLAPPED

Private Declare Function SetCommTimeouts Lib "kernel32" (ByVal hFile As Long, lpCommTimeouts As COMMTIMEOUTS) As Long

Private Declare Function GetCommTimeouts Lib "kernel32" (ByVal hFile As Long, lpCommTimeouts As COMMTIMEOUTS) As Long

Private Declare Function GetOverlappedResult Lib "kernel32" (ByVal hFile As Long, lpOverlapped As OVERLAPPED, lpNumberOfBytesTransferred As Long, ByVal bWait As Long) As Long

Private Declare Function BuildCommDCB Lib "kernel32" Alias "BuildCommDCBA" (ByVal lpDef As String, lpDCB As DCB) As Long

Private Declare Function SetCommState Lib "kernel32" (ByVal hCommDev As Long, lpDCB As DCB) As Long

Private Declare Function GetCommState Lib "kernel32" (ByVal nCid As Long, lpDCB As DCB) As Long

Private Declare Function CreateFile Lib "kernel32" Alias "CreateFileA" (ByVal lpFileName As String, ByVal dwDesiredAccess As Long, ByVal dwShareMode As Long, ByVal lpSecurityAttributes As Long, ByVal dwCreationDisposition As Long, ByVal dwFlagsAndAttributes As Long, ByVal hTemplateFile As Long) As Long

Private Declare Function FlushFileBuffers Lib "kernel32" (ByVal hFile As Long) As Long

Private Declare Function CreateEvent Lib "kernel32" Alias "CreateEventA" (lpEventAttributes As SECURITY_ATTRIBUTES, ByVal bManualReset As Long, ByVal bInitialState As Long, ByVal lpName As String) As Long

Private Declare Function SetCommMask Lib "kernel32" (ByVal hFile As Long, ByVal dwEvtMask As Long) As Long

Private Declare Function SetEvent Lib "kernel32" (ByVal hEvent As Long) As Long

Private Declare Function SetupComm Lib "kernel32" (ByVal hFile As Long, ByVal dwInQueue As Long, ByVal dwOutQueue As Long) As Long

Private Declare Function PurgeComm Lib "kernel32" (ByVal hFile As Long, ByVal dwFlags As Long) As Long

Private Declare Function ClearCommError Lib "kernel32" (ByVal hFile As Long, lpErrors As Long, lpStat As COMSTAT) As Long

Private Declare Function WaitCommEvent Lib "kernel32 " (ByVal hFile As Long, lpEvtMask As Long, lpOverlapped As OVERLAPPED) As Long

Private Declare Function ResetEvent Lib "kernel32 " (ByVal hFile As Long) As Long

Private Declare Function WaitForSingleObject Lib "kernel32" (ByVal hHandle As Long, ByVal dwMilliseconds As Long) As Long Private Declare Function GetTickCount Lib "kernel32" () As Long

Public Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)

Private Const INVALID_HANDLE_VALUE = -1

Private Const GENERIC_WRITE = &H40000000

Private Const GENERIC_READ = &H80000000

Private Const OPEN_EXISTING = 3

Private Const FILE_ATTRIBUTE_NORMAL = &H80

Private Const FILE_FLAG_OVERLAPPED = &H40000000

Private Const DTR_CONTROL_DISABLE = &H0

Private Const RTS_CONTROL_ENABLE = &H1

Private Const PURGE_RXABORT = &H2

Private Const PURGE_RXCLEAR = &H8

Private Const PURGE_TXABORT = &H1

Private Const PURGE_TXCLEAR = &H4

Private Const ERROR_IO_PENDING = 997

Private Const STATUS_WAIT_0 = &H0

Private Const WAIT_OBJECT_0 = (STATUS_WAIT_0 + 0)

Private Const WAIT_TIMEOUT = 258&

Public Const PROCESS_QUERY_INFORMATION = &H400

Public Const PROCESS_TERMINATE = &H1

Private Const EV_RXCHAR = &H1                '  Any Character received

Private m_OverlappedRead As OVERLAPPED

Private m_OverlappedWrite As OVERLAPPED

Private com_Handle As Long

Private com_RxBy As Long Private com_TxBy As Long

Public Property Get ReceivedByte() As Long    

ReceivedByte = com_RxBy

End Property

Public Property Get SendedByte() As Long

    SendedByte = com_TxBy

End Property

Public Property Let ReceivedByte(X As Long)    

com_RxBy = 0

End Property

Public Property Let SendedByte(X As Long)    

com_TxBy = 0

End Property

Public Property Get Handle() As Long

    Handle = com_Handle

End Property

'Public Property Let Handle(id As Long)

'    com_Handle = id 'End Property

'*************************************************************************

'**函 數 名:OpenPort '**ComPort:形式如:COM1、COM2、LPT1等等

'**Comsettings:形式如:"9600,n,8,1"

'**lngInSize:寫入緩沖區大小

'**lngOutSize:寫出緩沖區大小

'*************************************************************************

Public Function OpenPort(ComPort As String, Comsettings As String, Optional lngInSize As Long = 1024, Optional lngOutSize As Long = 1024) As Long   

  On Error GoTo handelinitcom    

Dim RetVal As Long     '定義標志值   

  Dim flag As Long

    '定義設備控制塊  

   Dim typDCB As DCB

    Dim CtimeOut As COMMTIMEOUTS, dcbs As DCB

    Dim strCOM As String, strConfig As String

    '    strCOM = "COM" & Format(ComNumber, "0")     strCOM = ComPort

    '    Com_Handle = CreateFile(strCOM, GENERIC_READ Or GENERIC_WRITE, 0, ByVal 0, _        

  '                 OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL Or FILE_FLAG_OVERLAPPED, 0)

    com_Handle = CreateFile(strCOM, _

            GENERIC_READ Or GENERIC_WRITE, 0, ByVal 0, _  

           OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL Or FILE_FLAG_OVERLAPPED, 0)

    If com_Handle = INVALID_HANDLE_VALUE Then

        OpenPort = -1   

      Exit Function

    End If

    '********獲取出錯信息********

    Dim errNum As Long     errNum = GetLastError()   

  '    Debug.Print "出錯信息:" & errNum

    '********獲取設備控制塊********   

  flag = GetCommState(com_Handle, typDCB)  

   '    Debug.Print "獲取串口DCB:" & flag       

Dim SetDb() As String

    SetDb = Split(Comsettings, ",")

    If UBound(SetDb) >= 3 Then

        typDCB.BaudRate = CLng(SetDb(0))

                             '定義波特率        

If UCase(SetDb(1)) = "N" Then

                                    'NOPARITY

           typDCB.Parity = 0     

                               'NOPARITY                               '無校驗位

        Else           

typDCB.Parity = 1        

End If        

typDCB.ByteSize = CByte(SetDb(2))  '數據位

               typDCB.StopBits = CByte(SetDb(3))'停止位 0/1/2 = 1/1.5/2   

  Else        

typDCB.BaudRate = 460800  '定義波特率        

typDCB.Parity = 0   'NOPARITY  '無校驗位        

typDCB.ByteSize = 8  '數據位        

typDCB.StopBits = 0  '停止位 0/1/2 = 1/1.5/2     End If  

    '********設置串口參數********

    flag = SetCommState(com_Handle, typDCB)     '    Debug.Print "設置串口參數:" & flag

    '********設置緩沖區大小********   

  flag = SetupComm(com_Handle, lngInSize, lngOutSize)     '    flag = SetupComm(com_Handle, 8192, 8192)

    CtimeOut.ReadIntervalTimeout = -1                      '0

    CtimeOut.ReadTotalTimeoutConstant = 0                  '2500

    CtimeOut.ReadTotalTimeoutMultiplier = 0               '0

    CtimeOut.WriteTotalTimeoutConstant = 0             '20  '2500

    CtimeOut.WriteTotalTimeoutMultiplier = 0            '200  '0    

'********超時設置********    

flag = SetCommTimeouts(com_Handle, CtimeOut)

    flag = SetCommMask(com_Handle, EV_RXCHAR)              '設置監視的事件為接收到字符   

  '********清空讀寫緩沖區********  

   Call PurgeComm(com_Handle, PURGE_RXABORT Or PURGE_RXCLEAR Or PURGE_TXABORT Or PURGE_TXCLEAR)    '清除緩沖區

    If flag = -1 Then        

RetVal = GetLastError()

        OpenPort = flag

        RetVal = CloseHandle(com_Handle)

        Exit Function

    End If

    '獲取信號句柄  

   Dim lpEventAttributes1 As SECURITY_ATTRIBUTES

    Dim lpEventAttributes2 As SECURITY_ATTRIBUTES

    m_OverlappedRead.hEvent = CreateEvent(lpEventAttributes1, 1, 0, 0)     m_OverlappedWrite.hEvent = CreateEvent(lpEventAttributes2, 1, 0, 0)

    '判斷設置參數是否成功   設置輸入和輸出緩沖區是否成功

    If m_OverlappedRead.hEvent = 0 Or m_OverlappedWrite.hEvent = 0 Then

        RetVal = GetLastError()  

       OpenPort = RetVal

        If (m_OverlappedRead.hEvent <> 0) Then

CloseHandle (m_OverlappedRead.hEvent)

        If (m_OverlappedWrite.hEvent <> 0) Then

CloseHandle (m_OverlappedWrite.hEvent)

        Call CloseHandle(com_Handle)  

       com_Handle = 0       

  Exit Function   

  End If

    OpenPort = 0  

   Exit Function

handelinitcom:    

Call CloseHandle(com_Handle)

    com_Handle = 0    

OpenPort = -1    

Exit Function

End Function

'*************************************************************************

'**函 數 名:ClosePort

'*************************************************************************

Public Function ClosePort() As Long

    If com_Handle = INVALID_HANDLE_VALUE Then

        Exit Function

    End If

    Call SetCommMask(com_Handle, 0)

    Call SetEvent(m_OverlappedRead.hEvent)

    Call SetEvent(m_OverlappedWrite.hEvent)

    If (m_OverlappedRead.hEvent <> 0) Then

CloseHandle (m_OverlappedRead.hEvent)

    If (m_OverlappedWrite.hEvent <> 0) Then

CloseHandle (m_OverlappedWrite.hEvent)

    If CloseHandle(com_Handle) <> 0 Then

        ClosePort = 0    

Else        

ClosePort = -1    

End If

    com_Handle = INVALID_HANDLE_VALUE

    frmConnection.CHUANKOUFLAG = 0

End Function

'*************************************************************************

'**函 數 名:ClearInBuf

'**輸    入:無

'**輸    出:無

'**功能描述:清空輸入緩沖區

'*************************************************************************

Public Function ClearInBuf() As Long   

  If (com_Handle = INVALID_HANDLE_VALUE) Then

        ClearInBuf = 1        

Exit Function    

End If    

Call PurgeComm(com_Handle, PURGE_RXABORT Or PURGE_RXCLEAR)

    ClearInBuf = 0

End Function

'*************************************************************************

'**函 數 名:ClearOutBuf

'**輸    入:無

'**輸    出:(Long) -

'**功能描述:清空輸出緩沖區

'*************************************************************************

Public Function ClearOutBuf() As Long

    If (com_Handle = INVALID_HANDLE_VALUE) Then

        ClearOutBuf = 1

        Exit Function

    End If    

Call PurgeComm(com_Handle, PURGE_TXABORT Or PURGE_TXCLEAR)

    ClearOutBuf = 0

End Function

'*************************************************************************

'**函 數 名:SendData

'**輸    入:bytBuffer()(Byte) - 數據

'**        :lngSize(Long) - 數據長度

'**輸    出:(Long) -

'**功能描述:發送數據

'*************************************************************************

Public Function SendData(bytBuffer() As Byte, lngSize As Long) As Long

    On Error GoTo Routine_Exit                                   '打開錯誤陷阱

    Dim errNum As Long    

Dim flag As Long    

Dim i As Long   

  If (com_Handle = 0) Then

        SendData = 1

        Exit Function

    End If

    Dim dwBytesWritten As Long

    Dim bWriteStat As Long

    Dim ComStats As COMSTAT

    Dim dwErrorFlags As Long

    '    dwBytesWritten = lngSize

    Call ClearCommError(com_Handle, dwErrorFlags, ComStats)

    bWriteStat = WriteFile(com_Handle, bytBuffer(0), lngSize, dwBytesWritten, m_OverlappedWrite)     '>>正常編譯時候就這樣就可以了

    Call GetOverlappedResult(com_Handle, m_OverlappedWrite, dwBytesWritten, 1)   

'等待直到發送完畢    

'<<正常編譯時候就這樣就可以了    

'    ''>>這樣在調試狀態下可以的或在編譯為P代碼的情況下是可以正常運行    

'    If Not bWriteStat Then    

'        If GetLastError() = ERROR_IO_PENDING Then    

'            Call GetOverlappedResult(com_Handle, m_OverlappedWrite, dwBytesWritten, 1)    '等待直到發送完畢    

'        End If    

'    End If    

'    ''<<這樣在調試狀態下可以的或在編譯為P代碼的情況下是可以正常運行

    com_TxBy = com_TxBy + dwBytesWritten

    SendData = dwBytesWritten

    ClearOutBuf                                            '清除緩沖區

    ''   

'發送數據     ''   

For i = 0 To UBound(bytBuffer)     '' 

       flag = WriteFile(Com_Handle, bytBuffer(i), 1, dwBytesWritten, m_OverlappedWrite)    

''        If Not flag Then

    ''            '獲取出錯碼     '' 

           errNum = GetLastError()     ''  

          If (errNum = ERROR_IO_PENDING) Then     '' 

               flag = 0     ''

                flag = GetOverlappedResult(Com_Handle, m_OverlappedWrite, dwBytesWritten, 1)     '' 

               SendData = SendData + dwBytesWritten     '' 

               Debug.Print "errNum = ERROR_IO_PENDING"     ''

            Else     ''           

End If     ''       

End If     ''     ''        '        '間隔時間(用於需要設定每字節間間隔時間的發送協議)     ''        '                Sleep (intIntervalTime)     ''    Next

Exit Function     '----------------

Routine_Exit:

    SendData = -1

End Function

'*************************************************************************

'**函 數 名:ReadData

'**輸    入:bytBuffer()(Byte) - 讀取到的數據

'**        :Outtime(Long)     - 等待時間ms

'**輸    出:(Long) -讀取的字節數量

'**功能描述:讀取數據 '*************************************************************************

'Public Function ReadData(bytBuffer() As Byte, lngSize As Long, Optional Outtime As Long = 2000) As Long

Public Function ReadData(bytBuffer() As Byte, Optional lngSize As Long = 255, Optional Outtime As Long = 2000) As Long

    On Error GoTo Routine_Exit                                   '打開錯誤陷阱

    If (com_Handle = 0) Then

        ReadData = 0

        Exit Function

    End If

    Dim lngBytesRead As Long

    Dim fReadStat As Long

    Dim dwRes  As Long

    Dim lngErrorFlags As Long

    Dim lngStatus As Long

    Dim udtCommStat As COMSTAT

    Dim evtMask As Long

    Dim ret As Long

'        lngBytesRead = lngSize

'    清除之前的一切錯誤與獲取當前的狀態

    lngStatus = ClearCommError(com_Handle, lngErrorFlags, _             udtCommStat)

        Debug.Print "udtCommStat.cbInQue " & udtCommStat.cbInQue

'    讀數據    

If lngStatus <> 0 And udtCommStat.cbInQue > 0 And lngSize > 0 Then

        If lngSize = 255 And udtCommStat.cbInQue > 255 Then

            lngSize = udtCommStat.cbInQue

        End If

        ReDim Preserve bytBuffer(lngSize) As Byte

        fReadStat = ReadFile(com_Handle, bytBuffer(0), lngSize, lngBytesRead, m_OverlappedRead)

        com_RxBy = com_RxBy + lngBytesRead

        If fReadStat = 0 Then

            Call PurgeComm(com_Handle, PURGE_RXABORT Or PURGE_RXCLEAR Or PURGE_TXABORT Or PURGE_TXCLEAR)    '清除緩沖區

'                    lngStatus = GetLastError

'                    If lngStatus = ERROR_IO_PENDING Then

'                           Call PurgeComm(com_Handle, PURGE_RXABORT Or PURGE_RXCLEAR Or PURGE_TXABORT Or PURGE_TXCLEAR) '清除緩沖區

'                    Else

'                       

' Some other error occurred.

'                        lngBytesRead = -1

'                       

'                lngStatus = SetCommErrorEx("CommRead (ReadFile)", _

'                                                     

'                        Com_Handle)

'                        GoTo Routine_Exit

'                    End If        

End If

        ClearInBuf                                         '清除緩沖區

    End If    

ReadData = lngBytesRead

    Exit Function

Routine_Exit:

    ReadData = 0

End Function

'*************************************************************************

'**函 數 名:Class_Initialize

'*************************************************************************

Private Sub Class_Initialize()

   com_Handle = INVALID_HANDLE_VALUE

   com_RxBy = 0

   com_TxBy = 0

End Sub

'*************************************************************************

'**函 數 名:Class_Terminate

'*************************************************************************

Private Sub Class_Terminate()

    Call ClosePort

End Sub

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM