我的程序中使用到第三方的DLL函数来按照固定格式读取串口信息,包括OPEN,CLOSE,READopen:返回:1-成功 0-失败
CLOSE:返回:1-成功 0-失败
READ: 返回:1-成功 0-没有读到信息
注意:READ函数返回0时,无法确定是没有可读的信息还是串口通信已出现故障。该函数在串口硬件连接故障时,运行时间颇长,导致我的程序无法响应用户操作,
有时还出现“程序忙”的WINDOWS提示信息。请问有什么办法让我的程序可即时响应?或者,有什么比较好的方式检测串口通信是否正常?目前,我采用ActiveX EXE封装该DLL,提供PUBLIC函数用CLOSE/OPEN的方式检测串口是否正常,该函数可以在异常时RAISEEVENTS。
同时,主程序的定时器中调用ActiveX EXE对象的函数。
主程序捕获异常的事件时,我就重新创建ActiveX EXE对象。参见原帖:
http://community.csdn.net/Expert/topic/3928/3928533.xml?temp=.6705286但经过测试,发现当串口线未与PC连接时,该程序仍然无法响应用户操作。

解决方案 »

  1.   

    TMD,什么败类“第三方”写的DLL?!
      

  2.   

    建议将三个函数的原型写下来,难道就没有超时设置的参数吗?就算没有,其实问题还是好解决的。1、在第一次Open时,此时判断串口是否有故障,OK之后再不作串口故障的判断。
    2、在Read时,计算函数从发送到返回花费的总时间,当超过某个值,则可判断通讯不正常,一般的如果返回为0时,不管通讯有问题还是因为没数据,如果及时返回了,都作没数据处理。
      

  3.   

    申明一下:三个函数均没有任何参数。to  XunBaian(蓝水晶) :
    你说的方法2是无法实现的,
    因为我发现有一些通信故障时,所用时间在130MILLISECOND左右,
    而Read时正常时间在50-200MILLISECOND。
      

  4.   

    Read其实在300ms内的通讯你都可以当无故障(如果此时有故障,可判断为无数据),凡超出300ms即超时。
      

  5.   

    Read的结果只有三种:300ms内有“有数据”和“无数据”,大于300ms为“超时(或称通讯故障)”,明白我的意思吗?
      

  6.   

    to XunBaian(蓝水晶) 
      Read其实在300ms内的通讯你都可以当无故障(如果此时有故障,可判断为无数据),凡超出300ms即超时。                                      ~~~~~~~~~~~~~~~~~~~~~~~~~我的程序必须
                                                        在任何故障出现时都给出一定的提示!
                                             由于某些串口故障也将导致Read时间较短且无数据
                                             这种情况下必须提示用户!!!
                                             
      

  7.   

    如下例:Dim sngTimer As Single
    Dim lngReturn As Long,lngNoDataCount As LonglngNoDataCount = 0
    Do While 退出条件
       sngTimer = Timer   lngReturn = Read() '......Read操作   If sngTimer - Timer <= 300 Then
          If lngReturn =1 Then
              ......这里正常取数
          ElseIf lngReturn = 0 Then
              lngNoDataCount = lngNoDataCount + 1
              If lngNoDataCount > 1 Then'连续两次以上都无数据时判为有故障
                 ......这里提示有故障
              Else
                 ......这里提示暂无数据(有故障和无数据都提示为无数据)
              End If
          Else
              lngNoDataCount = 0
          End If
       Else
          ....这里提示通讯有故障
       End If      DoEvents
    Loop
      

  8.   

    加详细注释:
       Dim sngTimer As Single
       Dim lngReturn As Long, lngNoDataCount As Long
       
       lngNoDataCount = 0
       Do While 退出条件
          sngTimer = Timer
          
          lngReturn = Read() '......Read操作
          
          If sngTimer - Timer <= 300 Then  '在300ms内
          
             If lngReturn = 1 Then '正常有数据返回
                '......这里正常取数
                lngNoDataCount = 0
                
             ElseIf lngReturn = 0 Then
                lngNoDataCount = lngNoDataCount + 1 '无数据次数累加
                
                If lngNoDataCount > 1 Then '连续两次以上都无数据时判为有故障
                   '......这里提示有故障
                Else '第一次判为通讯正常但无数据
                   '......这里提示暂无数据(有故障和无数据都提示为无数据)
                End If
                
             Else '其它情况
                lngNoDataCount = 0
             End If
          Else '300ms超时
             '....这里提示通讯有故障
          End If
          
          DoEvents
       Loop
      

  9.   

    TO XunBaian(蓝水晶) 
       可能是我说的不够清楚,
      你采用的算法:
        lngNoDataCount = lngNoDataCount + 1 '无数据次数累加
        If lngNoDataCount > 1 Then '连续两次以上都无数据时判为有故障
      在我的程序中可能不太适用。
      
      因为:串口读取到信息不是经常有的,可能1分钟就读到多条,也可能一个小时都没有!!
            不过,一旦读到串口数据,我需要立即显示。   据我测试,READ函数大概是采用主动询问的方式:
        1)通知第三方的硬件设备,试图读取信息
        2)若接收到该设备读取的信息,返回1否则返回0。
     
      
      

  10.   

    这个dll并没有提供诊断串口是否有故障的函数,所以你也很难作此功能,如你所说,就只有两种方法了
    1、就是你原来的反复使用Open和Close(还是回到你的方法^_^),因为你的DLL是有问题的,在VB环境下调试时,第二次Open会失败,就是说,一定要退出VB才能Open第二次,这个问题在你的程序编译成exe后会自动消失(就是说exe没这问题)
    2、当Read返回0时,只能含糊的提示“当前没有取到设备数据,请检查确认通讯是否正常”,这种提示当然不能用MsgBox来提示了,可在窗体上加个Label控件。除此二法,我已黔驴计穷了!
      

  11.   

    还有,当确实为通信故障导致信息读取失败时,最慢在1-2分钟内,必须通知用户。所以,我现在的做法是:
       串口打开而未读取到信息时,认为通信可能已经出现异常,每秒钟采用CLOSE/OPEN方式检查通信
       当有一次信息读取成功后,认为通信正常,此后每分钟采用CLOSE/OPEN方式检查通信;
      

  12.   

    所以我的意思就是某次Read超过300ms(可根据实际情况调整),才用MsgBox提示说通讯有故障。