程序中有2中数据
2A 02 02 05 06 01 00 00 01 55 -》数据帧2A 02-》是帧头05-》后面有5位数据(06 01 00 00 01)
2A 04 03 FE 00 01 2A OD -》拓扑帧2A 04-》是帧头03-》后面有3位数据(FE 00 01)Public Sub start_Click()
 If MSComm1.PortOpen Then MSComm1.PortOpen = False
           
        With MSComm1
           .CommPort = 1
           .Settings = "1200,N,8,1"
          .InputMode = comInputModeBinary
          .InBufferCount = 0 '清除接收缓冲区
          .OutBufferCount = 0         '清除发送缓冲区
          If Not .PortOpen Then
            .PortOpen = True '打开通信端口
          End If
        End With
        
         Sample
                
End SubPublic Sub Sample()
On Local Error GoTo errorOut
'定义一个接收数组 注意类型
 
Dim buffer() As Byte
Dim data As String
Do        Do
        DoEvents
      Loop Until MSComm1.InBufferCount > 2 '循环等待接收缓冲区>2个字节
         data = data & MSComm1.Input
   buffer() = data
 ''''''''
这里的任何把2中数据帧分离出来,然后处理数据呢?
我已经走进死胡同里,我以前判断长度的,这样数据老处理错误,望各位指点一下
''''
Loop Until MSComm1.PortOpen = False
errorOut:
    Debug.Print "硬件出现故障,请检查!"End Sub

解决方案 »

  1.   

    如果接收数据是2组数据连续接收,设置 MSComm控件属性RThreshold = 18
    然后依据数据帧及拓扑帧的帧头和帧长分别取得数据进行处理。
    将接受的BYTE数据转为16进制(双字节构成的字符串形式),进行条件判断。Private Sub Form_Load()
        Timer2.Interval = 10
        MSComm1.Settings = "1200,n,8,1"
        MSComm1.CommPort = 1
        MSComm1.RThreshold = 1
        MSComm1.PortOpen = True
    End Sub
    Private Sub MsComm1_OnComm()
        Dim intInputLen As Integer
        Select Case Me.MSComm1.CommEvent
            Case comEvReceive
                '此处添加处理接收的代码
                Me.MSComm1.InputMode = comInputModeBinary '二进制接收
                intInputLen = Me.MSComm1.InBufferCount
                ReDim bytInput(intInputLen)
                bytInput = Me.MSComm1.Input
                jieshou
                '写数据判断代码
        End Select
    End SubPublic Function jieshou() '接收数据处理为16进制
        Dim i As Integer
        For i = 0 To UBound(bytInput)
            If Len(Hex(bytInput(i))) = 1 Then
                strData = strData & "0" & Hex(bytInput(i))
            Else
                strData = strData & Hex(bytInput(i))
            End If
        Next
        RichTextBox1 = strData
        Text1 = Len(strData) \ 2
    End Function
      

  2.   


    Private Sub Form_Load()
        MSComm1.Settings = "1200,n,8,1"
        MSComm1.CommPort = 1
        MSComm1.RThreshold = 18
        MSComm1.PortOpen = True
    End SubPrivate Sub MsComm1_OnComm()
        Dim intInputLen As Integer
        Select Case Me.MSComm1.CommEvent
            Case comEvReceive
                '此处添加处理接收的代码
                Me.MSComm1.InputMode = comInputModeBinary '二进制接收
                intInputLen = Me.MSComm1.InBufferCount
                ReDim bytInput(intInputLen)
                bytInput = Me.MSComm1.Input
                jieshou
                '写数据判断代码
                If Len(strData) = 36 Then
                    sj1 = Mid(strData, 1, 20)
                    sj2 = mdi(strData, 21, 16)
                    '分别进入下一步数据处理
                End If
        End Select
    End SubPublic Function jieshou() '接收数据处理为16进制
        Dim i As Integer
        For i = 0 To UBound(bytInput)
            If Len(Hex(bytInput(i))) = 1 Then
                strData = strData & "0" & Hex(bytInput(i))
            Else
                strData = strData & Hex(bytInput(i))
            End If
        Next
        Text2 = strData
        Text1 = Len(strData) \ 2
    End Function
      

  3.   

    zdingyun 你好
    首先非常的感谢你
    我现在的数据有2种不同数据帧格式的
    可是现在数据是
    一组帧中的组成 :
    2A   02   02(网络号2) 05   06   01   00   00   01   55   
    2A   02   03(网络号3) 05   06   01   00   00   01   55   
    2A   02   01(网络号1) 05   06   01   00   00   01   55   
    上面的数据帧不止一个的2A   04   03   FE   00   01   2A   OD  
      

  4.   


    Option Explicit
        Dim Buffer() As Byte
        Dim Lbljieshou As String
        Dim lenInput As String
        Dim strData As String
        Dim j As Integer
        Dim k As Integer
        Dim sj(3) As StringPrivate Sub Form_Load()
        MSComm1.CommPort = 1                      'COM1串口
        MSComm1.Settings = "9600,n,8,1"           '串口设置
        MSComm1.InputMode = comInputModeBinary    '采用二进制传输
        MSComm1.InBufferCount = 0                 '清空接受缓冲区
        MSComm1.OutBufferCount = 0                '清空传输缓冲区
        MSComm1.InBufferSize = 512                '接收缓冲区大小
        MSComm1.OutBufferSize = 512               '发送缓冲区大小
        MSComm1.RThreshold = 1                   '产生MSComm事件
        MSComm1.PortOpen = True                   '开串口
        Timer1.Interval = 0                     '200ms Timer1使strData清空
        txtRev = ""
    End SubPrivate Sub MSComm1_OnComm()
        Dim intInputLen As Integer
        Text1 = ""
        'strData1 = ""
        Select Case MSComm1.CommEvent
            Case comEvReceive
                MSComm1.InputLen = 0
                intInputLen = MSComm1.InBufferCount
                ReDim Buffer(intInputLen)
                Buffer() = MSComm1.Input
                '数据处理代码
                  Call Receive
                If Len(strData) = 20 And Mid(strData, 1, 4) = "2A02" Then
                    If Mid(strData, 5, 2) = "01" Then
                        sj(0) = Mid(strData, 7, 12)
                        Label1 = "01:" & sj(0)
                        Timer1_Timer
                    ElseIf Mid(strData, 5, 2) = "02" Then
                        sj(1) = Mid(strData, 7, 12)
                        Label2 = "02:" & sj(1)
                        Timer1_Timer
                    ElseIf Mid(strData, 5, 2) = "03" Then
                        sj(2) = Mid(strData, 7, 12)
                        Label3 = "03:" & sj(2)
                        Timer1_Timer
                    End If
                    '分别进入下一步数据处理
                ElseIf Len(strData) = 16 And Mid(strData, 1, 4) = "2A04" Then
                    sj(3) = Mid(strData, 7, 6)
                    Label4 = "04:" & sj(3)
                    Timer1_Timer
                End If    End Select
    End SubPublic Sub Receive()'接收数据处理为16进制
        Dim i As Integer
        For i = 0 To UBound(Buffer)
            If Len(Hex(Buffer(i))) = 1 Then
                strData = strData & "0" & Hex(Buffer(i))
            Else
                strData = strData & Hex(Buffer(i))
            End If
        Next
    End SubPrivate Sub Timer1_Timer() '清除接收
        strData = ""
    End Sub
      

  5.   

    上述代码请将
    MSComm1.Settings = "9600,n,8,1"修改为:MSComm1.Settings = "1200,n,8,1"
      

  6.   

    zhu_1976
    你好
    我以前也是和你一样的做法
    可以做
    但是我数据帧一下子发过来有丢失的现象
    如:
                      02(网络号2)   05       06       01       00       00       01       55       
    2A       02       03(网络号3)   05       06       01       00       00       01       55       
    2A       02       01(网络号1)   05       06       01       00       00       01       55  
    前面的的2A 02被丢掉了
    zhu_1976
    能给段你原来的代码不?
    谢谢
      

  7.   

    buffer()   =   data 
    ---------------------然后就判断buffer()这个字节数组的长度n(字节数):
    n=UBound(buffer)-1
    ---------------------
    一组帧中的组成   : 
    2A       02       02(网络号2)   05       06       01       00       00       01       55       
    2A       02       03(网络号3)   05       06       01       00       00       01       55       
    2A       02       01(网络号1)   05       06       01       00       00       01       55       
     上面的数据帧不止一个的 2A       04       03       FE       00       01       2A       OD   
    ---------------------
    显然这里数据帧最少为1(2字节),才说明读到数据了:n>帧头字节数+2(字节数字)+帧尾字节数然后判断网络号,这个不难吧?
    然后截取数据帧,也不难吧?你说的这个通讯协议好象不全,应该有帧尾的!帧尾一般是chr(13)或char(10)

    ---------------------
      

  8.   

    这个问题的关键是先取帧头,再根据帧头确定后续长度。
    Private Sub Form_Load()
     With MSComm1 
      .CommPort = 1 
      .Settings = "1200,N,8,1" 
      .InputMode = comInputModeBinary 
      .RThreshold = 2    '收到帧头后触发 OnComm 事件
      .PortOpen = True
     End With
    End SubPrivate Sub MSComm1_OnComm()
    Dim bytBuff() As Byte, varTmp As Variant
    Dim bytChNo As Byte With MSComm1
      .InputLen = 2
      If .CommEvent = comEvReceive
        varTmp = .Input
        bytBuff = varTmp
        If bytBuff(0) <> &h2A The
           '此处错误处理
            '......
           Exit Sub
        End If    If bytBuff(1) = 2 Then  '第一类包
            Do
             Doevents
           Loop Until .InBufferCount >= 2
           '接收通道号和数据长度字段
           varTmp = .Input
           bytBuff = varTmp
           bytChNo = bytBuff(0)         
           .InputLen = bytBuff(1) + 1
               Else
           .InputLen = 1
           varTmp = .Input
           bytBuff = varTmp
           .InputLen = bytBuff(0) + 1
        End If    Do
          Doevents
        Loop Until .InBufferCount >= .InputLen
        varTmp = .Input
        bytBuff = varTmp
        '这里做数据处理
        '......
      End If
     End With
    End Sub我觉得,如果能将数据长度域统一放在第 3 个字节,作为帧头的一部分,会使程序结构更简单。
      

  9.   

    12 楼的说法是另一种情况。
    协议表示数据域长度,可以采取在帧首加长度域的方式,也可以用结束符的方式。一般不会两者同时使用。长度域方式是先取得后续长度,然后采用计数器方式(在Comm控件中用.InpitLen)接收后续数据。
    而结束符方式是采取逐字节接收的方式,直到结束符。它一般适合文本方式,因为正文数据中不会出现结束符。对二进制数据不适合,因为数据可能与结束符冲突。你可能会提出以重发来避免冲突的方案。但是在真正的结束符后面没有后续数据的情况下,你就不得不采用超时方式来结束通讯了。