程序中有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
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
解决方案 »
- Excel用VBA 处理数据 取其中几列的数据以TXT格式存放
- 关于ComboBox控件定位问题
- 求救:用过True DBGrid控件的朋友请进!
- 我用ole打开一个word,sizemode=autosize,只能打开显示第一页,怎样显示所有的页呀?
- 关于日期降序排列的。请教一下各位大虾。。
- 我想将 报表控件 中的每一个CELL变成下拉列表的形式,请问用哪个控件可以实现?
- 没有人能够解决吗,有大虾吗?
- 98下是否可以使用com+组件?非常感谢
- 急死我了,高手那里去了?如何使用progressbar
- 急急急!!!谁能解决在ActiveBar中,加载窗体时会屏幕会闪动的问题,我给500分!!!
- 着急中。。图例控件
- 急急急!!!HttpQueryInfo函数
然后依据数据帧及拓扑帧的帧头和帧长分别取得数据进行处理。
将接受的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
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
首先非常的感谢你
我现在的数据有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
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
MSComm1.Settings = "9600,n,8,1"修改为:MSComm1.Settings = "1200,n,8,1"
你好
我以前也是和你一样的做法
可以做
但是我数据帧一下子发过来有丢失的现象
如:
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
能给段你原来的代码不?
谢谢
---------------------然后就判断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)
---------------------
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 个字节,作为帧头的一部分,会使程序结构更简单。
协议表示数据域长度,可以采取在帧首加长度域的方式,也可以用结束符的方式。一般不会两者同时使用。长度域方式是先取得后续长度,然后采用计数器方式(在Comm控件中用.InpitLen)接收后续数据。
而结束符方式是采取逐字节接收的方式,直到结束符。它一般适合文本方式,因为正文数据中不会出现结束符。对二进制数据不适合,因为数据可能与结束符冲突。你可能会提出以重发来避免冲突的方案。但是在真正的结束符后面没有后续数据的情况下,你就不得不采用超时方式来结束通讯了。