我写了一个VB的用来发送和接受串口数据的小程序,下位机发送上来的16进制码比如:
EB 90 C1(设备代号) A0/A1(标示位,A0要求采样发送,A1采样数据) 68 09 00 00 10 07 00 68 81 06 43 C3 83 3C 33 33 A2 A3(采样数据,9路,比如68代表高4位,09代表低4位) 16(校检和,从设备代号一直加到A2 A3采样)。我希望把接到16进制数据转成字符串比如EB90C1A0/A16809000010070068810643C3833C3333A2A316(校验和)
Private Sub Form_Load()
MSComm1.Settings = "1200,e,8,1"
MSComm1.InBufferSize = 1024
MSComm1.OutBufferSize = 512
MSComm1.InputMode = comInputModeBinary
MSComm1.RThreshold = 1 '1 or 18
MSComm1.PortOpen = True
End SubPrivate Sub MSComm1_OnComm()
Dim buffer() As variant
Dim i As Integer
Dim Incept_1 As string
Dim Incept As string
Select Case MSComm1.CommEvent
Case comEvReceive
buffer = MSComm1.Input '这地方串口调试助手显示发送进来的是正确的
For i = LBound(buffer) To UBound(buffer)
If Len(Hex(buffer(i))) = 1 Then
Incept_1 = Incept_1 & "0" + Hex(buffer(i)) & Chr32
Else
Incept_1 = Incept_1 & Hex(buffer(i)) & Chr32
End If
Next i
Incept=Incept_1
Incept_1=""
//////// Mscomm1.output = Incept ///为了引起大家注意'这地方就奇怪了,如果这里我在END SELECT之后加'收发缓存情0,Incept就变成了字符串
EB90C1A0/A168090000833C3333A2A316(中间8位不见了,尝试加长输入16进制长度,每次都是隔8位才输出)
如果把收发缓存清0命令去掉,串口调试出来也正确,已经转成了我要的字符串,更奇怪的在下面。'++++++++++++++++++++++++++
'下面主要是对已经转成了我要的字符串Incept进行操作了 If Mid(Incept, 7, 2) = "A0" Then
Text6.Text = “通讯建立”
Shape1.BackColor=RGB(0,255,0) Else if Mid(Incept, 7, 2) = "A1" Then
Text6.Text = “开始接受采样”
//////////Mscomm1.output = Incept ’这个地方我又用串口调试助手看了下此时的Incept(这句话运行时,上面的那句///
Mscomm1.output = Incept 是被注释掉的),居然变成了EB90C1A0/A168090000!!!只留下了前8位,后面的都没了???这是怎么一回事??? End If
End Select
MSComm1.InBufferCount=0
MSComm1.OutBufferCount=0 '收发缓存清0 (执行///时,我全注释掉了)//////////Mscomm1.output = Incept '最奇怪的地方来了,我在这个地方看下INCEPT值,前2个///注释掉,居然串口调试助手接收栏不停的往出刷新,停都停不下来,并且数据全是最后几位3333A2A316的重复
End Sub求高人指点这是为什么???能不能给讲解一下这是什么原因?
令求高人指点,单字节校验和好算,我这个采样数据分的高位和低位的,这个校验和怎么计算啊???
还是采用转10进制,再转回16进制字符与校检位比较吗?怎么个比较?还请高人能给个校检的模板出来
EB 90 C1(设备代号) A0/A1(标示位,A0要求采样发送,A1采样数据) 68 09 00 00 10 07 00 68 81 06 43 C3 83 3C 33 33 A2 A3(采样数据,9路,比如68代表高4位,09代表低4位) 16(校检和,从设备代号一直加到A2 A3采样)。我希望把接到16进制数据转成字符串比如EB90C1A0/A16809000010070068810643C3833C3333A2A316(校验和)
Private Sub Form_Load()
MSComm1.Settings = "1200,e,8,1"
MSComm1.InBufferSize = 1024
MSComm1.OutBufferSize = 512
MSComm1.InputMode = comInputModeBinary
MSComm1.RThreshold = 1 '1 or 18
MSComm1.PortOpen = True
End SubPrivate Sub MSComm1_OnComm()
Dim buffer() As variant
Dim i As Integer
Dim Incept_1 As string
Dim Incept As string
Select Case MSComm1.CommEvent
Case comEvReceive
buffer = MSComm1.Input '这地方串口调试助手显示发送进来的是正确的
For i = LBound(buffer) To UBound(buffer)
If Len(Hex(buffer(i))) = 1 Then
Incept_1 = Incept_1 & "0" + Hex(buffer(i)) & Chr32
Else
Incept_1 = Incept_1 & Hex(buffer(i)) & Chr32
End If
Next i
Incept=Incept_1
Incept_1=""
//////// Mscomm1.output = Incept ///为了引起大家注意'这地方就奇怪了,如果这里我在END SELECT之后加'收发缓存情0,Incept就变成了字符串
EB90C1A0/A168090000833C3333A2A316(中间8位不见了,尝试加长输入16进制长度,每次都是隔8位才输出)
如果把收发缓存清0命令去掉,串口调试出来也正确,已经转成了我要的字符串,更奇怪的在下面。'++++++++++++++++++++++++++
'下面主要是对已经转成了我要的字符串Incept进行操作了 If Mid(Incept, 7, 2) = "A0" Then
Text6.Text = “通讯建立”
Shape1.BackColor=RGB(0,255,0) Else if Mid(Incept, 7, 2) = "A1" Then
Text6.Text = “开始接受采样”
//////////Mscomm1.output = Incept ’这个地方我又用串口调试助手看了下此时的Incept(这句话运行时,上面的那句///
Mscomm1.output = Incept 是被注释掉的),居然变成了EB90C1A0/A168090000!!!只留下了前8位,后面的都没了???这是怎么一回事??? End If
End Select
MSComm1.InBufferCount=0
MSComm1.OutBufferCount=0 '收发缓存清0 (执行///时,我全注释掉了)//////////Mscomm1.output = Incept '最奇怪的地方来了,我在这个地方看下INCEPT值,前2个///注释掉,居然串口调试助手接收栏不停的往出刷新,停都停不下来,并且数据全是最后几位3333A2A316的重复
End Sub求高人指点这是为什么???能不能给讲解一下这是什么原因?
令求高人指点,单字节校验和好算,我这个采样数据分的高位和低位的,这个校验和怎么计算啊???
还是采用转10进制,再转回16进制字符与校检位比较吗?怎么个比较?还请高人能给个校检的模板出来
On Error GoTo ErrHandle
Call NoErrClosePort
OpenComPort = True
MSCommRead.CommPort = mPort
MSCommRead.Settings = PORTSETTING
MSCommRead.InputMode = comInputModeBinary
MSCommRead.InBufferSize = 1024
MSCommRead.RThreshold = 128 '足够大的触发阀值
If MSCommRead.PortOpen = False Then
MSCommRead.PortOpen = True
End If
Exit Function
ErrHandle:
OpenComPort = False
mErrStr = err.Description
err.Clear
End FunctionPrivate Sub MSCommRead_OnComm()
On Error Resume Next
Dim Buffer As Variant, i As Integer, j As Integer
Dim vStr As String
With MSCommRead
Select Case .CommEvent
Case comEvReceive
j = .InBufferCount
If j > 0 Then
.RThreshold = 0 '停止接收
vStr = ""
lblRecv.Caption = "接收数据 (" & j & " 字节)"
Buffer = .Input
Call SendDataToBoard(gWritePData)
For i = 0 To j - 1
vStr = vStr & Hex(Buffer(i)) & " "
Next
vStr = Trim(vStr)
Call MainProcess(vStr)
End If
tmrShowErr.Enabled = False
.RThreshold = 128
Case comEventBreak
'Debug.Print "break"
Case comEventFrame
'Debug.Print "frame"
End Select
End With
End Sub
'获取高位
Public Function HiByte(a As Long) Dim b As Long b = a And &HFF00
b = b / 256
If b < 0 Then b = b + 256
HiByte = bEnd Function'获取低位
Public Function LowByte(a As Long) Dim b As Long b = a And &HFF
LowByte = bEnd Function'2个8Bit高低位合并回16Bit
Function MakeWord(ByVal bLow As Long, ByVal bHigh As Long) As Long MakeWord = bLow + bHigh * 256End Function
Private Sub MSCommRead_OnComm()
On Error Resume Next
Dim Buffer As Variant, i As Integer, j As Integer
Dim vStr As String
With MSCommRead
Select Case .CommEvent
Case comEvReceive
j = .InBufferCount
If j > 0 Then
.RThreshold = 0 '停止接收
vStr = ""
lblRecv.Caption = "接收数据 (" & j & " 字节)"
Buffer = .Input
Call SendDataToBoard(gWritePData)
For i = 0 To j - 1
vStr = vStr & Hex(Buffer(i)) & " "
Next
vStr = Trim(vStr)
Call MainProcess(vStr)
End If
tmrShowErr.Enabled = False
.RThreshold = 128
Case comEventBreak
'Debug.Print "break"
Case comEventFrame
'Debug.Print "frame"
End Select
End With
End Sub
没看明白,请大侠可以在我的基础上帮看看哪里出的错误码?
我的想法是这样的,如果拿到的INCEPT是正确的,那么我处理INCEPT里的采样信息(已全是字符串),
利用MID函数,分别把每一组&H 00 YY CC XX都取出来,
是不是我得再用VAL转成10进制,然后VAL(YY)*4096+VAL(CC)*256+VAL(XX),然后再把这个和转成字符串,之后用RIGHT(,2)取最后2位呢?这样得到的字符串直接就可以喝INCEPT的最后2位进行比较了吗?
Private Sub Form_Load()
MSComm1.Settings = "9600,e,8,1" (这地方一直是9600,我写错了)
MSComm1.InBufferSize = 1024
MSComm1.OutBufferSize = 512
MSComm1.InputMode = comInputModeBinary
MSComm1.RThreshold = 1 '1 or 18 (这地方的1得改吗?下位机发上来的不是定长,命令只有8个字节,而采样数据有40个字节)
MSComm1.PortOpen = True
End SubPrivate Sub MSComm1_OnComm()
Dim buffer() As variant
Dim i As Integer
Dim Incept_1 As string
Dim Incept As string
Select Case MSComm1.CommEvent
Case comEvReceive
/////////MSCOMM1.RThreshold = 0 (是在这里加这个吗?)
buffer = MSComm1.Input
For i = LBound(buffer) To UBound(buffer)
If Len(Hex(buffer(i))) = 1 Then
Incept_1 = Incept_1 & "0" + Hex(buffer(i)) & Chr32
Else
Incept_1 = Incept_1 & Hex(buffer(i)) & Chr32
End If
Next i
Incept=Incept_1
Incept_1=""
//////// Mscomm1.output = Incept ///引起大家注意'++++++++++++++++++++++++++
'下面主要是对已经转成了我要的字符串Incept进行操作了 If Mid(Incept, 7, 2) = "A0" Then
Text6.Text = “通讯建立”
Shape1.BackColor=RGB(0,255,0) Else if Mid(Incept, 7, 2) = "A1" Then
Text6.Text = “开始接受采样”
//////////Mscomm1.output = Incept
End If
End Select
MSComm1.InBufferCount=0
MSComm1.OutBufferCount=0 '收发缓存情0//////////Mscomm1.output = Incept '那这个地方怎么解释?为什么串口助手再不断的刷新呢?加了.RThreshold = 0就可以了吗?望赐教
MSComm1.Settings = "9600,e,8,1" (这地方一直是9600,我写错了)
MSComm1.InBufferSize = 1024
MSComm1.OutBufferSize = 512
MSComm1.InputMode = comInputModeBinary
MSComm1.RThreshold = 56 '40+8=48,48+8=56,试试看
MSComm1.PortOpen = True
End SubPrivate Sub MSComm1_OnComm()
Dim buffer() As variant
Dim i As Integer
Dim Incept_1 As string
Dim Incept As string
Select Case MSComm1.CommEvent
Case comEvReceive
MSCOMM1.RThreshold = 0 '立即停止触发comEvReceive
buffer = MSComm1.Input
For i = LBound(buffer) To UBound(buffer)
If Len(Hex(buffer(i))) = 1 Then
Incept_1 = Incept_1 & "0" + Hex(buffer(i)) & Chr32
Else
Incept_1 = Incept_1 & Hex(buffer(i)) & Chr32
End If
Next i
Incept=Incept_1
Incept_1=""
MSCOMM1.RThreshold = 56 '恢复事件
//////// Mscomm1.output = Incept ///引起大家注意'++++++++++++++++++++++++++
'下面主要是对已经转成了我要的字符串Incept进行操作了 If Mid(Incept, 7, 2) = "A0" Then
Text6.Text = “通讯建立”
Shape1.BackColor=RGB(0,255,0) Else if Mid(Incept, 7, 2) = "A1" Then
Text6.Text = “开始接受采样”
//////////Mscomm1.output = Incept
End If
End Select
'MSComm1.InBufferCount=0
'MSComm1.OutBufferCount=0 '这两个不要
68 09 00 00 10 07 00 68 81 06 43 C3 83 3C 33 33 A2 16
If Mid(strData, 1, 2) = "68" And Len(strData) = 36 Then
Text1.Text = strData
Text3.Text = Mid(strData, 3, 2)
strData = ""
End If
End Select
End Sub我这里做的收发形式是,我给下位一个指令(含标示位),下位收到了校验和,正确了了发
EB 90 C1 01 AA/55(正确AA,错误55) XX(校验和)
我收到信息后,判断有AA就继续运行,55直接报错
if length=7 RT=7
Else if length=38 RT=38
如何才能实现这个功能,能给个框架出来最好