标题:debug.print的疑惑
只看楼主
东海一鱼
Rank: 13Rank: 13Rank: 13Rank: 13
等 级:贵宾
威 望:48
帖 子:757
专家分:4760
注 册:2009-8-10
得分:0 
感觉确实如风吹过所说:

因为VB程序好像很少使用线程,界面UI又是最忌讳失去响应的。所以MSCOMM控件的函数都是非阻塞的。
Do While Len(tmp) < 6
     tmp = tmp + Comm.Input
    ' Debug.Print "tmp="; tmp       //这里相当于一个阻塞,不过时间非常短。
     n = n + 1
     If n >= 3000 Then
        Comm.PortOpen = False
       Exit Function
     End If
   Debug.Print
  Loop

调试时的debug.print函数相当于给了一个人工阻塞,于是串口IO有了缓冲的机会。建议可以用sleep(X)试试,用它的原因是延时可调,
不像DoEvents可能不能达到debug.print的延时效果。不过最终解决还是建议用事件方式比较好些。



举世而誉之而不加劝,举世而非之而不加沮,定乎内外之分,辩乎荣辱之境,斯已矣。彼其于世未数数然也。
2010-08-11 22:46
风吹过b
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:364
帖 子:4912
专家分:29900
注 册:2008-10-15
得分:0 
用  sleep(X) 是个好主意。

DoEvents  如用于让程序大量循环执行时,还可以响应界面的点击时,
还有就是 需要非常短暂的暂停一下,短暂到人基本看不出来,用于减轻CPU 的压力。
如一个程序一个循环时,CPU占用率 100%,这时系统什么反应都比较慢。在 每个循环中加条这个命令
会让系统的响应速度明显有提升,虽然CPU占用率还是100%,但程序却会动态占用CPU,而不是强制占最大值。

凡是与外设通讯,都建议使用事件驱动。WINDOWS的事件驱动是系统的核心,为什么不用。

----------------------
这句我觉有问题。
     If n >= 3000 Then
        Comm.PortOpen = False
       Exit Function
     End If
3000 次循环是很快的,这里,你可以用一个定时器的变量来控制时间。如3秒种的超时间

Public Ctime As Long       '这行定义是在所有过程外定义的 ,超时计时


Ctime = 0                   '设置开始时间为0
Timer1.Interval = 100       '0.1秒一次触发
Timer1.Enabled = True       '开启定时器
Do While Len(tmp) < 6
     tmp = tmp + Comm.Input
    ' Debug.Print "tmp="; tmp       '//这里相当于一个阻塞,不过时间非常短。
     DoEvents                    '放CPU
     'n = n + 1
     If Ctime > 30 Then     '当3秒后,退出循环
     'If n >= 3000 Then
        Comm.PortOpen = False
       Timer1.Enabled = False
       Exit Function
     End If
   'Debug.Print
Loop

Private Sub Timer1_Timer()
   Ctime = Ctime + 1
End Sub

授人于鱼,不如授人于渔
早已停用QQ了
2010-08-12 10:27
风吹过b
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:364
帖 子:4912
专家分:29900
注 册:2008-10-15
得分:0 
这是直接计算来判断是否超时的。

n=timer                         'n 为当前时间。起始时间
Do While Len(tmp) < 6
     tmp = tmp + Comm.Input
    ' Debug.Print "tmp="; tmp       '//这里相当于一个阻塞,不过时间非常短。
     DoEvents                    '放CPU
     'n = n + 1
     If timer- n >= 3 Then            '当前时间 - 起始时间 > 3秒
        Comm.PortOpen = False
        Exit Function
     End If
   'Debug.Print
Loop

授人于鱼,不如授人于渔
早已停用QQ了
2010-08-12 10:29
东海一鱼
Rank: 13Rank: 13Rank: 13Rank: 13
等 级:贵宾
威 望:48
帖 子:757
专家分:4760
注 册:2009-8-10
得分:0 
以下是引用风吹过b在2010-8-12 10:29:42的发言:

这是直接计算来判断是否超时的。

n=timer                         'n 为当前时间。起始时间
Do While Len(tmp) < 6
     tmp = tmp + Comm.Input
    ' Debug.Print "tmp="; tmp       '//这里相当于一个阻塞,不过时间非常短。
     DoEvents                    '放CPU
     'n = n + 1
     If timer- n >= 3 Then            '当前时间 - 起始时间 > 3秒
        Comm.PortOpen = False
        Exit Function
     End If
   'Debug.Print
Loop
   在tmp = tmp + Comm.Input前,若能加一个检测输入缓冲区检测的语句就更好了。

  我瞎说的啊,不懂VB。


举世而誉之而不加劝,举世而非之而不加沮,定乎内外之分,辩乎荣辱之境,斯已矣。彼其于世未数数然也。
2010-08-12 12:12
风吹过b
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:364
帖 子:4912
专家分:29900
注 册:2008-10-15
得分:0 
我没用过 MSCOMM 这个控件,所以,对它也不了解.
不记得有没有检测.

它这段代码是不管有没有内容,直接读一下,然后把读到的内容(可能有,也可能为空)连接起来.
如果长度达到了 6 ,那么就说明读到了数据.
使用的是 死读的办法.

