前几天开了个帖,请教各位朋友VB如何跟RS485通讯的问题,最后拿到正确的仪表通讯协议后,数据现在读取出来了,只是有个问题:运行最初会实时不断的把数据读取出来(因为读取的流量是不断变化的,所以通过窗口的数据变化看得出来,一直在读取),但是过一会儿,时间不定,我大概数了下数据变化的次数,有时候是十几次,有时候是二十几次,有时候是四十几次,最后数据就停止不动了,代表通讯中断,或者发送数据后仪表未返回数据,未发现程序有什么问题,不知道是什么原因。如果将程序关闭后重启,又可以开始读数了,不过效果跟之前的一样,读到一定时间就停止了。
    下面将代码发布上来,望高手朋友指点指点:
——————————————————————————————————————————————Option ExplicitPrivate xz As Integer  'xz=0,则寻址表1,读表1数据
                          'xz=1,则寻址表2,读表2数据Private Declare Sub CopyMemory Lib "Kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)Private Sub Form_Load()
   MSComm1.InputLen = 0
   MSComm1.SThreshold = 0
   MSComm1.InputMode = comInputModeBinary
   MSComm1.PortOpen = True
End SubPrivate Sub Form_Unload(Cancel As Integer)
   If MSComm1.PortOpen = True Then MSComm1.PortOpen = False
End SubPrivate Sub MSComm1_OnComm()
   Dim indata() As Byte
   Dim llb(3) As Byte '读取流量字节Dim i As Integer
Dim llf As Single   '流量浮点数
Dim ds As Single    '带速Select Case MSComm1.CommEvent
  Case comEventRxOver
     MSComm1.InBufferCount = 0
  Case comEvReceive
     indata = MSComm1.Input     llb(3) = indata(0)
     llb(2) = indata(1)
     llb(1) = indata(2)
     llb(0) = indata(3)     CopyMemory ByVal VarPtr(llf), ByVal VarPtr(llb(0)), 4         If xz = 0 Then
        Text1.Text = llf 
        Text2.Text = indata(10) 
        xz = 1
      Else
        Text3.Text = llf 
        Text4.Text = indata(10) 
        xz = 0
      End If
  End Select
End SubPrivate Sub Timer1_Timer()    'timer1的interval属性值为400
   Dim od(0) As Byte
   If xz = 0 Then
      od(0) = &H21
   Else
      od(0) = &H22
   End IfMSComm1.OutBufferCount = 0 '清除发送缓冲区
MSComm1.InBufferCount = 0  '清除接收缓冲区
MSComm1.RThreshold = 16    '所要接收的数据长度MSComm1.Output = od
End Sub

解决方案 »

  1.   

    Option ExplicitPrivate xz As Integer  'xz=0,则寻址表1,读表1数据
                              'xz=1,则寻址表2,读表2数据Private Declare Sub CopyMemory Lib "Kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)Private Sub Form_Load()
       MSComm1.InputLen = 0
       MSComm1.SThreshold = 0
       MSComm1.InputMode = comInputModeBinary
       MSComm1.PortOpen = True
    End SubPrivate Sub Form_Unload(Cancel As Integer)
       If MSComm1.PortOpen = True Then MSComm1.PortOpen = False
    End SubPrivate Sub MSComm1_OnComm()
       Dim indata() As Byte
       Dim llb(3) As Byte '读取流量字节Dim i As Integer
    Dim llf As Single   '流量浮点数
    Dim ds As Single    '带速Select Case MSComm1.CommEvent
      Case comEventRxOver
         MSComm1.InBufferCount = 0
      Case comEvReceive
         indata = MSComm1.Input     llb(3) = indata(0)
         llb(2) = indata(1)
         llb(1) = indata(2)
         llb(0) = indata(3)     CopyMemory ByVal VarPtr(llf), ByVal VarPtr(llb(0)), 4         If xz = 0 Then
            Text1.Text = llf 
            Text2.Text = indata(10) 
            xz = 1
          Else
            Text3.Text = llf 
            Text4.Text = indata(10) 
            xz = 0
          End If
      End Select
    End SubPrivate Sub Timer1_Timer()    'timer1的interval属性值为400
       Dim od(0) As Byte
       If xz = 0 Then
          od(0) = &H21
       Else
          od(0) = &H22
       End IfMSComm1.OutBufferCount = 0 '清除发送缓冲区
    MSComm1.InBufferCount = 0  '清除接收缓冲区
    MSComm1.RThreshold = 16    '所要接收的数据长度MSComm1.Output = od
    End Sub
    看到其他人可以写代码,我发出去的怎么不是代码形式的?试一下,这样可以不。
      

  2.   

    那就将自动关闭而后自动启动有MsComm控件的窗体。
      

  3.   

    那就将自动关闭而后自动启动有MsComm控件的窗体。
    按固定时间间隔关闭和启动有MsComm控件的窗体。
      

  4.   

    谢谢楼上zdingyun 兄,但是这样是治标不治本呀,我想到了,主要是查找程序什么问题,还有其它解决的办法没得。
      

  5.   

      MSComm1.CommEvent 接收和Timer1_Timer配合有问题  如果仪表有事,给你响应慢一点,你刚好在接收,而Timer1_Timer又触发了,
      MSComm1.OutBufferCount = 0 '清除发送缓冲区
      MSComm1.InBufferCount = 0  '清除接收缓冲区
      MSComm1.RThreshold = 16    '所要接收的数据长度
      又初始化了,你应想到是什么结果了,你这样做,控制不了的,
      
      你应在 MSComm1.CommEvent一进来,就把Timer1直成无效,接收完后,再置有效
      才能有效的控制发和收