现在发现还是挺简单的
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' 加卸载控制系统-通讯协议类 Add JDF 20160516
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'a) 通讯结构 9600 N 8 1 CRC校验 数据传输方式:ASCII码-16进制
'b) 通讯协议 接收(PC发):帧头(FE)+(数据长度+)指令+校验位(CRC)
' 发送 (PC收): 帧头 (EF) + 指令 + 状态 + 校验位(crc)
'c) 指令(功能码):砝码加载(0x31)、砝码停(0x32)、砝码卸载(0x33)、
' 试样架升(0x34)、试样架停(0x35)、试样架降(0x36)以及设备状态(0x37);
'd) 状态(功能码):急停(0x3F)、砝码电机停()、砝码电机上限位停(0x41)、砝码电机下限位停(0x42)、
' 砝码向上运动中(0x43)、砝码向下运动中(0x44)、试样架电机停()、试样架电机上限位停(0x45)、
' 试样电机下限位停(0x46)、试样台向上运动中(0x47)、试样台向下运动中(0x48)。
' 增加一个接收成功(0x40),一个接收错误(0x49)。
'e) 注意PC指令仅在有需要时发送,不要循环发送。
Private msgType1 As Byte
Private msgType2 As Byte
Sub Class_Initialize()
msgType1 = &HFE '发送
msgType2 = &HEF '接受
End Sub
Public Function GetCmd(ByVal msgtype As Integer, ByVal cmdFlag As Integer) As String
Dim cmd(3) As Byte
Dim data As Byte
cmd(0) = GetMsgType(msgtype) '获取消息类型
data = GetEnumType(cmdFlag) '获取指令
cmd(1) = CLng("&H" & data)
Dim cal As Long
Dim calhi As Long, callo As Long
cal = buildcrc(cmd, 1)
calhi = (cal And &HFF00) / (2 ^ 8)
callo = cal And &HFF
cmd(2) = CByte(callo):
cmd(3) = CByte(calhi)
GetCmd = cmd
End Function
'获取消息类型 send=0 get
Private Function GetMsgType(ByVal msgtype As Integer) As Byte
GetMsgType = IIf(msgtype = 0, msgType1, msgType2)
End Function
Private Function GetEnumType(ByVal cmdFlag As Integer) As Byte
GetEnumType = IIf(cmdFlag > 0, Hex(cmdFlag), 0)
End Function
'CRC16校验
Function CRC16(data() As Byte) As String
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
CRC16Lo = &HFF
CRC16Hi = &HFF
CL = &H1
CH = &HA0
For i = 0 To UBound(data)
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 flag
Next i
Dim ReturnData(1) As Byte
ReturnData(0) = CRC16Lo 'CRC低位
ReturnData(1) = CRC16Hi 'CRC高位
CRC16 = ReturnData
End Function
'获取校验码
Private Function buildcrc(modbusqry() As Byte, wlen As Integer) As Long
Dim byckshi As Byte
Dim byckshiint As Long
Dim byckslo As Byte
Dim bycksloint As Long
Dim nloopcnt As Integer
Dim nIndex As Integer
Dim byckshitable As Variant
Dim byckslotable As Variant
byckshitable = Array( _
&H0, &HC1, &H81, &H40, &H1, &HC0, &H80, &H41, &H1, &HC0, &H80, &H41, &H0, &HC1, &H81, _
&H40, &H1, &HC0, &H80, &H41, &H0, &HC1, &H81, &H40, &H0, &HC1, &H81, &H40, &H1, &HC0, _
&H80, &H41, &H1, &HC0, &H80, &H41, &H0, &HC1, &H81, &H40, &H0, &HC1, &H81, &H40, &H1, _
&HC0, &H80, &H41, &H0, &HC1, &H81, &H40, &H1, &HC0, &H80, &H41, &H1, &HC0, &H80, &H41, _
&H0, &HC1, &H81, &H40, &H1, &HC0, &H80, &H41, &H0, &HC1, &H81, &H40, &H0, &HC1, &H81, _
&H40, &H1, &HC0, &H80, &H41, &H0, &HC1, &H81, &H40, &H1, &HC0, &H80, &H41, &H1, &HC0, _
&H80, &H41, &H0, &HC1, &H81, &H40, &H0, &HC1, &H81, &H40, &H1, &HC0, &H80, &H41, &H1, _
&HC0, &H80, &H41, &H0, &HC1, &H81, &H40, &H1, &HC0, &H80, &H41, &H0, &HC1, &H81, &H40, _
&H0, &HC1, &H81, &H40, &H1, &HC0, &H80, &H41, &H1, &HC0, &H80, &H41, &H0, &HC1, &H81, _
&H40, &H0, &HC1, &H81, &H40, &H1, &HC0, &H80, &H41, &H0, &HC1, &H81, &H40, &H1, &HC0, _
&H80, &H41, &H1, &HC0, &H80, &H41, &H0, &HC1, &H81, &H40, &H0, &HC1, &H81, &H40, &H1, _
&HC0, &H80, &H41, &H1, &HC0, &H80, &H41, &H0, &HC1, &H81, &H40, &H1, &HC0, &H80, &H41, _
&H0, &HC1, &H81, &H40, &H0, &HC1, &H81, &H40, &H1, &HC0, &H80, &H41, &H0, &HC1, &H81, _
&H40, &H1, &HC0, &H80, &H41, &H1, &HC0, &H80, &H41, &H0, &HC1, &H81, &H40, &H1, &HC0, _
&H80, &H41, &H0, &HC1, &H81, &H40, &H0, &HC1, &H81, &H40, &H1, &HC0, &H80, &H41, &H1, _
&HC0, &H80, &H41, &H0, &HC1, &H81, &H40, &H0, &HC1, &H81, &H40, &H1, &HC0, &H80, &H41, _
&H0, &HC1, &H81, &H40, &H1, &HC0, &H80, &H41, &H1, &HC0, &H80, &H41, &H0, &HC1, &H81, _
&H40)
byckslotable = Array( _
&H0, &HC0, &HC1, &H1, &HC3, &H3, &H2, &HC2, &HC6, &H6, &H7, &HC7, &H5, &HC5, &HC4, _
&H4, &HCC, &HC, &HD, &HCD, &HF, &HCF, &HCE, &HE, &HA, &HCA, &HCB, &HB, &HC9, &H9, _
&H8, &HC8, &HD8, &H18, &H19, &HD9, &H1B, &HDB, &HDA, &H1A, &H1E, &HDE, &HDF, &H1F, &HDD, _
&H1D, &H1C, &HDC, &H14, &HD4, &HD5, &H15, &HD7, &H17, &H16, &HD6, &HD2, &H12, &H13, &HD3, _
&H11, &HD1, &HD0, &H10, &HF0, &H30, &H31, &HF1, &H33, &HF3, &HF2, &H32, &H36, &HF6, &HF7, _
&H37, &HF5, &H35, &H34, &HF4, &H3C, &HFC, &HFD, &H3D, &HFF, &H3F, &H3E, &HFE, &HFA, &H3A, _
&H3B, &HFB, &H39, &HF9, &HF8, &H38, &H28, &HE8, &HE9, &H29, &HEB, &H2B, &H2A, &HEA, &HEE, _
&H2E, &H2F, &HEF, &H2D, &HED, &HEC, &H2C, &HE4, &H24, &H25, &HE5, &H27, &HE7, &HE6, &H26, _
&H22, &HE2, &HE3, &H23, &HE1, &H21, &H20, &HE0, &HA0, &H60, &H61, &HA1, &H63, &HA3, &HA2, _
&H62, &H66, &HA6, &HA7, &H67, &HA5, &H65, &H64, &HA4, &H6C, &HAC, &HAD, &H6D, &HAF, &H6F, _
&H6E, &HAE, &HAA, &H6A, &H6B, &HAB, &H69, &HA9, &HA8, &H68, &H78, &HB8, &HB9, &H79, &HBB, _
&H7B, &H7A, &HBA, &HBE, &H7E, &H7F, &HBF, &H7D, &HBD, &HBC, &H7C, &HB4, &H74, &H75, &HB5, _
&H77, &HB7, &HB6, &H76, &H72, &HB2, &HB3, &H73, &HB1, &H71, &H70, &HB0, &H50, &H90, &H91, _
&H51, &H93, &H53, &H52, &H92, &H96, &H56, &H57, &H97, &H55, &H95, &H94, &H54, &H9C, &H5C, _
&H5D, &H9D, &H5F, &H9F, &H9E, &H5E, &H5A, &H9A, &H9B, &H5B, &H99, &H59, &H58, &H98, &H88, _
&H48, &H49, &H89, &H4B, &H8B, &H8A, &H4A, &H4E, &H8E, &H8F, &H4F, &H8D, &H4D, &H4C, &H8C, _
&H44, &H84, &H85, &H45, &H87, &H47, &H46, &H86, &H82, &H42, &H43, &H83, &H41, &H81, &H80, _
&H40)
byckshi = &HFF
byckslo = &HFF
For nloopcnt = 0 To (wlen)
nIndex = byckshi Xor modbusqry(nloopcnt)
byckshi = byckslo Xor byckshitable(nIndex)
byckslo = byckslotable(nIndex)
Next
bycksloint = CInt(byckslo) * 2 ^ 8
byckshiint = byckshi
buildcrc = bycksloint Or byckshiint
End Function
'TODO: 下位机发送数据到上位机
Public Function MsgSendToPC(inputData() As Byte) As String
Dim cal As Long
Dim calhi As Long, callo As Long
Dim checkCode(1) As Byte
cal = buildcrc(inputData, 2)
calhi = (cal And &HFF00) / (2 ^ 8)
callo = cal And &HFF
checkCode(0) = CByte(callo)
checkCode(1) = CByte(calhi)
MsgSendToPC = checkCode
End Function
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' 调用MsgSendToPC Add JDF 20160618
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'Private Sub MSComm1_OnComm()
' Dim InputBuf() As Byte
' Dim inputData(2) As Byte, checkCode() As Byte
' Dim i As Integer
'
' If MSComm1.CommEvent <> comEvReceive Then Exit Sub
' InputBuf = MSComm1.Input
'
' If UBound(InputBuf) > 0 Then
'
' For i = 0 To 2
' inputData(i) = InputBuf(i)
' Next
'
' checkCode = AnalyzeData(inputData)
'
' If InputBuf(3) = checkCode(0) And InputBuf(4) = checkCode(1) Then
'
' End If
'
' End If
'
'End Sub
'
''解析下位机发送过来的msg
'Public Function AnalyzeData(inputData() As Byte) As String
' Dim msg As CommPortCompact
' Set msg = New CommPortCompact
' AnalyzeData = msg.MsgSendToPC(inputData)
'End Function