1 换一款好的 U 转串线。最好的是基于 FT232 芯片的。以前在老公司参与过读卡器 U 转串的芯片选型和测试工作。有些芯片就是会在工作中死机。2 软件死掉也可能有其他原因,最好是将软件附加上输出日志功能进行测试运行,看看究竟是什么原因致死。3 如果是每秒发送一次,就不要一直开着串口。一次通讯完成后,就释放串口。这样即便死掉,也不必重启机器。如果每次死掉还是串口被占用,至少可以说明软件是在通讯中死掉。
看LZ的代码,感觉在双重 Do Loop 循环中使用过多或者说不恰当使用Sleep函数延迟是造成LZ问题的主要原因,以下贴LZ的这部分源代码,供讨论: Private Sub Timer1_Timer() Timer1.Enabled = False Dim currentdate As Date Dim currentdate1 As Date currentdate = Now currentdate1 = currentdate Do Do If Not isStarted Then Exit Do Else Call DataSend(&H66, MSComm1) Call Sleep(t66 * 1000) Call DataSend(&H7E, MSComm1) Call Sleep(t7e * 1000) End If DoEvents Loop While Not DateDiff("s", currentdate, Now) > lLoopTime * 60 If Not isStarted Then Exit Do Else Call DataSend(&H67, MSComm1) Call Sleep(t67 * 1000) Call DataSend(&H6A, MSComm1) Call Sleep(t6a * 1000) Call DataSend(&H6C, MSComm1) Call Sleep(t6c * 1000) Call DataSend(&H67, MSComm1) Call Sleep(t67 * 1000) currentdate = Now End If DoEvents Loop While Not DateDiff("s", currentdate1, Now) > mLoopTime * 60 isStarted = False Call EndSend End Sub
按LZ目前实际大小循环发送,提供一段代码参考(可在LZ的工程中使用): Private Sub Command5_Click() MSComm1.PortOpen = True Timer2.Enabled = True Timer2.Interval = t66 * 1000 End SubPrivate Sub Form_Load() MSComm1.CommPort = port MSComm1.Settings = setting Timer2.Enabled = False End SubPrivate Sub Timer2_Timer() Static sum As Long If sum < 18 Then If sum Mod 2 = 0 Then Call DataSend(&H66, MSComm1) Timer2.Interval = t66 * 1000 Else Call DataSend(&H7E, MSComm1) Timer2.Interval = t7e * 1000 End If ElseIf sum >= 18 Then If sum = 18 Then Call DataSend(&H67, MSComm1) Timer2.Interval = t67 * 1000 ElseIf sum = 19 Then Call DataSend(&H6A, MSComm1) Timer2.Interval = t6a * 1000 ElseIf sum = 20 Then Call DataSend(&H6C, MSComm1) Timer2.Interval = t6c * 1000 ElseIf sum = 21 Then Call DataSend(&H67, MSComm1) Timer2.Interval = t67 * 1000 ElseIf sum > 21 Then Call DataSend(&H66, MSComm1) Timer2.Interval = t66 * 1000 sum = sum - 22 End If End If sum = sum + 1 End Sub
怎么通过系统时间来校正呢?zdingyun兄 Private Sub Command5_Click() MSComm1.PortOpen = True Timer2.Enabled = True Timer2.Interval = t66 * 1000 End SubPrivate Sub Form_Load() MSComm1.CommPort = port MSComm1.Settings = setting Timer2.Enabled = False End SubPrivate Sub Timer2_Timer() Static sum As Long If sum < 18 Then If sum Mod 2 = 0 Then Call DataSend(&H66, MSComm1) Timer2.Interval = t66 * 1000 Else Call DataSend(&H7E, MSComm1) Timer2.Interval = t7e * 1000 End If ElseIf sum >= 18 Then If sum = 18 Then Call DataSend(&H67, MSComm1) Timer2.Interval = t67 * 1000 ElseIf sum = 19 Then Call DataSend(&H6A, MSComm1) Timer2.Interval = t6a * 1000 ElseIf sum = 20 Then Call DataSend(&H6C, MSComm1) Timer2.Interval = t6c * 1000 ElseIf sum = 21 Then Call DataSend(&H67, MSComm1) Timer2.Interval = t67 * 1000 ElseIf sum > 21 Then Call DataSend(&H66, MSComm1) Timer2.Interval = t66 * 1000 sum = sum - 22 End If End If sum = sum + 1 End Sub
我现在最快是1秒发一组协议 还是不行啊 2秒也是一样的
这是我的一组协议 波特率是9600 数据位是8 奇偶位NONE 停止位1
建议:如果是台式机,可使用PCI插槽的串口扩展卡来获得物理的RS232口.我现在就是这样使用的.
还要注意,你的程序是否存在疏漏,手动调试有时间间隔,程序里有没有考虑到呢?或者,程序一直处于等待状态时没有释放资源(doevents)
用串口调试器调试过没有?你用串口调试器间隔1秒钟不断的发送命令,看看会不会死机,如果也死机,那么说明是你的硬件或驱动的问题,如果不死,那么就是你的程序的问题了。还有你可以从“设备管理器”中可以查阅到USB转的串口的编号最简单的判断是不是转换器的故障的方法就是将转换器的2-3短连,实现自发自收,如果不能实现,那么说明你的硬件有问题,不过,如果实现了,也不一定就没有问题。
我在自己电脑上用加个虚拟串口来接收VB(COM3)发送的数据,在调试助手(COM4)里看数据,都很正常,无论发多久,工作多长时间都没事。
但是我拿到工作电脑上用UCB转串口(COM3)就会出现死VB程序的情况。
(阿根廷巫师)----串口调试器调试过,用串口调试器间隔1秒钟不断的发送命令,不会死机(我这是在自己电脑上加个COM4,调试助手用这个COM4来接收来自VB-COM3的数据,这应该说明我程序没有问题吧,如果死机才是程序的问题吧,感觉巫师你说的不太对呢,呵呵)。
按照鼎云兄,“可使用PCI插槽的串口扩展卡来获得物理的RS232口”这是一个解决办法,怎么来扩展,以前没有用过,得请教你下,先谢谢了!
但如果是应用于工控机现场,建议买质量有保障的.
因为是自己收发消息,可能跟现场稍有区别,再看看通信协议跟程序流程有什么遗漏的地方。最好是用串口监听分析你测试的数据通信与现场有没有不一样的地方。
通信协议是什么的?ASTM吗?
另外我把源代码贴出来,大家帮我测试分析下吧,我觉得程序还是没有问题的。感谢几位了!
地址:http://download.csdn.net/source/1882122,标题是:我的测试程序,用现场USB转串口VB就无规律死机,大家帮分析下。
Do
Loop
循环中使用过多或者说不恰当使用Sleep函数延迟是造成LZ问题的主要原因,以下贴LZ的这部分源代码,供讨论:
Private Sub Timer1_Timer()
Timer1.Enabled = False
Dim currentdate As Date
Dim currentdate1 As Date
currentdate = Now
currentdate1 = currentdate
Do
Do
If Not isStarted Then
Exit Do
Else
Call DataSend(&H66, MSComm1)
Call Sleep(t66 * 1000)
Call DataSend(&H7E, MSComm1)
Call Sleep(t7e * 1000)
End If
DoEvents
Loop While Not DateDiff("s", currentdate, Now) > lLoopTime * 60
If Not isStarted Then
Exit Do
Else
Call DataSend(&H67, MSComm1)
Call Sleep(t67 * 1000)
Call DataSend(&H6A, MSComm1)
Call Sleep(t6a * 1000)
Call DataSend(&H6C, MSComm1)
Call Sleep(t6c * 1000)
Call DataSend(&H67, MSComm1)
Call Sleep(t67 * 1000)
currentdate = Now
End If
DoEvents
Loop While Not DateDiff("s", currentdate1, Now) > mLoopTime * 60
isStarted = False
Call EndSend
End Sub
Call DataSend(&H67, MSComm1)
Call Sleep(t67 * 1000)
Call DataSend(&H6A, MSComm1)
Call Sleep(t6a * 1000)我就想发 AA AA FF 05 67 00 00 00 FF 后过上t67 * 1000的时间才发送AA AA FF 05 6A 00 00 00 FF ,有其他办法实现吗?可以拿调试助手看发送的协议快慢(时间快慢在设置里面)
Private Sub Command5_Click()
MSComm1.PortOpen = True
Timer2.Enabled = True
Timer2.Interval = t66 * 1000
End SubPrivate Sub Form_Load()
MSComm1.CommPort = port
MSComm1.Settings = setting
Timer2.Enabled = False
End SubPrivate Sub Timer2_Timer()
Static sum As Long
If sum < 18 Then
If sum Mod 2 = 0 Then
Call DataSend(&H66, MSComm1)
Timer2.Interval = t66 * 1000
Else
Call DataSend(&H7E, MSComm1)
Timer2.Interval = t7e * 1000
End If
ElseIf sum >= 18 Then
If sum = 18 Then
Call DataSend(&H67, MSComm1)
Timer2.Interval = t67 * 1000
ElseIf sum = 19 Then
Call DataSend(&H6A, MSComm1)
Timer2.Interval = t6a * 1000
ElseIf sum = 20 Then
Call DataSend(&H6C, MSComm1)
Timer2.Interval = t6c * 1000
ElseIf sum = 21 Then
Call DataSend(&H67, MSComm1)
Timer2.Interval = t67 * 1000
ElseIf sum > 21 Then
Call DataSend(&H66, MSComm1)
Timer2.Interval = t66 * 1000
sum = sum - 22
End If
End If
sum = sum + 1
End Sub
我今天去中关村买了50的PCI串口卡,回来驱动装不上,郁闷,明天重新去换个,好的磨砂的要500.
我原来的USB转串口在电脑上是COM3口,我现在直接用电脑自带的 如:COM1, 来测试没有问题 。
谢谢鼎云兄、ybh37兄、of123、阿根廷巫师你们了
Timer1.Enabled = False
LZ的Timer1.Interval设置为1.
你那个我没有整出来,你帮我结合我的代码帮我修改下吧,发送的协议还是那样,可以设定时间。
按理说,lz这样写也没什么问题,sleep时,控件属性什么的会变化吗?仅仅是suspends the execution of the current thread 吧?我觉得可能还有别的什么因素~~
1秒需要设置成1000
把时间控件那的核心代码改为用 zdingyun 给我的方案也试了,也是一样的问题,有时候运行没有问题,有时候VB程序就死掉了。
我今天去换个PCI的转串口卡,昨天买的50元太次了,驱动装不上,准备买了200元的,磨砂的。
今天又去换了个几十的PCI卡,还是不行,moxa的没有现货,明天去退了这个次的,不行先买个PL340的USB转串口的试试,要是还不行的话就该去考虑下moxa的了
我这个主要是控制继电器,进而控制电磁阀用的,还控制点步进电机运动。
zdingyun兄你写的那个我试了,时间不准,与设定的时间相差比较大,没有Sleep准,用Timer2.Interval一般时间都耗的长。
我找个刚配的电脑试下啊!看看怎么样
使用Timer计时器,计时器实际时间是Interval加上Timer事件其中代码的执行时间.
可以通过系统时间来校正.
Private Sub Command5_Click()
MSComm1.PortOpen = True
Timer2.Enabled = True
Timer2.Interval = t66 * 1000
End SubPrivate Sub Form_Load()
MSComm1.CommPort = port
MSComm1.Settings = setting
Timer2.Enabled = False
End SubPrivate Sub Timer2_Timer()
Static sum As Long
If sum < 18 Then
If sum Mod 2 = 0 Then
Call DataSend(&H66, MSComm1)
Timer2.Interval = t66 * 1000
Else
Call DataSend(&H7E, MSComm1)
Timer2.Interval = t7e * 1000
End If
ElseIf sum >= 18 Then
If sum = 18 Then
Call DataSend(&H67, MSComm1)
Timer2.Interval = t67 * 1000
ElseIf sum = 19 Then
Call DataSend(&H6A, MSComm1)
Timer2.Interval = t6a * 1000
ElseIf sum = 20 Then
Call DataSend(&H6C, MSComm1)
Timer2.Interval = t6c * 1000
ElseIf sum = 21 Then
Call DataSend(&H67, MSComm1)
Timer2.Interval = t67 * 1000
ElseIf sum > 21 Then
Call DataSend(&H66, MSComm1)
Timer2.Interval = t66 * 1000
sum = sum - 22
End If
End If
sum = sum + 1
End Sub
Timer2.Interval = txx * 1000
时修改为:
Timer2.Interval = txx * 1000 - 10
来校正时间.
原来电脑上的COM1能用 我只是把9-9的线接错了 应该是2-2,3-3,我搞成2-3,3-2了
问题就到这了,该结贴啦!呵呵 。
谢谢ybh37兄、of123、阿根廷巫师、鼎云兄这3天来一直关注。
如果还有死机的情况发生,再请教你们吧!非常感谢!
我只是把9-9的线接错了 应该是2-2,3-3,我搞成2-3,3-2了