解决方案 »

  1.   

    不行的,因为我的串口是USB虚拟的,我一拔掉USB,这个串口就没了,然后再插上后,上位机发送就会很卡,并且下位机也没反应,明显是没收到数据,并且我点关掉串口后再打开串口也不行,必须要在关掉串口后下位机重新上电才能识别。所以我现在就想在以拔掉USB,就关掉当前打开的这个虚拟串口。
      

  2.   

    以前电脑带2个COM口,通信时拔掉通信线,再连通也无法再通信,需要重新启动才能恢复。
      

  3.   

    我现在想做的就是一个打开串口按钮,在打开选中的串口后,按钮就显示“关闭串口”,在USB被拔掉后出该串口关闭,并且按键的Caption也变为“打开串口”,如果是发完一次就关闭,再发再打开的话那这个打开和关闭串口的按钮不一直在跳变吗,我看到别人做的一个软件就是在拔掉USB后才关闭,按钮的catpion才跟着变,应该不是您的这个思路,他这个是怎么做到的呢?
      

  4.   

    嗯,我现在是USB虚拟的串口,如果不这么做的话也得重新启动才能恢复
      

  5.   


    usb串口应该比系统串口检测会容易些,你可以系统中检测WM_DEVICECHANGE
    消息,然后做处理
      

  6.   

    我现在想做的就是一个打开串口按钮,在打开选中的串口后,按钮就显示“关闭串口”,在USB被拔掉后出该串口关闭,并且按键的Caption也变为“打开串口”,如果是发完一次就关闭,再发再打开的话那这个打开和关闭串口的按钮不一直在跳变吗,我看到别人做的一个软件就是在拔掉USB后才关闭,按钮的catpion才跟着变,应该不是您的这个思路,他这个是怎么做到的呢?监视一下注册表吧
    HKEY_LOCAL_MACHINE\HARDWARE\DEVICEMAP\SERIALCOMM 下注册了可用的串口,USB串口一拿掉,对应的串口就删掉了,检测不到对应的串口,你就可以关掉串口了。
      

  7.   

    我现在想做的就是一个打开串口按钮,在打开选中的串口后,按钮就显示“关闭串口”,在USB被拔掉后出该串口关闭,并且按键的Caption也变为“打开串口”,如果是发完一次就关闭,再发再打开的话那这个打开和关闭串口的按钮不一直在跳变吗,我看到别人做的一个软件就是在拔掉USB后才关闭,按钮的catpion才跟着变,应该不是您的这个思路,他这个是怎么做到的呢?监视一下注册表吧
    HKEY_LOCAL_MACHINE\HARDWARE\DEVICEMAP\SERIALCOMM 下注册了可用的串口,USB串口一拿掉,对应的串口就删掉了,检测不到对应的串口,你就可以关掉串口了。我现在想做的就是一个打开串口按钮,在打开选中的串口后,按钮就显示“关闭串口”,在USB被拔掉后出该串口关闭,并且按键的Caption也变为“打开串口”,如果是发完一次就关闭,再发再打开的话那这个打开和关闭串口的按钮不一直在跳变吗,我看到别人做的一个软件就是在拔掉USB后才关闭,按钮的catpion才跟着变,应该不是您的这个思路,他这个是怎么做到的呢?监视一下注册表吧
    HKEY_LOCAL_MACHINE\HARDWARE\DEVICEMAP\SERIALCOMM 下注册了可用的串口,USB串口一拿掉,对应的串口就删掉了,检测不到对应的串口,你就可以关掉串口了。
    不行的,我一开始枚举串口的时候就是读的注册表,我试了,即便拔掉之后注册表里还在的,必须等出VB里把打开的这个串口关掉后它才会消失,不关掉的话注册表里一直显示那个串口是存在的
      

  8.   


    usb串口应该比系统串口检测会容易些,你可以系统中检测WM_DEVICECHANGE
    消息,然后做处理
    能详细描述一下您的方法吗,我不太懂啊
      

  9.   

    比较土的一个办法,不过测试了一下确实可行
    用mscomm控件去打开你占用的这个串口,如果串口存在,错误号是8005,如果拔掉了,错误号就变成8002了
      

  10.   

    怪了,我可以的,Arduino 试过我才发的
      

  11.   

    我这边亲测真不行的。。我的串口是用STM32的USB虚拟的,拔掉后我再发送数据上位机会很卡,执行再打开串口代码错误号也还是8005
      

  12.   

    Private Sub MSComm_OnComm()
        Select Case MSComm1.CommEvent
            Case comEventBreak   ' 收到 Break。
            Case comEventCDTO   ' CD (RLSD) 超时。
            Case comEventCTSTO   ' CTS Timeout。
            Case comEventDSRTO   ' DSR Timeout。
            Case comEventFrame   ' Framing Error
            Case comEventOverrun   '数据丢失。
            Case comEventRxParity ' Parity 错误。
            Case comEventTxFull   '传输缓冲区已满。
            Case comEventDCB   '获取 DCB] 时意外错误事件
            Case comEvCD   ' CD 线状态变化。
            Case comEvCTS   ' CTS 线状态变化。
            Case comEvDSR   ' DSR 线状态变化。
            Case comEvRing   ' Ring Indicator 变化。
            Case comEvReceive   ' 收到 RThreshold # of chars.
            Case comEvSend   ' 传输缓冲区有 Sthreshold 个字符                     '
            Case comEvEOF   ' 输入数据流中发现 EOF 字符
        End Select
    End Sub建议LZ从涉及Case comEventTxFull   '传输缓冲区已满。
    或者Case comEvSend   ' 传输缓冲区有 Sthreshold 个字符
    等OnComm事件考虑USB的COM口被拔除。
      

  13.   

    我的程序只有发送事件,不接收任何数据的,所以OnComm不行吧
      

  14.   


    Case comEventTxFull   '传输缓冲区已满。似乎更能反映LZ拔除USB出现情况。或者几个线变化来考虑解决问题。这些都要实践证实。
      

  15.   

    串口打开的时候进行拔插会出现了8021错误
    If Err.Number = 8021 Then
    MsgBox "端口检索设备错误!", vbOKOnly + vbExclamation, "提示"
       MSComm1.PortOpen = False
    exit sub
    end if详细参阅:http://bbs.csdn.net/topics/360133044
      

  16.   


    这些建议都需要实验证实,只有发送数据就与传输缓冲区有关,当然与传输缓冲区已满那事件有关。我只是建议,解决问题要靠LZ自己。
    谢谢您的热心回答,我在oncomm里这么检测了,在拔掉USB后还是没动静。。
      

  17.   

    楼主用的什么线?
    是纯粹的USB线虚拟的串口还是用的USB转串口线?
    我用力特的USB转串口线试了一下,监视一下注册表HKEY_LOCAL_MACHINE\HARDWARE\DEVICEMAP\SERIALCOMM绝对是可行的。
      

  18.   

    我这边亲测真不行的。。我的串口是用STM32的USB虚拟的,拔掉后我再发送数据上位机会很卡,执行再打开串口代码错误号也还是8005
    你拔掉的是串口线,不是USB线是吧?
      

  19.   

    我用的是USB虚拟的串口,不是转的。。我虚拟的串口拔掉USB后只有关掉串口注册表才会显示没有,不然刷新后还在的。
      

  20.   

    我这边亲测真不行的。。我的串口是用STM32的USB虚拟的,拔掉后我再发送数据上位机会很卡,执行再打开串口代码错误号也还是8005
    你拔掉的是串口线,不是USB线是吧?
    我把掉的是USB线。。不是串口。。因为我说我的串口是用USB虚拟出来的,也不是USB转串口,就是这里的串口9,我插上USB后,设备里会出现这个虚拟串口,拔掉USB后串口消失
      

  21.   


    我用这个8021 错误成功的检测并处理拔USB 头的问题,是在检测InbufCount 时产生异常的。你接收数据的代码可能有问题。
      

  22.   

    用 U 转串倒好办了。只要监控 OnDeviceChange 消息。
      

  23.   


    我用这个8021 错误成功的检测并处理拔USB 头的问题,是在检测InbufCount 时产生异常的。你接收数据的代码可能有问题。
    啊,那能共享一下您的这段接收代码吗,我学习一下
      

  24.   


    我用这个8021 错误成功的检测并处理拔USB 头的问题,是在检测InbufCount 时产生异常的。你接收数据的代码可能有问题。
    啊,那能共享一下您的这段接收代码吗,我学习一下原始代码混在工程逻辑里,更显得麻烦。你付费我可以代你做。
      

  25.   


    我用这个8021 错误成功的检测并处理拔USB 头的问题,是在检测InbufCount 时产生异常的。你接收数据的代码可能有问题。
    啊,那能共享一下您的这段接收代码吗,我学习一下原始代码混在工程逻辑里,更显得麻烦。你付费我可以代你做。
    啊。代做倒不用了。。您要能解决这个问题就感激不尽了。。现在我的程序还没有任何接收数据,就是我只负责在按键按下的时候发送数据,平时什么都不做,不需要接收数据的,所以您说的接收代码可能有问题有待商榷
      

  26.   

    不接收就检测 OutBufferCount .实在搞不定再联系我。
      

  27.   


    串口不是即插即用设备,你这样的需求就有点离谱。按理说,串口线是不允许热插拔的。即使是 U 转串,也必须是拔掉 U 口端才能用系统消息来感知(USB 是即插即用)。所以,你的需求可能要在主机和设备端建立应答机制。主机向设备发送查询命令,设备返回一个状态。主机端可以利用 Timer 定时查询。因为串口的超时需要很久,可以用 Timer 在发出查询命令后计时处理。这样的方式可以适合各种串口。
      

  28.   

    我们现在的通讯就是这样实现的,设备关闭,打开均可以实现通讯,不关闭软件绝对没问题。嗯,API里面是这样搞很安逸。
      

  29.   


    Public Class 通讯
    Friend m串口 As New System.IO.Ports.SerialPort
    Public Property 连接() As Boolean
     Get
        Return m串口.IsOpen
     Set(ByVal value As Boolean)
    If value Then
     If m串口.IsOpen = False Then
        Try
          m串口.Open()
        Catch ex As Exception
                                   
        End Try
      End If
      Else
         m串口.Close()
    End If
    End Class
      

  30.   

    你需要清理的是,对串口设备操作的层面问题。1 所谓打开和关闭串口,实际上是对 PC 端控件的操作。只要本机该端口存在且没有打开,就可以无错误地打开串口。2 当 PC 端发送数据时,本机硬件会改变接口上 TXD 脚的电平。无论是否真有线路连接,都不会出错。3 当 PC 端接收数据时,如果你的代码是定长循环的,且线路断开或外部设备没有正确回应,则会停留在循环中。因此,你的解决之道至少有两种:1 在你的循环中加入超时处理(可以借助 Timer)。2 如果你的架构是通过中断方式接收(而不是发送代码中的死循环接收),且通过设置公共变量标志来确定成功接收到最后发送的数据的应答。则可以在发送持续中,显示一个 Reset 按钮。如果长时间没有得到应答,按此按钮,将公共变量恢复为允许发送的状态。
      

  31.   

    有2个解决方案
    1,是监视WM_DEVICECHANGE消息 然后枚举硬件设备看看你的虚拟usb串口是否还在
    2,是每次需要用的时候才打开串口发消息 发完后关闭串口
      

  32.   

    请问楼主你解决了吗?我现在也遇到这个问题,串口本来在正常工作,现在假设突然拔出串口,本来想通过注册表中的COM口列表来判断,可是拔出后那个口还存在,只有关掉程序才会消失。所以现在不知道怎么处理,拔掉的话这个COM口居然一直是打开着的,还不能关掉它(会提示这个COM口不存在),真是郁闷啊