视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001
Modbus 通讯协议编程
2025-09-27 16:17:42 责编:小OO
文档
Modbus 通讯协议编程

本人最近为了实现电脑与Delta VFD-M变频器通讯,特意用VB6.0编了一个Modbus协议通讯软件,不过这只是一个测试版,但Modbus的ASCii协议和RTU协议都已经实现。现在将源程序上贴,希望可以帮助到有需要的朋友,谢谢!(我发现图片贴不上去)

    另外,假如你觉得有更好的想法,欢迎E-mail指教。

附:VB6源程序

Option Explicit

Private Text1text As String

Private RTUCRC As String

'串口选择

Private Sub Combo1_Click()

              MSComm1.CommPort = Combo1.ListIndex + 1

End Sub

'数据位改变

Private Sub Combo2_Click()

        Call setting

End Sub

'波特率改变

Private Sub Combo3_Click()

        Call setting

End Sub

'奇偶校验改变

Private Sub Combo4_Click()

        Call setting

End Sub

'停止位改变

Private Sub Combo5_Click()

        Call setting

End Sub

Private Sub setting()

         MSComm1.Settings = CStr(Combo3.Text) & 

                                          & 

End Sub

'打开关闭串口

Private Sub Command1_Click()

        On Error Resume Next

        If MSComm1.PortOpen = False Then

            MSComm1.PortOpen = True

        Else

               MSComm1.PortOpen = False

        End If

        

        If MSComm1.PortOpen Then                                '打开关闭按钮显示文字及combo1使能

             Command1.Caption = "关闭串口"

             Combo1.Enabled = False

        Else

              Command1.Caption = "打开串口"

              Combo1.Enabled = True

        End If

        

          If Err Then                                                          '打开串口失败,则显示出错信息

               MsgBox Error$, 48, "错误信息"

                Exit Sub

           End If

End Sub

'10转16进制

Private Sub Command2_Click(Index As Integer)

     On Error Resume Next

         Text4.Text = Hex(Text3.Text)

           If Err Then                                                          ''则显示出错信息

               MsgBox Error$, 48, "错误信息"

                Exit Sub

           End If

End Sub

'16转10进制

Private Sub Command3_Click()

         Dim a As Long

         a = Val("&H" & CStr(Text4.Text))

         Text3.Text = a

End Sub

'手动串口发送

Private Sub Command4_Click()

         If MSComm1.PortOpen = False Then

                  MsgBox "请先打开串口", , "错误信息"

                  Exit Sub

          End If

          Call sentsub

End Sub

'清除接收窗

Private Sub Command5_Click()

          Text2.Text = ""

End Sub

Private Sub Command6_Click()

        Unload Me

End Sub

Private Sub Command7_Click()

        On Error Resume Next

          Dim STP As String

           STP = CStr(Chr(2)) & "010001" & CStr(Chr(3)) & "25"

           MSComm1.Settings = "9600,N,7,2"

           MSComm1.PortOpen = True

           MSComm1.Output = STP

           MSComm1.PortOpen = False

           If Err Then                                                          '打开串口失败,则显示出错信息

               MsgBox Error$, 48, "错误信息"

                Exit Sub

           End If

End Sub

Private Sub Command8_Click()

        On Error Resume Next

        Dim FWD As String

           FWD = CStr(Chr(2)) & "010101" & CStr(Chr(3)) & "26"

           MSComm1.Settings = "9600,N,7,2"

           MSComm1.PortOpen = True

           MSComm1.Output = FWD

           MSComm1.PortOpen = False

           If Err Then                                                          '打开串口失败,则显示出错信息

               MsgBox Error$, 48, "错误信息"

                Exit Sub

           End If

End Sub

Private Sub Command9_Click()

        On Error Resume Next

           Dim REV As String

           REV = CStr(Chr(2)) & "010201" & CStr(Chr(3)) & "27"

           MSComm1.Settings = "9600,N,7,2"

           MSComm1.PortOpen = True

           MSComm1.Output = REV

           MSComm1.PortOpen = False

           If Err Then                                                          '打开串口失败,则显示出错信息

               MsgBox Error$, 48, "错误信息"

                Exit Sub

           End If

End Sub

'窗口加载