VB里推荐的二种办法就是 死读 和 事件驱动.
只是他死读的时间太短,只读 3000 次.而不是按秒来算的.他的电脑相对来说,比较快,总是在 3000次循环中无法完全读出数据来.
而添加了 debug.print 后,会大大增加 读的时间,所以能读出来.



授人于鱼,不如授人于渔
早已停用QQ了
2010-08-12 16:19
bczgvip
Rank: 14Rank: 14Rank: 14Rank: 14
等 级:贵宾
威 望:66
帖 子:1310
专家分:5312
注 册:2009-2-26
得分:0 
'添加上这段代码调试看看吧!
Private Sub MSComm1_OnComm ()
   debug.print "MSComm_OnComm: ";
   Select Case
   ' Handle each event or error by placing
   ' code below each case statement

   ' Errors
      Case comEventBreak   ' A Break was received.
      Case comEventFrame   ' Framing Error
      Case comEventOverrun   ' Data Lost.
      Case comEventRxOver   ' Receive buffer overflow.
      Case comEventRxParity   ' Parity Error.
      Case comEventTxFull   ' Transmit buffer full.
      Case comEventDCB   ' Unexpected error retrieving DCB]

   ' Events
      Case comEvCD   ' Change in the CD line.
      Case comEvCTS   ' Change in the CTS line.
      Case comEvDSR   ' Change in the DSR line.
      Case comEvRing   ' Change in the Ring Indicator.
      Case comEvReceive   ' Received RThreshold # of
                        ' chars.
      Case comEvSend   ' There are SThreshold number of
                     ' characters in the transmit
                     ' buffer.
      Case comEvEof   ' An EOF charater was found in
                     ' the input stream
   End Select
End Sub
2010-08-13 11:52
tanyk
Rank: 1
等 级:新手上路
帖 子:13
专家分:0
注 册:2009-8-28
得分:0 
程序代码:
Public Function Byte_Read(Comm As MSComm, sAddr As String) As String
  Dim STX As String
  Dim Cmd As String
  Dim Addr As String
  Dim ByteNum As String
  Dim ETX As String
  Dim CheckString As String
  Dim CheckSum As String
  Dim CmdCode As String
  Dim Sum As Integer
  Dim n As Integer

    Dim delay_time As Double
    Dim delay_start As Double
    Dim delay_chk As Double
  Dim tmp As String

 
  STX = Chr(2)
  Cmd = "0"
  Addr = UCase(sAddr)
  ByteNum = "03"
  ETX = Chr(3)

 
  CheckString = Cmd + Addr + ByteNum + ETX
  For n = 1 To Len(CheckString)
    Sum = Sum + Asc(Mid$(CheckString, n, 1))
  Next n
  CheckSum = Right$(Hex(Sum), 2)

  CmdCode = STX + Cmd + Addr + ByteNum + ETX + CheckSum
  Comm.PortOpen = True
  Comm.Output = CmdCode
'DoEvents
'Debug.Print "CMDCODE="; CmdCode


 ' Do While Len(tmp) < 6
    ' tmp = tmp + Comm.Input
    ' Debug.Print "tmp="; Comm.Input
    ' n = n + 1
     'If n >= 100 Then
       ' Comm.PortOpen = False
       'Exit Function
     'End If
   'Debug.Print
    'DoEvents
 ' Loop


 delay_time = 0.1
    delay_start = Timer
    Do
        delay_chk = delay_start + delay_time
    Loop Until Timer > delay_chk

     tmp = Comm.Input
  tmp = Mid$(tmp, 6, 2) + Mid$(tmp, 4, 2) + Mid$(tmp, 2, 2)

  Byte_Read = Hex2Bin(tmp)

  Comm.PortOpen = False
End Function


各位大虾: 谢谢你们的帮忙;
          近日XD在一本台湾的书上看到了一些例子,后将代码修改后,测试运行速度快了很多,运转也正常;
           但XD还是想不通为何旧程度里要用debug.print才能运行,谢谢


[ 本帖最后由 tanyk 于 2010-8-14 09:46 编辑 ]
2010-08-14 09:43
风吹过b
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:364
帖 子:4912
专家分:29900
注 册:2008-10-15
得分:0 
原程序是读 3000 次循环,以前的电脑速度比较慢,在3000次循环中,能读到数据。

现在的电脑速度比较快,光3000次循环是不能读到数据了,或者读不全。
而 debug.print 在循环中执行,除下显示 内容外,还起到了一个延时作用,但实际读 取时间不止3000个循环,
从而导致数据能读到。
 
去掉这句,及编译成 EXE 后不会执行 debug ,都会不会产生这额外的 延时作用,导致就读不到数据 了。


授人于鱼,不如授人于渔
早已停用QQ了
2010-08-14 14:42
tanyk
Rank: 1
等 级:新手上路
帖 子:13
专家分:0
注 册:2009-8-28
得分:0 
回复 18楼 风吹过b
谢谢
2010-08-14 15:18
中国火炬
Rank: 1
等 级:新手上路
威 望:1
帖 子:13
专家分:0
注 册:2010-8-8
得分:0 
Private Sub Timer1_Timer()
Timer1.Enabled = False
.
.
.
Timer1.Enabled = True
End Sub

试试
2010-08-14 17:25



参与讨论请移步原网站贴子:https://bbs.bccn.net/thread-315239-1-1.html




关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.288060 second(s), 8 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved