说了你也听不懂啊 发送的数据是 02 03 04 05 44 0c 0x 52 31 **XX XX 电子称返回的数据是 05 04 03 02 44 10 0x 52 31** ## ## XX XX 0x 是电子称的地址号 ** 是数据包的序号,发送者每次+1 XXXX 是CRC检验码,对数据包前面的所有字节进行校验的校验和 #### 就是重量值,是个Float类型的值,需要转换 再补一些吧,估计你还要接着问的, 这些数据是二进制数,也叫十六进制数, 电子称的地址号应该是在电子称上设定的,从1到8的8个数中的一个,如果有多台称要用同一根线的时候,地址就要不同 数据包的序号从00开始,每次加一,超过FF就转回00。 下边一个函数是计算CRC的,还有一个是转换浮点数的'================================= '名称 GetCRC16 '参数 Data Byte() 数据内容 ' Offset Integer 数组起始位置,默认值 0(从数组第一个元素开始) ' Length Integer 计算长度,默认值 0(计算整个数组) '返回 Byte() '说明 计算CRC16值 '日期 2007-03-09 ' 2007-03-15 修改Length判断 '================================= Private Function GetCRC16(Data() As Byte, Optional ByVal offset As Integer = 0, Optional ByVal Length As Integer = 0) As Byte() Dim CRC16Lo As Byte, CRC16Hi As Byte 'CRC寄存器 Dim CL As Byte, Ch As Byte '多项式码&HA001 Dim SaveHi As Byte, SaveLo As Byte Dim I As Integer Dim Flag As Integer Dim ReturnData(1) As Byte
For I = offset To offset + Length CRC16Lo = CRC16Lo Xor Data(I) '每一个数据与CRC寄存器进行异或 For Flag = 0 To 7 SaveHi = CRC16Hi SaveLo = CRC16Lo CRC16Hi = CRC16Hi \ 2 '高位右移一位 CRC16Lo = CRC16Lo \ 2 '低位右移一位 If ((SaveHi And &H1) = &H1) Then '如果高位字节最后一位为1 CRC16Lo = CRC16Lo Or &H80 '则低位字节右移后前面补1 End If '否则自动补0 If ((SaveLo And &H1) = &H1) Then '如果LSB为1,则与多项式码进行异或 CRC16Hi = CRC16Hi Xor Ch CRC16Lo = CRC16Lo Xor CL End If Next Next
ReturnData(0) = CRC16Lo 'CRC低位 ReturnData(1) = CRC16Hi 'CRC高位 GetCRC16 = ReturnData End Function '============================================================= Public Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)Public Function StrToSng(ByVal Data As String) As Single Dim I As Integer, C As Integer, R() As Byte On Error GoTo hErr StrToSng = 0 C = LenB(StrToSng) - 1 ReDim R(C) For I = 0 To C R(C - I) = CByte("&H" & Mid(Data, I * 2 + 1, 2)) Next CopyMemory StrToSng, R(0), LenB(StrToSng) hErr: End Function
我后来将代码改成下面的样子,但是输出来的CRC是0000,我在ReturnData(0) = CRC16Hi,ReturnData(1) = CRC16Lo这两句代码上面做中断,CRC16Hi和CRC16Lo是有值输出的,但是赋值给ReturnData的时候ReturnData的值始终为0,这是为什么呢? Private Sub Command1_Click() Dim outbuff() As Byte Dim CRC() As Byte ReDim outbuff(11) As Byte If MSComm.PortOpen = False Then '验证串口打开' MSComm.PortOpen = True End If
MSComm.Output = outbuff '发送数据' For I = 1 To 20000000 '延时发送' NextEnd SubPrivate Function CRC16(data() As Byte) As String Dim CRC16Lo As Byte, CRC16Hi As Byte Dim CL As Byte, Ch As Byte Dim SaveHi As Byte, SaveLo As Byte Dim I As Integer Dim Flag As IntegerCRC16Lo = &HFF CRC16Hi = &HFF CL = &H1 Ch = &HA0For I = 0 To UBound(data) CRC16Lo = CRC16Lo Xor data(I) For Flag = 0 To 7 SaveHi = CRC16Hi SaveLo = CRC16Lo CRC16Hi = CRC16Hi \ 2 CRC16Lo = CRC16Lo \ 2 If ((SaveHi And &H1) = &H1) Then CRC16Lo = CRC16Lo Or &H80 End If If ((SaveLo And &H1) = &H1) Then CRC16Hi = CRC16Hi Xor Ch CRC16Lo = CRC16Lo Xor CL End If Next Flag Next IDim ReturnData(1) As Byte ReturnData(0) = CRC16Hi ReturnData(1) = CRC16LoCRC16 = ReturnData End Function
函数声明错了 不是 Private Function CRC16(data() As Byte) As String 而是 Private Function CRC16(data() As Byte) As Byte()
// 发送指令包的结构类(指令:"R1")
//========================================================================//struct{
ulong Flag; //包前导码(0x02030405)
uchar PCBA; //板识别码(0x44)
uchar Size; //包字节数(0x0C)
uchar Addr; //板地址码(0x01-0x08)
uword Exec; //执行指令(0x5231)
uchar TxSN; //包序列号(发送1次+1)
uword CRC; //包校验码[02]
}Tx;
上位机发这包数据
==================================================
struct
{
ulong Flag; //包前导码(0x05040302)
uchar PCBA; //板识别码(0x44)
uchar Size; //包字节数(0x10)
uchar Addr; //板地址码(0x01-0x08)
uword Exec; //执行指令(0x5231)
uchar TxSN; //包序列号(发送端的=TxSN)
float V[1]; //天平数据[04]
uword CRC; //包校验码[02]
}Rx;
电子称返回这包数据给你,重量结果在 float V[1]里
数据读取对你来说可能也还是个问题
发送的数据是 02 03 04 05 44 0c 0x 52 31 ** XX XX
电子称返回的数据是 05 04 03 02 44 10 0x 52 31** ## ## XX XX
0x 是电子称的地址号
** 是数据包的序号,发送者每次+1
XXXX 是CRC检验码,对数据包前面的所有字节进行校验的校验和
#### 就是重量值,是个Float类型的值,需要转换
再补一些吧,估计你还要接着问的,
这些数据是二进制数,也叫十六进制数,
电子称的地址号应该是在电子称上设定的,从1到8的8个数中的一个,如果有多台称要用同一根线的时候,地址就要不同
数据包的序号从00开始,每次加一,超过FF就转回00。
下边一个函数是计算CRC的,还有一个是转换浮点数的'=================================
'名称 GetCRC16
'参数 Data Byte() 数据内容
' Offset Integer 数组起始位置,默认值 0(从数组第一个元素开始)
' Length Integer 计算长度,默认值 0(计算整个数组)
'返回 Byte()
'说明 计算CRC16值
'日期 2007-03-09
' 2007-03-15 修改Length判断
'=================================
Private Function GetCRC16(Data() As Byte, Optional ByVal offset As Integer = 0, Optional ByVal Length As Integer = 0) As Byte()
Dim CRC16Lo As Byte, CRC16Hi As Byte 'CRC寄存器
Dim CL As Byte, Ch As Byte '多项式码&HA001
Dim SaveHi As Byte, SaveLo As Byte
Dim I As Integer
Dim Flag As Integer
Dim ReturnData(1) As Byte
CRC16Lo = &HFF
CRC16Hi = &HFF
CL = &H1
Ch = &HA0
Length = IIf(Length < 1, UBound(Data) - offset, Length - 1) 'Update 2007-03-15
For I = offset To offset + Length
CRC16Lo = CRC16Lo Xor Data(I) '每一个数据与CRC寄存器进行异或
For Flag = 0 To 7
SaveHi = CRC16Hi
SaveLo = CRC16Lo
CRC16Hi = CRC16Hi \ 2 '高位右移一位
CRC16Lo = CRC16Lo \ 2 '低位右移一位
If ((SaveHi And &H1) = &H1) Then '如果高位字节最后一位为1
CRC16Lo = CRC16Lo Or &H80 '则低位字节右移后前面补1
End If '否则自动补0
If ((SaveLo And &H1) = &H1) Then '如果LSB为1,则与多项式码进行异或
CRC16Hi = CRC16Hi Xor Ch
CRC16Lo = CRC16Lo Xor CL
End If
Next
Next
ReturnData(0) = CRC16Lo 'CRC低位
ReturnData(1) = CRC16Hi 'CRC高位
GetCRC16 = ReturnData
End Function
'=============================================================
Public Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)Public Function StrToSng(ByVal Data As String) As Single
Dim I As Integer, C As Integer, R() As Byte
On Error GoTo hErr
StrToSng = 0
C = LenB(StrToSng) - 1
ReDim R(C)
For I = 0 To C
R(C - I) = CByte("&H" & Mid(Data, I * 2 + 1, 2))
Next
CopyMemory StrToSng, R(0), LenB(StrToSng)
hErr:
End Function
Private Sub Command1_Click()
Dim outbuff() As Byte
Dim CRC() As Byte
ReDim outbuff(11) As Byte If MSComm.PortOpen = False Then '验证串口打开'
MSComm.PortOpen = True
End If
outbuff(0) = &H2
outbuff(1) = &H3
outbuff(2) = &H4
outbuff(3) = &H5
outbuff(4) = &H44
outbuff(5) = &HC
outbuff(6) = &H3
outbuff(7) = &H52
outbuff(8) = &H31
outbuff(9) = &H3
CRC = CRC16(outbuff)
MSComm.Output = outbuff '发送数据'
For I = 1 To 20000000 '延时发送'
NextEnd SubPrivate Function CRC16(data() As Byte) As String
Dim CRC16Lo As Byte, CRC16Hi As Byte
Dim CL As Byte, Ch As Byte
Dim SaveHi As Byte, SaveLo As Byte
Dim I As Integer
Dim Flag As IntegerCRC16Lo = &HFF
CRC16Hi = &HFF
CL = &H1
Ch = &HA0For I = 0 To UBound(data)
CRC16Lo = CRC16Lo Xor data(I)
For Flag = 0 To 7
SaveHi = CRC16Hi
SaveLo = CRC16Lo
CRC16Hi = CRC16Hi \ 2
CRC16Lo = CRC16Lo \ 2
If ((SaveHi And &H1) = &H1) Then
CRC16Lo = CRC16Lo Or &H80
End If
If ((SaveLo And &H1) = &H1) Then
CRC16Hi = CRC16Hi Xor Ch
CRC16Lo = CRC16Lo Xor CL
End If
Next Flag
Next IDim ReturnData(1) As Byte
ReturnData(0) = CRC16Hi
ReturnData(1) = CRC16LoCRC16 = ReturnData
End Function
不是
Private Function CRC16(data() As Byte) As String
而是
Private Function CRC16(data() As Byte) As Byte()