Private Sub Form_Load()

         Dim d%

            For d = 1 To 16

                   Combo1.AddItem ("COM" & CStr(d))

            Next

                   Combo1.ListIndex = 0

                   

            Combo2.AddItem "6"

            Combo2.AddItem "7"

            Combo2.AddItem "8"

            Combo2.ListIndex = 2

            

            Combo3.AddItem "110"

            Combo3.AddItem "330"

            Combo3.AddItem "1200"

            Combo3.AddItem "2400"

            Combo3.AddItem "4800"

            Combo3.AddItem "9600"

            Combo3.AddItem "19200"

            Combo3.AddItem "38400"

            Combo3.AddItem "56000"

            Combo3.AddItem "57600"

            Combo3.AddItem "115200"

            Combo3.ListIndex = 5

            

            Combo4.AddItem "n"

            Combo4.AddItem "o"

            Combo4.AddItem "e"

            Combo4.ListIndex = 0

            

            Combo5.AddItem "1"

            Combo5.AddItem "2"

            Combo5.ListIndex = 0

            

            For d = 0 To 254

                Combo6.AddItem d

            Next

                Combo6.ListIndex = 1

            

         Text1.Text = "010601001770"

         Text2.Text = ""

         Text3.Text = ""

         Text4.Text = ""

         Text5.Text = "1000"

         Text6.Text = "06"

         Text7.Text = "0"

         Text8.Text = "1"

         

         Option1.value = True

         Option3.value = True

         Option7.value = True

         Option9.value = True

         

         If MSComm1.PortOpen = False Then

                Command1.Caption = "打开串口"

         Else

                Command1.Caption = "关闭串口"

         End If

End Sub

'串口接收程序

Private Sub MSComm1_OnComm()

        Dim Hexchr As String, hexstring As String, i As Integer, j As Integer, hexdisp As String

        If Option8.value Then

             hexstring = MSComm1.Input                                                                    '十六进制显示

            i = Len(hexstring)

             For j = 1 To i

                 Hexchr = Mid(hexstring, j, 1)

                 If Hex(Asc(Hexchr)) < 16 Then

                    Text2.Text = Text2.Text & "0" & Hex(Asc(Hexchr)) & " "

                 Else

                    Text2.Text = Text2.Text & Hex(Asc(Hexchr)) & " "

                End If

            Next j

            Text2.Text = Text2.Text & CStr(Chr(13)) & CStr(Chr(10))

        Else

            Text2.Text = Text2.Text & MSComm1.Input & CStr(Chr(13)) & CStr(Chr(10))   'ASCII码显示

        End If

End Sub

'手动发送选择

Private Sub Option1_Click()

         If Option1.value = True Then

              Timer1.Enabled = False

              Command4.Enabled = True

        Else

              Timer1.Enabled = True

              Command4.Enabled = False

        End If

End Sub

'Delta ASCII发送协议

Private Sub Option10_Click()

        Combo6.Enabled = True

       Text6.Enabled = True

       Text7.Enabled = True

       Text8.Enabled = True

       Label10.Enabled = True

       Label11.Enabled = True

       Label12.Enabled = True

       Label13.Enabled = True

       Option6.Enabled = False

       Option7.Enabled = False

       Option11.value = True

       Combo2.ListIndex = 1

       Combo5.ListIndex = 1

       Text1.Enabled = False

       Label14.Enabled = False

       Frame7.Visible = True

End Sub

'自动发送选择

Private Sub Option2_Click()

         If Option2.value = True Then

              Timer1.Enabled = True

              Command4.Enabled = False

        Else

              Timer1.Enabled = False

              Command4.Enabled = True

        End If

End Sub

Private Sub Option3_Click()               'Non选项

       Combo6.Enabled = False

       Text6.Enabled = False

       Text7.Enabled = False

       Text8.Enabled = False

       Label10.Enabled = False

       Label11.Enabled = False

       Label12.Enabled = False

       Label13.Enabled = False

       Option6.Enabled = True

       Option7.Enabled = True

       Combo2.ListIndex = 2

       Combo5.ListIndex = 0

       Text1.Enabled = True

       Label14.Enabled = True

       Frame7.Visible = False

End Sub

