新闻资讯
  技术专题
  首页 > 新闻资讯 > 技术专题

MODBUS通讯上位机的简单制作

时间:2017-01-20 来源:百特工控 浏览:1 字号:
  文章开始,先简单介绍一下modbus协议。

  MODBUS是OSI模型第7层上的应用层报文传输协议,它在连接至不同类型总线或网络的设备之间提供客户机/服务器通信。自1979年出现工业串行链路的实施标准以来,MODBUS使成千上万的自动化设备能够进行通信。MODBUS 是一个请求/应答协议,并且提供功能码规定的服务。

目前,使用下列情况实现MODBUS:

1、以太网上的TCP/IP。

2、各种媒体:有线EIA/TIA-232-E、EIA-422、EIA/TIA-485-A(习惯地称之为RS-485标准);光纤、无线等等上的异步串行传输。

3、MODBUS PLUS,一种高速令牌传递网络。

    去烦就简,在实际使用当中我们只要注意它的格式就可以了;而我们最常用的是在RS-485上使用MODBUS协议。其中最重要指令是读写寄存器,介绍如下:

    03功能码 功能:读保持寄存器

请求

地址(1 个字节)+ 功能码(0x03)+起始地址(2 个字节)+寄存器数量(2 个字节)+校验码(2 个字节)

应答   

地址(1 个字节)+  功能码 (0x03)+ 字节数( 1 个字节)+寄存器值(寄存器数量×2个字节)+校验码(2 个字节)

例如:   发送     01 03 00 00 00 02 C4 0B  // 读取寄存器地址00和01的值

         接收     01 03 04 00 00 00 01 3B F3   //返回寄存器地址00的值0,寄存器地址01的值01 。

 

 

   06 功能码 功能:写单个寄存器

请求

地址(1 个字节)+功能码(0x06)+寄存器地址(2 个字节)+寄存器值2 个字节+校验码(2 个字节)

应答   

地址(1 个字节)+  功能码 (0x03)+寄存器地址(2 个字节)+寄存器值(2 个字节)+校验码(2 个字节)

例如:   发送 01 06 00 01 00 01 19 CA   //写寄存器01值 01

        接收    01 06 00 01 00 01 19 CA 

 

16 功能码 功能:写多个寄存器

请求

地址(1 个字节)+功能码(0x10)+起始地址(2 个字节)+寄存器数量(2 个字节)

+字节数(1 个字节)+寄存器值(寄存器数量×2 个字节)+校验码(2 个字节)

应答

地址(1 个字节)+功能码(0x10)+起始地址(2 个字节)+寄存器数量(2 个字节)

+校验码(2 个字节)

 

 

例如   发送 01 10 00 00 00 02 04 00 00 00 01 32 6F //寄存器00写入00,寄存器01写入01

接收 01 10 00 00 00 02 41 C8               

    有了以上内容就可以制作上位机软件,由于前面用的一台电脑出故障,使用另台电脑时,发现原来的使用者安装好了VisualBasic6.0,在硬件条件具备的情况下,尝试做了个针对性的测试软件。

    先介绍下串口控件MSComm,打开属性页如下图

里面的设置为大家所熟悉的端口号、波特率、校验位等;因此串口的设置不复杂,与串口调试助手设置差不多。

初始化如下L

    MSComm.CommPort=Port  ' 设定端口

    MSComm.Settings = BaudRate & "," & ParityBit & "," & DataBit & "," & StopBit ' 设置波特率,无校验,8位数据位,1位停止位

    MSComm.InBufferSize=1024  ' 设置接收缓冲区为1024字节

    MSComm.OutBufferSize=4096 ' 设置发送缓冲区为4096字节

    MSComm.InBufferCount=0     ' 清空输入缓冲区

    MSComm.OutBufferCount=0    ' 清空输出缓冲区

    MSComm.SThreshold=1        ' 发送缓冲区空触发发送事件

    MSComm.RThreshold=1        ' 每X个字符到接收缓冲区引起触发接收事件

    MSComm.OutBufferCount=0    ' 清空发送缓冲区

    MSComm.InBufferCount=0     ' 清空接收缓冲

MSComm.PortOpen=True       ' 打开串口

 

数据的接收

   ReceiveArr=MSComm.Input           ' 数据放入数组

数据的发送

   MSComm.Output=SendArr               ' 发送数据

 

有了以上的串口内容,笔者就开始尝试编写一个串口调试助手,然后根据接收的数据,经过处理就可以完成一个MODBUS通信测试软件了。但是很快发现制做一个串口调试助手需要花费时间还是比较多的,而且是一个大家常用的软件,那么是否有源代码呢?通过别人的原代码修改可以事半功倍。果然,网上有完整的代码,还有其它语言的代码。这样就找了个功能相对完整的串口RS485调试助手如图:

经过测试发现这个软件不完善:1、需要先发送数据之后,才能正常接收数据;2、长的数据被分成几个接收。对于第一问题不影响使用,如前所述MODBUS 是一个请求/应答协议,一发一收,上位机需要先发数据。对于第二个问题,修改中断方式,利用定时器中断,然后控制好接收时间就可以了。

接下来就是数据的处理,MODBUS后面两字节采用的是CRC校验,计算效验码是个难点。代码如下:

Dim CRC1 As String

Public Sub CRC(STR1 As String)

Dim CRCREG As Long

Dim MVAL As Long

Dim R As Integer

Dim t As Long

Dim a As Long

Dim B As Long

CRCREG = 65535

For R = 1 To Len(STR1) Step 2

MVAL = Val("&H" + Mid(STR1, R, 2))

CRCREG = CRCREG Xor MVAL

CRCREG = CRCREG And 65535

For t = 1 To 8 Step 1

If (CRCREG And &H1) Then

CRCREG = (CRCREG \ 2) Xor &HA001

CRCREG = CRCREG And 65535

Else:

CRCREG = CRCREG \ 2

CRCREG = CRCREG And 65535

End If

Next

Next

 

a = CRCREG And 255

B = CRCREG And 65280

a = a * 256

B = B / 256

 

If (a + B) < 16 Then

CRC1 = "000" + Hex(a + B)

ElseIf (a + B) < 256 Then

CRC1 = "00" + Hex(a + B)

ElseIf (a + B) < 4096 Then

CRC1 = "0" + Hex(a + B)

Else

CRC1 = Hex(a + B)

End If

End Sub

 

接下来就是对号入座了。原本打算给每个寄存器放一个读按键和写按键,后面发现单个读取写入不实用,改成一次读取多个参数。由于有一百多个寄存器超过了上限,因此分两条指令,收到第一条应答后发送第二条,写参数也是同样的处理。

读参数的处理

Select Case i 'i代表寄存器

Case 0

Case 1

     c1.Text = ReceiveArr(i * 2 + 4 - commandstart * 2)

               

 

写参数的处理:

        Select Case i

            Case 1 '代表寄存器

                DATA_SENT(i * 2 + 7) = 0

                If Int(ADDR.Text) < 100 Then

                DATA_SENT(i * 2 + 7 + 1) = Int(ADDR.Text)

                Else

                err.Show’超过输入范围,跳出提示框

                GoTo Err

                End If

 

完成的软件如下:

 

这是笔者制作的第一个完整的VB软件,之前也曾想制作类似的软件,每次都是望而却步。制作这个软件时也是抱着试试的心理。在此分享给大家,也让大家借此机会了解下MODBUS,同时可以借鉴本例,制作属于自己的工具。

  
客服中心X
  • 在线客服
  • 点击这里给我发消息  客服
  • 在线时间
  • 9:00 - 17:00
在线客服