用MODBUS协议和PLC通信的四个函数

工作中用到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

原文地址:https://www.cnblogs.com/gorechen/p/4169121.html