Private Sub Option4_Click()               'ASCII选项

       Combo6.Enabled = True

       Text6.Enabled = True

       Text7.Enabled = True

       Text8.Enabled = True

       Label10.Enabled = True

       Label11.Enabled = True

       Label12.Enabled = True

       Label13.Enabled = True

       Option6.Enabled = False

       Option7.Enabled = False

       Combo2.ListIndex = 1

       Combo5.ListIndex = 1

       Text1.Enabled = False

       Label14.Enabled = False

       Frame7.Visible = False

End Sub

Private Sub Option5_Click()               'RTU选项

       Combo6.Enabled = True

       Text6.Enabled = True

       Text7.Enabled = True

       Text8.Enabled = True

       Label10.Enabled = True

       Label11.Enabled = True

       Label12.Enabled = True

       Label13.Enabled = True

       Option6.Enabled = False

       Option7.Enabled = False

       Combo2.ListIndex = 2

       Combo5.ListIndex = 1

       Text1.Enabled = False

       Label14.Enabled = False

       Frame7.Visible = False

End Sub

'发送时间间隔调整输入

Private Sub Text5_Change()

        Dim number As String

        Dim num As Integer

        Dim numcyc As Integer

        num = Len(Text5.Text)

        For numcyc = 1 To num

            number = Mid(Text5.Text, numcyc, 1)

            Select Case InStr("01234567", number)

            Case 0

               MsgBox "输入时间间隔错误,请重新输入", , "错误信息"

               Exit Sub

            End Select

        Next

         Timer1.Interval = Text5.Text

End Sub

'自动发送定时器

Private Sub Timer1_Timer()

         If MSComm1.PortOpen Then

               Call sentsub

         End If

End Sub

'状态刷新定时器

Private Sub Timer2_Timer()

         StatusBar1.Panels(1).Text = "串口选择:" & CStr(Combo1.Text)

         StatusBar1.Panels(2).Text = "串口设置:" & CStr(MSComm1.Settings)

         StatusBar1.Panels(3).Text = "串口状态:" & CStr(MSComm1.PortOpen)

End Sub

'串口发送子程序

Private Sub sentsub()

             Dim optioncase%

             If Option3.value Then optioncase = 1

             If Option4.value Then optioncase = 2

             If Option5.value Then optioncase = 3

             If Option10.value Then optioncase = 4

             Select Case optioncase

             Case 1

                     If Option6.value Then

                       Text1text = Text1.Text

                       Call Hexsent

                     Else

                       Text1text = Text1.Text

                       Call ASCIIsent

                     End If

             Case 2

                  Call incorporate                '将输入的十进制从机地址、命令、资料地址和资料内容合并成字符串

                  Call ASCIIcheck

                  Call ASCIIsent

             Case 3

                  Call incorporate                 '将输入的十进制从机地址、命令、资料地址和资料内容合并成字符串

                  Call RTUcheck

                  Call Hexsent

             Case 4

                  Call incorporate1                '将输入的十进制从机地址、命令、资料地址和资料内容合并成字符串

                  Call deltaASCII

                  Call ASCIIsent

            End Select

End Sub

'十六进制发送

Private Sub Hexsent()

            Dim hexchrlen%, Hexchr As String, hexcyc%, hexmid As Byte, hexmiddle As String

            Dim hexchrgroup() As Byte, i As Integer

               hexchrlen = Len(Text1text)

               For hexcyc = 1 To hexchrlen                                                  '检查Text1文本框内数值是否合适

               Hexchr = Mid(Text1text, hexcyc, 1)

               If InStr("01234567ABCDEFabcdef", Hexchr) = 0 Then

                     MsgBox "无效的数值,请重新输入", , "错误信息"

                     Exit Sub

                End If

               Next

               ReDim hexchrgroup(1 To hexchrlen \\ 2) As Byte

               For hexcyc = 1 To hexchrlen Step 2                                         '将文本框内数值分成两个、两个

                     i = i + 1

                     Hexchr = Mid(Text1text, hexcyc, 2)

                     hexmid = Val("&H" & CStr(Hexchr))

                     hexchrgroup(i) = hexmid

                     'MSComm1.Output = CStr(hexmid)

               Next

               MSComm1.Output = hexchrgroup

End Sub

'ASC码发送

Private Sub ASCIIsent()

                MSComm1.Output = Text1text

End Sub

'ASC校验,此段程序计算出LRC校验值,并加上字头和字尾

