工作中用到MODBUS协议和PLC通信,为了方便,单独写了四个函数,通过调用这四个函数,可以很方便地实现与PLC通信的各种功能。
读位函数
Public Function ReadBits(ByVal PLC_Address As Byte, ByVal StartData As Byte, ByVal Length As Byte)
Dim CRC() As Byte
Dim d(5) As Byte
ReDim DataOutput(7) As Byte
Dim DataInput() As Byte
Dim DataIn As String
Dim LengthD As Integer
Dim j As Long
ReDim BitData(Length) As String
d(0) = PLC_Address
d(1) = 1
d(2) = StartData 256
d(3) = StartData Mod 256
d(4) = Length 256
d(5) = Length Mod 256
CRC = CRC16(d)
DataOutput(0) = d(0)
DataOutput(1) = d(1)
DataOutput(2) = d(2)
DataOutput(3) = d(3)
DataOutput(4) = d(4)
DataOutput(5) = d(5)
DataOutput(6) = CRC(1)
DataOutput(7) = CRC(0)
LengthD = 5 + CInt(Val(Length) 8)
If CInt(Val(Length) Mod 8) > 0 Then
LengthD = LengthD + 1
End If
MSComm1.InBufferCount = 0
MSComm1.OutBufferCount = 0
If MSComm1.PortOpen = False Then
MSComm1.PortOpen = True
End If
MSComm1.Output = DataOutput
Start = Timer
Do
If Timer > Start + 0.1 Then
CommChk = True
ReadBits = BitData
Exit Function
Else
CommChk = False
End If
Loop Until MSComm1.InBufferCount >= LengthD
DataInput = MSComm1.Input
MSComm1.PortOpen = False
j = 3
DataIn = ""
For j = 3 To LengthD - 3
DataIn = DataIn + HexToB(DataInput(j))
Next
j = 0
For j = 0 To Length - 1
BitData(j) = Mid$(DataIn, j + 1, 1)
Next
ReadBits = BitData
End Function
读字函数
Public Function ReadWords(ByVal PLC_Address As Byte, ByVal StartData As Byte, ByVal Length As Byte)
Dim CRC() As Byte
Dim d(5) As Byte
ReDim DataOutput(7) As Byte
Dim DataInput() As Byte
Dim j, i As Long
ReDim WordData(Length) As String
d(0) = PLC_Address
d(1) = 3
d(2) = StartData 256
d(3) = StartData Mod 256
d(4) = Length 256
d(5) = Length Mod 256
CRC = CRC16(d)
DataOutput(0) = d(0)
DataOutput(1) = d(1)
DataOutput(2) = d(2)
DataOutput(3) = d(3)
DataOutput(4) = d(4)
DataOutput(5) = d(5)
DataOutput(6) = CRC(1)
DataOutput(7) = CRC(0)
MSComm1.InBufferCount = 0
MSComm1.OutBufferCount = 0
If MSComm1.PortOpen = False Then
MSComm1.PortOpen = True
End If
MSComm1.Output = DataOutput
Start = Timer
Do
If Timer > Start + 0.1 Then
CommChk = True
ReadWords = WordData
Exit Function
Else
CommChk = False
End If
Loop Until MSComm1.InBufferCount >= Length * 2 + 5
DataInput = MSComm1.Input
MSComm1.PortOpen = False
j = 3
i = 0
For j = 3 To (Length * 2 + 2) Step 2
WordData(i) = DataInput(j) * 256 + DataInput(j + 1)
i = i + 1
Next
ReadWords = WordData
End Function
写位函数
Public Sub WriteBit(ByVal PLC_Address As Byte, ByVal StartData As Byte, ByVal WirteValue As Byte)
Dim CRC() As Byte
Dim d(5) As Byte
ReDim DataOutput(7) As Byte
d(0) = PLC_Address
d(1) = 5
d(2) = StartData 256
d(3) = StartData Mod 256
If WirteValue = 1 Then
d(4) = &HFF
d(5) = &H0
Else
d(4) = &H0
d(5) = &H0
End If
CRC = CRC16(d)
DataOutput(0) = d(0)
DataOutput(1) = d(1)
DataOutput(2) = d(2)
DataOutput(3) = d(3)
DataOutput(4) = d(4)
DataOutput(5) = d(5)
DataOutput(6) = CRC(1)
DataOutput(7) = CRC(0)
MSComm1.InBufferCount = 0
MSComm1.OutBufferCount = 0
If MSComm1.PortOpen = False Then
MSComm1.PortOpen = True
End If
MSComm1.Output = DataOutput
MSComm1.PortOpen = False
End Sub
写字函数
Public Sub WriteWord(ByVal PLC_Address As Byte, ByVal StartData As Byte, ByVal WirteValue As Long)
Dim CRC() As Byte
Dim d(5) As Byte
ReDim DataOutput(7) As Byte
d(0) = PLC_Address
d(1) = 6
d(2) = StartData 256
d(3) = StartData Mod 256
d(4) = WirteValue 256
d(5) = WirteValue Mod 256
CRC = CRC16(d)
DataOutput(0) = d(0)
DataOutput(1) = d(1)
DataOutput(2) = d(2)
DataOutput(3) = d(3)
DataOutput(4) = d(4)
DataOutput(5) = d(5)
DataOutput(6) = CRC(1)
DataOutput(7) = CRC(0)
MSComm1.InBufferCount = 0
MSComm1.OutBufferCount = 0
If MSComm1.PortOpen = False Then
MSComm1.PortOpen = True
End If
MSComm1.Output = DataOutput
MSComm1.PortOpen = False
End Sub