VB的MSCOMM控件虽然很好用,但是在没有装VB的机器上用该控件总觉得有些累赘,网上的VB API代码大部分都基于是同步方式,处理复杂的通信模式不是太理想,所以用了一些时间,把VC项目中的异步串口读写代码翻译为VB格式。

在VB新建一个类,把下面的代码复制后即可使用

'*************************************************************************
'**模 块 名:SerialPort
'**说    明:YFsoft 版权所有2006 - 2007(C)
'**创 建 人:叶帆
'**日    期:2006-08-17 14:32:29
'**修 改 人:
'**日    期:
'**描    述:串口异步读写(API)
'**版    本:V1.0.0
'*************************************************************************
Option Explicit

Private Type ComStat
    fCtsHold As Long
    fDsrHold As Long
    fRlsdHold As Long
    fXoffHold As Long
    fXoffSent As Long
    fEof As Long
    fTxim As Long
    fReserved As Long
    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
    'DWORD DCBlength;      /* sizeof(DCB)                     */
    'DWORD BaudRate;       /* Baudrate at which running       */
    'DWORD fBinary: 1;     /* Binary Mode (skip EOF check)    */
    'DWORD fParity: 1;     /* Enable parity checking          */
    'DWORD fOutxCtsFlow:1; /* CTS handshaking on output       */
    'DWORD fOutxDsrFlow:1; /* DSR handshaking on output       */
    'DWORD fDtrControl:2;  /* DTR Flow control                */
    'DWORD fDsrSensitivity:1; /* DSR Sensitivity              */
    'DWORD fTXContinueOnXoff: 1; /* Continue TX when Xoff sent */
    'DWORD fOutX: 1;       /* Enable output X-ON/X-OFF        */
    'DWORD fInX: 1;        /* Enable input X-ON/X-OFF         */
    'DWORD fErrorChar: 1;  /* Enable Err Replacement          */
    'DWORD fNull: 1;       /* Enable Null stripping           */
    'DWORD fRtsControl:2;  /* Rts Flow control                */
    'DWORD fAbortOnError:1; /* Abort all reads and writes on Error */
    'DWORD fDummy2:17;      /* Reserved                        */
    fBitFields As Long 'See Comments in Win32API.Txt
    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 'Reserved; Do Not Use
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

Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject 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 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 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 GetOverlappedResult Lib "kernel32" (ByVal hFile As Long, lpOverlapped As OVERLAPPED, lpNumberOfBytesTransferred As Long, ByVal bWait As Long) As Long
Private Declare Function WaitForSingleObject Lib "kernel32" (ByVal hHandle As Long, ByVal dwMilliseconds 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 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&

Private m_Handle As Long
Private m_OverlappedRead As OVERLAPPED
Private m_OverlappedWrite As OVERLAPPED

'*************************************************************************
'**函 数 名:OpenPort
'**输    入:ComNumber(Long)     - 串口号
'**        :Comsettings(String) - 配置信息
'**输    出:(Long) - 0 成功 非 0 失败
'**功能描述:打开串口
'**全局变量:
'**调用模块:
'**作    者:叶帆
'**日    期:2006-08-17 14:40:14
'**修 改 人:
'**日    期:
'**版    本:V1.0.0
'*************************************************************************
Public Function OpenPort(ComNumber As Long, Comsettings As String, Optional lngInSize As Long = 1024, Optional lngOutSize As Long = 512) As Long
    On Error GoTo handelinitcom
    Dim retval As Long
    Dim CtimeOut As COMMTIMEOUTS, dcbs As DCB
    Dim strCOM As String, strConfig As String

strCOM = "\.COM" & Format(ComNumber, "0")
    m_Handle = CreateFile(strCOM, GENERIC_READ Or GENERIC_WRITE, 0, 0&, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL Or FILE_FLAG_OVERLAPPED, 0)
    If m_Handle = -1 Then
        OpenPort = -1
        Exit Function
    End If

'设置dcb块
    dcbs.DCBlength = Len(dcbs)                           '长度
    Call GetCommState(m_Handle, dcbs)

'波特率,奇偶校验,数据位,停止位  如:9600,n,8,1
    strConfig = "COM" & Format(ComNumber, "0") & ":" & Comsettings
    Call BuildCommDCB(strConfig, dcbs)

'------------------------------
    '    dcbs.fBinary = 1                          '二进制方式
    '    dcbs.fOutxCtsFlow = 0                     '不用CTS检测发送流控制
    '    dcbs.fOutxDsrFlow = 0                     '不用DSR检测发送流控制
    '    dcbs.fDtrControl = DTR_CONTROL_DISABLE    '禁止DTR流量控制
    '    dcbs.fDsrSensitivity = 0                  '对DTR信号线不敏感
    '    dcbs.fTXContinueOnXoff = 1                '检测接收缓冲区
    '    dcbs.fOutX = 0                            '不做发送字符控制
    '    dcbs.fInX = 0                             '不做接收控制
    '    dcbs.fErrorChar = 0                       '是否用指定字符替换校验错的字符
    '    dcbs.fNull = 0                            '保留NULL字符
    '    dcbs.fRtsControl = RTS_CONTROL_ENABLE     '允许RTS流量控制
    '    dcbs.fAbortOnError = 0                    '发送错误后,继续进行下面的读写操作
    '    dcbs.fDummy2 = 0                          '保留
    dcbs.fBitFields = 1 * 2 ^ 0 Or DTR_CONTROL_DISABLE * 2 ^ 4 Or 1 * 2 ^ 7 Or RTS_CONTROL_ENABLE * 2 ^ 12

dcbs.wReserved = 0                        '没有使用,必须为0
    dcbs.XonLim = 0                           '指定在XOFF字符发送之前接收到缓冲区中可允许的最小字节数
    dcbs.XoffLim = 0                          '指定在XOFF字符发送之前缓冲区中可允许的最小可用字节数
    dcbs.XonChar = 0                          '发送和接收的XON字符
    dcbs.XoffChar = 0                         '发送和接收的XOFF字符
    dcbs.ErrorChar = 0                        '代替接收到奇偶校验错误的字符
    dcbs.EofChar = 0                          '用来表示数据的结束
    dcbs.EvtChar = 0                          '事件字符,接收到此字符时,会产生一个事件
    'dcbs.wReserved1 = 0                      '没有使用
    'dcbs.BaudRate =9600                      '波特率
    'dcbs.Parity=0                            '奇偶校验
    'dcbs.ByteSize=8                          '数据位
    'dcbs.StopBits=0                          '停止位
    '------------------------------

If dcbs.Parity = 0 Then                   ' 0-4=None,Odd,Even,Mark,Space
        dcbs.fBitFields = dcbs.fBitFields And &HFFFD     'dcbs.fParity = 0                      '奇偶校验无效
    Else
        dcbs.fBitFields = dcbs.fBitFields Or &H2         'dcbs.fParity = 1                      '奇偶校验有效
    End If

'超时设置
    CtimeOut.ReadIntervalTimeout = 20                  '0
    CtimeOut.ReadTotalTimeoutConstant = 1              '2500
    CtimeOut.ReadTotalTimeoutMultiplier = 1            '0
    CtimeOut.WriteTotalTimeoutConstant = 10            '2500
    CtimeOut.WriteTotalTimeoutMultiplier = 1           '0
   
    retval = SetCommTimeouts(m_Handle, CtimeOut)

If retval = -1 Then
        retval = GetLastError()
        OpenPort = retval
        retval = CloseHandle(m_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 SetCommState(m_Handle, dcbs) = -1 Or SetupComm(m_Handle, lngInSize, lngOutSize) = -1 Or 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(m_Handle)
        m_Handle = 0
        Exit Function
    End If

OpenPort = 0
    Exit Function
handelinitcom:
    Call CloseHandle(m_Handle)
    m_Handle = 0
    OpenPort = -2
    Exit Function
End Function

'*************************************************************************
'**函 数 名:ClosePort
'**输    入:无
'**输    出:(Long) - 0 成功 -1 失败
'**功能描述:关闭串口
'**全局变量:
'**调用模块:
'**作    者:叶帆
'**日    期:2006-08-17 14:56:13
'**修 改 人:
'**日    期:
'**版    本:V1.0.0
'*************************************************************************
Public Function ClosePort() As Long
    If (m_Handle = 0) Then
        ClosePort = 1
        Exit Function
    End If

Call SetCommMask(m_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(m_Handle) <> 0 Then
        ClosePort = 0
    Else
        ClosePort = -1
    End If

m_Handle = 0
End Function

'*************************************************************************
'**函 数 名:ClearInBuf
'**输    入:无
'**输    出:无
'**功能描述:清空输入缓冲区
'**全局变量:
'**调用模块:
'**作    者:叶帆
'**日    期:2006-08-17 14:57:26
'**修 改 人:
'**日    期:
'**版    本:V1.0.0
'*************************************************************************
Public Function ClearInBuf() As Long
    If (m_Handle = 0) Then
        ClearInBuf = 1
        Exit Function
    End If
    Call PurgeComm(m_Handle, PURGE_RXABORT Or PURGE_RXCLEAR)
    ClearInBuf = 0
End Function

'*************************************************************************
'**函 数 名:ClearOutBuf
'**输    入:无
'**输    出:(Long) -
'**功能描述:清空输出缓冲区
'**全局变量:
'**调用模块:
'**作    者:叶帆
'**日    期:2006-08-17 15:40:38
'**修 改 人:
'**日    期:
'**版    本:V1.0.0
'*************************************************************************
Public Function ClearOutBuf() As Long
    If (m_Handle = 0) Then
        ClearOutBuf = 1
        Exit Function
    End If
    Call PurgeComm(m_Handle, PURGE_TXABORT Or PURGE_TXCLEAR)
    ClearOutBuf = 0
End Function

'*************************************************************************
'**函 数 名:SendData
'**输    入:bytBuffer()(Byte) - 数据
'**        :lngSize(Long)     - 数据长度
'**输    出:(Long) -
'**功能描述:发送数据
'**全局变量:
'**调用模块:
'**作    者:叶帆
'**日    期:2006-08-17 15:43:42
'**修 改 人:
'**日    期:
'**版    本:V1.0.0
'*************************************************************************
Public Function SendData(bytBuffer() As Byte, lngSize As Long) As Long
    On Error GoTo ToExit '打开错误陷阱
    '------------------------------------------------
    If (m_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(m_Handle, dwErrorFlags, ComStats)
    bWriteStat = WriteFile(m_Handle, bytBuffer(0), lngSize, dwBytesWritten, m_OverlappedWrite)

If bWriteStat = 0 Then
        If GetLastError() = ERROR_IO_PENDING Then
            Call GetOverlappedResult(m_Handle, m_OverlappedWrite, dwBytesWritten, 1)                   '等待直到发送完毕
        End If
    Else
        dwBytesWritten = 0
    End If

SendData = dwBytesWritten
    '------------------------------------------------
    Exit Function
    '----------------
ToExit:
    SendData = -1
End Function

'*************************************************************************
'**函 数 名:ReadData
'**输    入:bytBuffer()(Byte) - 数据
'**        :lngSize(Long)     - 数据长度
'**输    出:(Long) -
'**功能描述:读取数据
'**全局变量:
'**调用模块:
'**作    者:叶帆
'**日    期:2006-08-17 16:04:38
'**修 改 人:
'**日    期:
'**版    本:V1.0.0
'*************************************************************************
Public Function ReadData(bytBuffer() As Byte, lngSize As Long, Optional Overtime As Long = 3000) As Long
    On Error GoTo ToExit '打开错误陷阱
    '------------------------------------------------
    If (m_Handle = 0) Then
        ReadData = 1
        Exit Function
    End If

Dim lngBytesRead As Long
    Dim fReadStat As Long
    Dim dwRes  As Long

lngBytesRead = lngSize

'读数据
    fReadStat = ReadFile(m_Handle, bytBuffer(0), lngSize, lngBytesRead, m_OverlappedRead)
    If fReadStat = 0 Then
        If GetLastError() = ERROR_IO_PENDING Then                           '重叠 I/O 操作在进行中
            dwRes = WaitForSingleObject(m_OverlappedRead.hEvent, Overtime)  '等待,直到超时
            Select Case dwRes
            Case WAIT_OBJECT_0:   '读完成
                If GetOverlappedResult(m_Handle, m_OverlappedRead, lngBytesRead, 0) = 0 Then
                    '错误
                    ReadData = -2
                    Exit Function
                End If
            Case WAIT_TIMEOUT:    '超时
                ReadData = -1
                Exit Function
            Case Else:                  'WaitForSingleObject 错误
            End Select
        End If
    End If
    ReadData = lngBytesRead
    '------------------------------------------------
    Exit Function
    '----------------
ToExit:
    ReadData = -1
End Function

'*************************************************************************
'**函 数 名:Class_Terminate
'**输    入:无
'**输    出:无
'**功能描述:
'**全局变量:
'**调用模块:
'**作    者:叶帆
'**日    期:2006-08-17 16:36:21
'**修 改 人:
'**日    期:
'**版    本:V1.0.0
'*************************************************************************
Private Sub Class_Terminate()
    Call ClosePort
End Sub

用API实现串口异步读写相关推荐

  1. MFC win32 API串口异步模式代码示范 vs2015

    MFC win32 API串口异步模式代码示范   vs2015 本程序为单步接收,即点击接收按钮,才能收到消息. 实时循环接收需要添加线程 参考实例: https://blog.csdn.net/t ...

  2. win32 API 开发串口 参考资料

    win32 API  开发串口 参考资料                                                                                 ...

  3. linux下aio异步读写详解与实例

    1.为什么会有异步I/O aio异步读写是在linux内核2.6之后才正式纳入其标准.之所以会增加此模块,是因为众所周知我们计算机CPU的执行速度远大于I/O读写的执行速度,如果我们用传统的阻塞式或非 ...

  4. java 异步读写_Java异步与AIO

    异步编程提供了一个非阻塞的,事件驱动的编程模型. 这种编程模型利用系统中多核执行任务来提供并行,因此提高了应用的吞吐率.Java异步编程通常需要使用Future,FutureTask和Callable ...

  5. 磁盘文件的正常读写与异步读写

    磁盘文件的正常读写与异步读写 转自:http://222.30.226.10/hhcmc/study/teach_vc/teach_sp_52.htm 在Win32系统下文件可以支持平常的同步读写和异 ...

  6. 最近总结了串口(COM)读写操作的三种方式

    最近总结了串口(COM)读写操作的三种方式: 第1种方式是采用微软在.NET2.0推出了一个串口控件,SerialPort类,但必须是.NET2.0才可以 第2种方式是用API写串口通信,虽然难度高, ...

  7. boost::asio向socket中异步读写数据

    内容代码参考自: Boost.Asio C++ Network Programming Cookbook 异步写入数据的核心是异步回调函数. 在此之前, 必须弄明白异步IO的基本概念和回调函数触发的时 ...

  8. 串口编程之一: WIN32 API 中串口DCB 结构的介绍

    在应用WIN32  API 对串口进行编程时, 必定会使用到DCB 结构. 下面的DCB 结构的一些介绍. 首先是DCB 结构. typedef struct _DCB {           DWO ...

  9. 【FPGA】双端口RAM的设计(异步读写)

    上篇写了双端口RAM设计(同步读写):https://blog.csdn.net/Reborn_Lee/article/details/90647784 关于异步读写和同步读写,在单端口RAM设计中也 ...

最新文章

  1. 2021广西高考成绩几点可以查询,高考完多久分数能出来广西 2021年广西高考分数查询公布时间...
  2. EncodeUtil
  3. DevExperience(1712)
  4. 阿里云不做SaaS、要练好内功被集成,发布SaaS加速器
  5. C#LeetCode刷题之#53-最大子序和(Maximum Subarray)
  6. 阳黎盛:4.11美联储预计加息,脱欧被顺延!
  7. 现在没有可用的软件包 *** ,但是它被其它的软件包引用了 和 E: 无法定位软件包 ***问题解决(思路清晰干货)
  8. 智能手机玩转Smart3D三维建模介绍
  9. ios系统安装包下载_iOS在后台自动升级?一招教你屏蔽iOS更新
  10. Android Studio 配置Git,移动端h5页面开发教程百度云资源
  11. Linux下的MongoDB基础学习二
  12. 用JS搞了一个自动翻译,从此不再头疼看英文书了
  13. 【暖手练习】MATLAB习题
  14. 图像处理:以图像分类和图像深度估计为例,如何将研究想法进行迁移学习应用?
  15. 计算机表格基础知识训练,计算机基础知识综合练习与答案
  16. 串口驱动中使用FIFO
  17. Java实现在线聊天功能
  18. GHOST系统封装教程 系统封装工具 XP系统封装(一)
  19. Linux基础知识问题解答
  20. 妙用Spring的事务超时时间timeout

热门文章

  1. Spring MVC数据绑定和表单标签的应用(附带实例)
  2. php限制接口访问次数_令牌桶限流思路分享(PHP+Redis实现机制)
  3. vc如何使用 truetype_25岁的女性如何抗初老?
  4. jmeter 控制偏离_Jmeter(二十) - 从入门到精通 - JMeter监听器 -下篇(详解教程)
  5. 一位00后前端2年经验的成长历程
  6. 从前景、待遇、入门难度分析,Java和HTML5哪个好
  7. c++中计算2得n次方_PLC-上海会通松下PLC中的数据类型有哪些?
  8. java elasticsearch_在Spring java框架中使用ElasticSearch的最佳方式
  9. vector容器详细介绍
  10. db2数据库服务器时间怎么修改,DB2数据库中,肿么修改数据的创建时间,求SQL语句。...