Private Sub ASCIIcheck()

         Dim a%, b%, chrnum%, Lrcbyte As String

         Dim checksum%, char%, AscLrc%, Lrc%

         

         chrnum = Len(Text1text)

         For a = 1 To chrnum Step 2

            char = Val("&H" & CStr(Mid(Text1text, a, 2)))   '两个两个的取字符

            checksum = checksum + char                      '全部加起来

         Next

         AscLrc = checksum Mod &H100                        '取255的余数

         Lrc = (&HFF - AscLrc) + 1                                '取二次补

         If Lrc < 16 Then                                               '此段程序是判断Hex(lrc)是否是一位数,

             Lrcbyte = "0" + CStr(Hex(Lrc))                     '如果是的话,前面加0;否则不加零

        Else

            Lrcbyte = CStr(Hex(Lrc))

        End If

         Text1text = CStr(Chr(58)) & CStr(Text1text) & Lrcbyte & CStr(Chr(13)) & CStr(Chr(10))

End Sub

'DeltaASCII校验,此段程序计算出LRC校验值,并加上字头和字尾

Private Sub deltaASCII()

         Dim a%, b%, chrnum%, Lrcbyte As String

         Dim checksum%, char%, Lrc%

                  

         chrnum = Len(Text1text)

         For a = 1 To chrnum

            char = Asc(Mid(Text1text, a, 1))   '两个两个的取字符

            checksum = checksum + char                      '全部加起来

         Next

         Lrc = (checksum + &H3) Mod &H100                       '取255的余数

         If Lrc < 16 Then                                               '此段程序是判断Hex(lrc)是否是一位数,

             Lrcbyte = "0" + CStr(Hex(Lrc))                     '如果是的话,前面加0;否则不加零

        Else

            Lrcbyte = CStr(Hex(Lrc))

        End If

         Text1text = CStr(Chr(2)) & CStr(Text1text) & CStr(Chr(3)) & Lrcbyte

End Sub

'RTU校验

Private Sub RTUcheck()

        Dim CRC() As Byte

        Dim d(5) As Byte

        Dim string1 As String

        Dim j As Integer, chrlength As Integer, temp As String

        

        string1 = Text1text

        chrlength = Len(string1)

        For j = 0 To chrlength / 2 - 1

                  temp = Mid(string1, j * 2 + 1, 2)

                  d(j) = Val("&H" & temp)

        Next

        RTUCRC = CRC16(d)                         '调用CRC16计算函数, CRC(0)为高位,  CRC(1)为低位

        Text1text = Text1text & RTUCRC

End Sub

Private Sub incorporate()                                       '将输入的十进制从机地址、命令、资料地址和资料内容合并成字符串

       Dim wholechar As String, wc%, wcyc%, wchar As String

       Dim SID As String, Cmd As String, InfoAdd As String, data As String

       Dim SIDnum%, Cmdnum%, InfoAddNum%, Datanum%

       

      On Error Resume Next

        wholechar = CStr(Combo6.Text) & CStr(Text6.Text) & CStr(Text7.Text) & CStr(Text8.Text)

        wc = Len(wholechar)

        For wcyc = 1 To wc

            wchar = Mid(wholechar, wcyc, 1)

            If InStr("01234567", wchar) = 0 Then

                MsgBox "输入错误,请重新输入", , "错误提示"

                Exit Sub

            End If

        Next

             SIDnum = Len(CStr(Hex(Combo6.Text)))

              Select Case SIDnum

              Case 0

                Exit Sub

             Case 1

                 SID = "0" & CStr(Hex(Combo6.Text))

             Case 2

                 SID = CStr(Hex(Combo6.Text))

             End Select

             Cmdnum = Len(CStr(Hex(Text6.Text)))

             Select Case Cmdnum

             Case 0

                Exit Sub

             Case 1

                  Cmd = "0" & CStr(Hex(Text6.Text))

             Case 1

                  Cmd = CStr(Hex(Text6.Text))

             End Select

             

             InfoAddNum = Len(CStr(Hex(Text7.Text)))

             Select Case InfoAddNum

             Case 0

                Exit Sub

             Case 1

                  InfoAdd = "000" & CStr(Hex(Text7.Text))

             Case 2

                  InfoAdd = "00" & CStr(Hex(Text7.Text))

             Case 3

                  InfoAdd = "0" & CStr(Hex(Text7.Text))

             Case 4

                  InfoAdd = CStr(Hex(Text7.Text))

            End Select

                  

             Datanum = Len(CStr(Hex(Text8.Text)))

             Select Case Datanum

             Case 0

                Exit Sub

             Case 1

                  data = "000" & CStr(Hex(Text8.Text))

             Case 2

                  data = "00" & CStr(Hex(Text8.Text))

             Case 3

                  data = "0" & CStr(Hex(Text8.Text))

             Case 4

                  data = CStr(Hex(Text8.Text))

            End Select

            

           If Err Then                                                          '显示出错信息

               MsgBox Error$, 48, "错误信息"

                Exit Sub

           End If

            Text1text = CStr(SID) & CStr(Cmd) & CStr(InfoAdd) & CStr(data)

