我是用VB跟Keyce LS7000测量信通信,LS7000测量一产品要求一秒钟读50个数据,能实现吗?我用的是VB的Timer设置10ms触发读取数据命令,延时10ms
但似只能读到每秒钟7个数据左右Timer并不能实现多任务工作,其它的任务可能会影响到他的延时不知道有没有办法可以实现。

解决方案 »

  1.   

    你连的传感器可以1s发送50次数据吗?用timer可以1s发送50次数据的。
      

  2.   

    10ms太短了,使用Timer上做不到的,Timer的精确度:18ms
      

  3.   

    1秒50个数据,20ms一个,是设备自动发送吧。接收后1s处理下行不?
      

  4.   

    是设备自动发送,我这边通过timer发送请求命令“M0,0"
    那设备就将测到的数据如"M+0000012.202"返回我接收到数据就在屏幕上画曲线
    就做这些动作现在是一秒钟只能做到7个数据左右
      

  5.   

    基恩士的LS-7000?
    这是高精度高速的CCD测量仪器,需要专业的控制器才行。如果楼主想通过简单的VB编程来实现控制,我看不可能达到它本身的  高速  定位。
      

  6.   

    使用这个延时函数可以达到20毫秒内的精度,如果忽略处理部分占时,楼主可尝试下。
    忘记地址了,本人只是负责copy。
    Option Explicit'2009-10-15
    '延时模块(不会让窗口失去响应,不太占CPU)
    '调用方式:Yanshi(300),即延时300毫秒。
    '本模块参考了某个类模块,那个类模块里的代码我理解得不透彻,就精简了一下写了本模块,没想到
    '也能用,暂时没发现问题。
    Private Declare Function GetTickCount Lib "kernel32" () As Long
    Dim i As Long
    Private Type FILETIME
        dwLowDateTime As Long
        dwHighDateTime As Long
    End TypePrivate Declare Function CreateWaitableTimer Lib "kernel32" Alias "CreateWaitableTimerA" (ByVal lpSemaphoreAttributes As Long, ByVal bManualReset As Long, ByVal lpName As String) As Long
    Private Declare Function SetWaitableTimer Lib "kernel32" (ByVal Htimer As Long, lpDueTime As FILETIME, ByVal lPeriod As Long, ByVal pfnCompletionRoutine As Long, ByVal lpArgToCompletionRoutine As Long, ByVal fResume As Long) As Long
    Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
    Private Declare Function WaitForSingleObject Lib "kernel32" (ByVal hHandle As Long, ByVal dwMilliseconds As Long) As Long
    Private Declare Function MsgWaitForMultipleObjects Lib "user32" (ByVal nCount As Long, pHandles As Long, ByVal fWaitAll As Long, ByVal dwMilliseconds As Long, ByVal dwWakeMask As Long) As LongPrivate Const WAIT_OBJECT_0 = 0
    Private Const INFINITE = &HFFFF    '无限超时(Infinite timeout)
    Private Const QS_HOTKEY& = &H80
    Private Const QS_KEY& = &H1
    Private Const QS_MOUSEBUTTON& = &H4
    Private Const QS_MOUSEMOVE& = &H2
    Private Const QS_PAINT& = &H20
    Private Const QS_POSTMESSAGE& = &H8
    Private Const QS_SENDMESSAGE& = &H40
    Private Const QS_TIMER& = &H10
    Private Const QS_MOUSE& = (QS_MOUSEMOVE Or QS_MOUSEBUTTON)
    Private Const QS_INPUT& = (QS_MOUSE Or QS_KEY)
    Private Const QS_ALLEVENTS& = (QS_INPUT Or QS_POSTMESSAGE Or QS_TIMER Or QS_PAINT Or QS_HOTKEY)
    Private Const QS_ALLINPUT& = (QS_SENDMESSAGE Or QS_PAINT Or QS_TIMER Or QS_POSTMESSAGE Or QS_MOUSEBUTTON Or QS_MOUSEMOVE Or QS_HOTKEY Or QS_KEY)Private Sub Command1_Click()
        i = GetTickCount
        Yanshi (Val(Text1.Text))
        Me.Caption = "已经延时:" & GetTickCount - i & " ms"
    End SubPublic Sub Yanshi(MilliSeconds As Long)
        On Error GoTo Cuo:
    Dim Htimer As Long, WenjianTime As FILETIME, Ret As Long
        'Htimer是计时器句柄    If Htimer <> 0 Then CloseHandle Htimer
        Htimer = CreateWaitableTimer(0, True, "Timer" & Format(Now, "hhmmnn"))
        'CreateWaitableTimer创建一个可等待的计时器对象,返回值:Long,如执行成功,返回可等待
        '计时器对象的句柄;零表示出错。参数lpSemaphoreAttributes As SECURITY_ATTRIBUTES
        '指定一个结构,用于设置对象的安全特性。如将参数声明为ByVal As Long,并传递零值,
        '就可使用对象的默认安全设置。bManualReset As Long,如果为TRUE,表示创建一个人工重设计时器;
        '如果为FALSE,则创建一个自动重设计时器。lpName As String,指定可等待计时器对象的名称。
        If Htimer = 0 Then
            Debug.Print "调用CreateWaitableTimer失败"
            Exit Sub
        End If
        WenjianTime.dwHighDateTime = -1
        WenjianTime.dwLowDateTime = -(MilliSeconds * 10000)
        Ret = SetWaitableTimer(Htimer, WenjianTime, 0, 0, 0, 0)
        'SetWaitableTimer启动一个可等待计时器,将它设为未发信号状态。返回值 As Long,非零表示成功,
        '零表示失败。hTimer As Long,指定一个可等待计时器的句柄。lpDueTime As FILETIME,指定
        '一个包含了64位时间值的结构。如果为正,它代表计时器要触发的时间。如果为负,它代表自
        '函数调用以来持续的时间。时间是以100ns为单位指定的。lPeriod As Long,如果为零,这个计时器
        '只会触发一次。否则,计时器会根据这里设置的持续时间自动重新启动(以毫秒为单位指定)。
        'pfnCompletionRoutine As Long,指定零或者计时器触发时要调用的一个函数的地址。可在标准
        '模块中用一个函数通过AddressOf操作符提供这个地址。或者使用此类ocx控件。最终的例程采取下述形式:
        'Sub myfunc(ByVal lpArgToCompletion&, ByVal dwTimerLow&, ByVal dwTimerHigh&)
        'lpArgToCompletionRoutine As Long,传递给最终例程的值。fResume As Long,如果为TRUE,
        '而且系统支持电源管理,那么在计时器触发的时候,系统会退出省电模式。如设为TRUE,但系统不
        '支持省电模式,GetLastError就会返回ERROR_NOT_SUPPORTED。
        '至于WenjianTime的dwHighDateTime和dwLowDateTime,dwHighDateTime设为-1,
        'dwLowDateTime设为-(延时时间*10000),因为要转换单位,所以要*10000。至于为什么是负的,
        '请看此句:如果为正,它代表计时器要触发的时间。如果为负,它代表自函数调用以来持续的时间。
        '时间是以100ns为单位指定的。后面4个参数都填0。
        If Ret = 0 Then
            Debug.Print "调用SetWaitableTimer失败"
            CloseHandle Htimer
            Exit Sub
        End If
        Do
            Ret = MsgWaitForMultipleObjects(1, Htimer, False, INFINITE, QS_ALLINPUT)
            '等候计时器发出信号
            DoEvents
        Loop Until Ret = WAIT_OBJECT_0
        'MsgWaitForMultipleObjects等候单个对象或一系列对象发出信号,标志着规定的超时已经过去,
        '或特定类型的消息已抵达线程的输入队列。如返回条件已经满足,则立即返回。返回WAIT_OBJECT_0
        '意思是所有的对象都发出信号。参数:nCount,指定列表中的句柄数量。pHandles,指定对象句柄
        '组合中的第一个元素。fWaitAll,如果为TRUE,表示除非对象同时发出信号,否则就等待下去。
        '如果为FALSE,表示任何对象发出信号即可。dwMilliseconds,指定要等待的毫秒数,填INFINITE
        '表示无限等待。dwWakeMask,带有QS_??前缀的一个或多个常数,用于标识特定的消息类型。
        '如果用WaitForSingleObject函数就会导致窗口失去响应,所以本例用MsgWaitForMultipleObjects函数。
        '一旦不再需要,一定记住用CloseHandle关闭计时器对象的句柄。它的所有句柄都关闭以后,
        '对象自己也会删除。
        CloseHandle Htimer
        Htimer = 0    Exit Sub
    Cuo:
        CloseHandle HtimerEnd Sub
      

  7.   

    测试了,这个函数确实不怎么占cpu,看能不能提高您的采样频度
      

  8.   

    9600的波特率,就算1起始位,一个校验位,一个停止位,8个数据位,供11个位,每秒就有9600/11,大约900个字节。按1个字节的命令起始字,2个字节的数据,可以有300个数据祯,要是用查询的方式,每个查询命令也是1个命令起始子,2个字节数据,每秒可以查询到150个数据帧。足够楼主说的50个数据了。还可以有2/3的处理时间。另外可以用更高的波特率来减少传输时间。比如14400 19200 28800 38400 56000 128000 256000 这样更主要的是下位机的处理能力,要是一个模数转换就用100ms,或者显示一个数据用时超过20ms,那就
      

  9.   

    Option Explicit
    Private Declare Function timeGetTime Lib "winmm.dll" () As LongPrivate Sub Form_Click()
    Dim i As Long, l As Long
    i = timeGetTime
    l = i
    Do
        If timeGetTime - i >= 1 Then
        Debug.Print timeGetTime
        i = timeGetTime
        If timeGetTime - l >= 20 Then Exit Do '测试20ms内的输出数量
        End If
        DoEvents
    Loop
    End Sub
    使用这个函数能达到1ms的定时精度,但是耗CPU。
      

  10.   

    更正:使用14楼的延时函数能达到1ms级别的精度,因为gettickcount只有15ms的精度,用它来检测延时函数的精度是不准确的,用timegettime能检测到该函数的延时精度为1ms
      

  11.   

    使用API函数TimeSetEvent可以实现高精度定时间隔
      

  12.   

    可以使用OnCOM事件和Timer计时一块使用
      

  13.   

    提供个程序思路,这样应该能做到可能的快,不过根据机器的不同,
    运行效果会有相应的不同,毕竟是在VB下运行,效率低,占用资源
    大这是逃不了的。
    先说说程序架构,需要几个主要过程
    1、主循环监测时间变化发送数据任务的过程
    2、串口接收数据的过程
    3、计时器测量过程先说说计时器测量过程
    你的设备可以支持到每秒50次的信息采集,而且是需要命令触发才会返回信息的。
    这样说来,硬件层已经规定了,每条通讯在 20ms 之间完成,包括发送和接收的
    过程。
    为了能比较精确的测量到时间的变化,而不至于影响到主过程的运行,所以开一个
    新线程来做时间间隔测量是比较好的方法,就但是单片机的中断计数过程来用。在现成里每隔5毫秒用GetTickCount取一下时间,然后将这次取时间的值与上次
    取时间的值进行差值计算存入公共变量中。主程序就需要两个变量作为处理基数,1个就是在线程里用的时间差变量,还有一个
    是是否发送数据完成的变量。当主程序循环时发现时间差变量大于或等于20的时候。
    判断上次数据是否发送完毕,当这两个条件都符合,主程序开始发送命令给下位机,
    并设置最后的发送时间参数为当前取得的参数。而串口接收过程则不用理会其他两个过程的运作,只需要收到数据解释出来处理就
    可以了。建议所谓的主循环过程也开一个线程来做,这样程序跑得会更顺畅。还有,记得在线程的循环过程中加个 Sleep ,这样会释放很多 CPU 资源