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口被拔除。
我的程序只有发送事件,不接收任何数据的,所以OnComm不行吧
Case comEventTxFull '传输缓冲区已满。似乎更能反映LZ拔除USB出现情况。或者几个线变化来考虑解决问题。这些都要实践证实。
串口打开的时候进行拔插会出现了8021错误 If Err.Number = 8021 Then MsgBox "端口检索设备错误!", vbOKOnly + vbExclamation, "提示" MSComm1.PortOpen = False exit sub end if详细参阅:http://bbs.csdn.net/topics/360133044
串口不是即插即用设备,你这样的需求就有点离谱。按理说,串口线是不允许热插拔的。即使是 U 转串,也必须是拔掉 U 口端才能用系统消息来感知(USB 是即插即用)。所以,你的需求可能要在主机和设备端建立应答机制。主机向设备发送查询命令,设备返回一个状态。主机端可以利用 Timer 定时查询。因为串口的超时需要很久,可以用 Timer 在发出查询命令后计时处理。这样的方式可以适合各种串口。
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
你需要清理的是,对串口设备操作的层面问题。1 所谓打开和关闭串口,实际上是对 PC 端控件的操作。只要本机该端口存在且没有打开,就可以无错误地打开串口。2 当 PC 端发送数据时,本机硬件会改变接口上 TXD 脚的电平。无论是否真有线路连接,都不会出错。3 当 PC 端接收数据时,如果你的代码是定长循环的,且线路断开或外部设备没有正确回应,则会停留在循环中。因此,你的解决之道至少有两种:1 在你的循环中加入超时处理(可以借助 Timer)。2 如果你的架构是通过中断方式接收(而不是发送代码中的死循环接收),且通过设置公共变量标志来确定成功接收到最后发送的数据的应答。则可以在发送持续中,显示一个 Reset 按钮。如果长时间没有得到应答,按此按钮,将公共变量恢复为允许发送的状态。
usb串口应该比系统串口检测会容易些,你可以系统中检测WM_DEVICECHANGE
消息,然后做处理
HKEY_LOCAL_MACHINE\HARDWARE\DEVICEMAP\SERIALCOMM 下注册了可用的串口,USB串口一拿掉,对应的串口就删掉了,检测不到对应的串口,你就可以关掉串口了。
HKEY_LOCAL_MACHINE\HARDWARE\DEVICEMAP\SERIALCOMM 下注册了可用的串口,USB串口一拿掉,对应的串口就删掉了,检测不到对应的串口,你就可以关掉串口了。我现在想做的就是一个打开串口按钮,在打开选中的串口后,按钮就显示“关闭串口”,在USB被拔掉后出该串口关闭,并且按键的Caption也变为“打开串口”,如果是发完一次就关闭,再发再打开的话那这个打开和关闭串口的按钮不一直在跳变吗,我看到别人做的一个软件就是在拔掉USB后才关闭,按钮的catpion才跟着变,应该不是您的这个思路,他这个是怎么做到的呢?监视一下注册表吧
HKEY_LOCAL_MACHINE\HARDWARE\DEVICEMAP\SERIALCOMM 下注册了可用的串口,USB串口一拿掉,对应的串口就删掉了,检测不到对应的串口,你就可以关掉串口了。
不行的,我一开始枚举串口的时候就是读的注册表,我试了,即便拔掉之后注册表里还在的,必须等出VB里把打开的这个串口关掉后它才会消失,不关掉的话注册表里一直显示那个串口是存在的
usb串口应该比系统串口检测会容易些,你可以系统中检测WM_DEVICECHANGE
消息,然后做处理
能详细描述一下您的方法吗,我不太懂啊
用mscomm控件去打开你占用的这个串口,如果串口存在,错误号是8005,如果拔掉了,错误号就变成8002了
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口被拔除。
Case comEventTxFull '传输缓冲区已满。似乎更能反映LZ拔除USB出现情况。或者几个线变化来考虑解决问题。这些都要实践证实。
If Err.Number = 8021 Then
MsgBox "端口检索设备错误!", vbOKOnly + vbExclamation, "提示"
MSComm1.PortOpen = False
exit sub
end if详细参阅:http://bbs.csdn.net/topics/360133044
这些建议都需要实验证实,只有发送数据就与传输缓冲区有关,当然与传输缓冲区已满那事件有关。我只是建议,解决问题要靠LZ自己。
谢谢您的热心回答,我在oncomm里这么检测了,在拔掉USB后还是没动静。。
是纯粹的USB线虚拟的串口还是用的USB转串口线?
我用力特的USB转串口线试了一下,监视一下注册表HKEY_LOCAL_MACHINE\HARDWARE\DEVICEMAP\SERIALCOMM绝对是可行的。
你拔掉的是串口线,不是USB线是吧?
你拔掉的是串口线,不是USB线是吧?
我把掉的是USB线。。不是串口。。因为我说我的串口是用USB虚拟出来的,也不是USB转串口,就是这里的串口9,我插上USB后,设备里会出现这个虚拟串口,拔掉USB后串口消失
我用这个8021 错误成功的检测并处理拔USB 头的问题,是在检测InbufCount 时产生异常的。你接收数据的代码可能有问题。
我用这个8021 错误成功的检测并处理拔USB 头的问题,是在检测InbufCount 时产生异常的。你接收数据的代码可能有问题。
啊,那能共享一下您的这段接收代码吗,我学习一下
我用这个8021 错误成功的检测并处理拔USB 头的问题,是在检测InbufCount 时产生异常的。你接收数据的代码可能有问题。
啊,那能共享一下您的这段接收代码吗,我学习一下原始代码混在工程逻辑里,更显得麻烦。你付费我可以代你做。
我用这个8021 错误成功的检测并处理拔USB 头的问题,是在检测InbufCount 时产生异常的。你接收数据的代码可能有问题。
啊,那能共享一下您的这段接收代码吗,我学习一下原始代码混在工程逻辑里,更显得麻烦。你付费我可以代你做。
啊。代做倒不用了。。您要能解决这个问题就感激不尽了。。现在我的程序还没有任何接收数据,就是我只负责在按键按下的时候发送数据,平时什么都不做,不需要接收数据的,所以您说的接收代码可能有问题有待商榷
串口不是即插即用设备,你这样的需求就有点离谱。按理说,串口线是不允许热插拔的。即使是 U 转串,也必须是拔掉 U 口端才能用系统消息来感知(USB 是即插即用)。所以,你的需求可能要在主机和设备端建立应答机制。主机向设备发送查询命令,设备返回一个状态。主机端可以利用 Timer 定时查询。因为串口的超时需要很久,可以用 Timer 在发出查询命令后计时处理。这样的方式可以适合各种串口。
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
1,是监视WM_DEVICECHANGE消息 然后枚举硬件设备看看你的虚拟usb串口是否还在
2,是每次需要用的时候才打开串口发消息 发完后关闭串口