End Sub

Private Sub incorporate1()                                       '将输入的十进制从机地址、命令、资料地址和资料内容合并成字符串

       Dim wholechar As String, wc%, wcyc%, wchar As String

       Dim SID As String, Cmd As String, InfoAdd As String, data As String

       Dim SIDnum%, Cmdnum%, InfoAddNum%, Datanum%

       

      On Error Resume Next

        wholechar = CStr(Combo6.Text) & CStr(Text7.Text) & CStr(Text8.Text)

        wc = Len(wholechar)

        For wcyc = 1 To wc

            wchar = Mid(wholechar, wcyc, 1)

            If InStr("01234567", wchar) = 0 Then

                MsgBox "输入错误,请重新输入", , "错误提示"

                Exit Sub

            End If

        Next

             SIDnum = Len(CStr(Hex(Combo6.Text)))

              Select Case SIDnum

              Case 0

                Exit Sub

             Case 1

                 SID = "0" & CStr(Hex(Combo6.Text))

             Case 2

                 SID = CStr(Hex(Combo6.Text))

             End Select

            'Cmdnum = Len(CStr(Hex(Text6.Text)))

             'Select Case Cmdnum

             'Case 0

             '   Exit Sub

             'Case 1

             '     Cmd = "0" & CStr(Hex(Text6.Text))

             'Case 1

             '     Cmd = CStr(Hex(Text6.Text))

             'End Select

             

             InfoAddNum = Len(CStr(Hex(Text7.Text)))

             Select Case InfoAddNum

             Case 0

                Exit Sub

             Case 1

                  InfoAdd = "0" & CStr(Hex(Text7.Text))

             Case 2

                  InfoAdd = CStr(Hex(Text7.Text))

            End Select

                  

             Datanum = Len(CStr(Hex(Text8.Text)))

             Select Case Datanum

             Case 0

                Exit Sub

             Case 1

                  data = "000" & CStr(Hex(Text8.Text))

             Case 2

                  data = "00" & CStr(Hex(Text8.Text))

             Case 3

                  data = "0" & CStr(Hex(Text8.Text))

             Case 4

                  data = CStr(Hex(Text8.Text))

            End Select

            

           If Err Then                                                          '显示出错信息

               MsgBox Error$, 48, "错误信息"

                Exit Sub

           End If

            

            If Option11.value Then

                  Cmd = "08"

                  Text1text = CStr(SID) & CStr(Cmd) & CStr(InfoAdd)

             Else

                  Cmd = "07"

                  Text1text = CStr(SID) & CStr(Cmd) & CStr(InfoAdd) & CStr(data)

            End If

            

End Sub

Private Function CRC16(data() As Byte) As String

      Dim CRC16Lo As Byte, CRC16Hi As Byte      'CRC寄存器

      Dim CL As Byte, CH As Byte                '多项式码&HA001

      Dim CRCLo As String, CRCHi As String

      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

      If Len(Hex(CRC16Hi)) = 1 Then

         CRCHi = "0" + Hex(CRC16Hi)

      Else

         CRCHi = Hex(CRC16Hi)

      End If

      If Len(Hex(CRC16Lo)) = 1 Then

         CRCLo = "0" + Hex(CRC16Lo)

      Else

         CRCLo = Hex(CRC16Lo)

      End If

         CRC16 = CRCLo + CRCHi

  End Function

 下载本文

显示全文
专题