ModbusTcp和ModbusRtu

ModbusTcp和ModbusRtu

自己实现的modbusTCP主从站和RTU主从站。纯C语言实现,未调用第三方库,工程下载链接:
modbusTcp主从站和RTU主从站

1、何为Modbus通信协议

1.1 Modbus基本介绍

Modbus协议介绍:Modbus是 OSI 模型第 7 层上的应用层报文传输协议,它在连接至不同类型总线或网络的设备之间提供客户机/服务器通信。包括了ASCII、RTU、TCP三种报文类型,协议本身并没有定义物理层,定义了控制器能够认识和使用的消息结构,不管它们是经过何种网络进行通信的。Modbus协议使用串口传输时可以选择RTU或者ASCII模式,并规定了消息、数据结构、命令和应答方式,且需要对数据进行校验。ASCII模式采用LRC校验,RTU模式采用16位CRC校验。通过以太网传输时使用TCP,这种模式下不使用校验,因为TCP协议是一个面向连接的可靠协议。

在这里插入图片描述

​ 图1-1 ISO/OSI模型

**常用通信协议:**ModbusTcp/ModbusRtu/ModbusAscii

Modbus发展迅速的原因:

  • 开源免费
  • 可以在多种电气接口及多种通信介质中使用
    • 常用通信介质:双绞线、光纤、红外、无线等
    • 常用电气接口:RS232、RS485、TCP/IP等
  • 报文帧简单紧凑

1.2 通信过程

  • 通过Modbus协议,控制器相互之间、或控制器经由网络(如以太网)可以和其它设备之间进行通信。Modbus协议使用的是主从通讯技术,即由主设备主动查询和操作从设备。一般将主控设备方所使用的协议称为Modbus Master,从设备方使用的协议称为Modbus Slave。典型的主设备包括工控机和工业控制器等;典型的从设备如PLC可编程控制器等。

  • Modbus的工作方式是请求/应答,每次通讯都是主站先发送指令,可以是广播,或是向特定从站的单播;从站响应指令,并按要求应答,或者报告异常。当主站不发送请求时,从站不会自己发出数据,从站和从站之间不能直接通讯 。

  • Modbus通讯物理接口可以选择串口,也可以选择以太网。它的通信遵循以下过程:

    • 主设备向从设备发送请求
    • 从设备分析并处理主设备的请求,然后向主设备发送结果
    • 如果出现任何差错,从设备将返回一个异常功能码

1.3 Modbus通讯方式

  • MODBUS 协议允许在各种网络体系结构内进行简单通信。每种设备(PLC、HMI、控制面板、驱动程序、动作控制、输入/输出设备)都能使用 MODBUS协议来启动远程操作。

Modbus有下列三种通信方式:

  • 以太网:对应的通信模式是Modbus TCP/IP

  • 异步串行传输(各种介质如有线RS-232-/422/485/;光纤、无线等):对应的通信模式是Modbus RTUModbus ASCII

  • 高速令牌传递网络:对应的通信模式是Modbus PLUS

Modbus RTU和Modbus ASCII协议应用于串口链接(RS232、RS485、RS422),Modbus tcp/ip协议应用于以太网链接


1.4 Modbus存储区

数据类型:布尔量、寄存器

读写性:只读、读写

四种存储区:

  • 只读布尔量:输入线圈 1区 范围:10001-19999
  • 读写布尔量:输出线圈 0区 范围:00001-09999
  • 只读寄存器:输入寄存器 3区 范围:30001-39999
  • 读写寄存器:输出寄存器 4区 范围:40001-49999

1.5 专业术语解释

缩写含义解释
ADU应用数据单元
HDLC高级数据链路控制
HMI人机界面
IETF因特网工程工作组
I/O输入/输出设备
IP互连网协议
MAC介质访问控制
MBMODBUS 协议
MBAPMODBUS 协议
PDU协议数据单元
PLC可编程逻辑控制器
TCP传输控制协议

2、ModbusRTU传输模式

2.1 ModbusRTU如何判断开始与结束

  • ModbusRTU协议中,需要用时间间隔来判断一帧报文的开始和结束,协议规定的时间为3.5个字符周期。在一帧报文开始前,必须有大于3.5个字符周期的空闲时间,一帧报文结束后,也必须要有3.5个字符周期的空闲时间,否则就会出现粘包的请况。3.5个字符周期是一个具体时间,与波特率有关

在这里插入图片描述

​ 图2-1 RTU报文帧

  • 整个报文帧必须以连续的字符流发送。如果两个字符之间的空闲间隔大于 1.5 个字符时间,则报文帧被认为不完整应该被接收节点丢弃。

2.2 CRC循环冗余校验

  • 在 RTU 模式包含一个对全部报文内容执行的,基于循环冗余校验 (CRC - Cyclical Redundancy Checking) 算法的错误检验域。CRC 域检验整个报文的内容。不管报文有无奇偶校验,均执行此检验。

    1)CRC有16位,由两个字节组成

    2)CRC附加在报文最后面,先附加低字节,再附加高字节。

    3)附加在报文后面的 CRC 的值由发送设备计算。接收设备在接收报文时重新计算 CRC 的值,并将计算结果于实际接收到的CRC 值相比较。如果两个值不相等,则为错误。

  • 计算过程:

    CRC 的计算, 开始对一个 16 位寄存器预装全 1。 然后将报文中的连续的 8 位子节对其进行后续的计算。只有字符中的 8 个数据位参与生成 CRC 的运算,起始位,停止位和校验位不参与 CRC计算。CRC 的生成过程中, 每个 8–位字符与寄存器中的值异或。然后结果向最低有效位(LSB)方向移动(Shift) 1 位,而最高有效位(MSB)位置充零。 然后提取并检查 LSB:如果 LSB 为 1, 则寄存器中的值与一个固定的预置值异或;如果 LSB 为 0, 则不进行异或操作。这个过程将重复直到执行完 8 次移位。完成最后一次(第 8 次)移位及相关操作后,下一个 8位字节与寄存器的当前值异或,然后又同上面描述过的一样重复 8 次。当所有报文中子节都运算之后得到的寄存器忠的最终值,就是 CRC。


2.2 ModbusRTU在串行链路中的报文格式

格式:

从站地址(1 byte)+功能码(1 byte)+数据区(N bytes)+校验码(2 bytes)

解释:

从站地址:一个字节,作用是索引

功能码:一个字节,表明读写功能

数据:通信所传输的数据,可以是多字节

校验:判断接收的数据在传输过程中是否有损失,两个字节


2.3 功能码描述


2.3.1 读取输出线圈
  • 发送报文格式:
从站地址功能码起始(高)起始(低)数量(高)数量(低)校验码
0x010x010x000x130x000x1BXXXX

报文含义解释:读1号从站的输出线圈,起始地址是0x13=19,对应的地址为00020,线圈数量为0x1B=27。即读取1号从站输出线圈,地址是00020-00046,一共27个线圈的状态值。

***注意:***起始地址是0x13是用来索引的,对应的地址为00020才是具体的地址,它是与存储区相关的。

  • 返回报文格式:
从站地址功能码字节计数字节一字节二字节三字节四校验码
0x010x010x040xCD0x6B0xB20x05XXXX

返回报文含义:返回1号从站输出线圈00020-00046,一共27个线圈的状态值,返回的字节数为4个,分别为CD、6B、B2、05


2.3.2 读取输入线圈
  • 发送报文格式
从站地址功能码起始(高)起始(低)数量(高)数量(低)校验码
0x010x020x000xC40x000x1DXXXX

发送报文含义:读取1号从站输入线圈,起始地址为0xC4=196,对应地址为10197,线圈数量为0x1D=29,即读取1号从站输入线圈,地址从10197-10255,一共29个线圈的状态值

  • 返回报文格式
从站地址功能码字节计数字节1字节2字节3字节4校验
0x010x020x040xCD0x6B0xB20x05XXXX

返回报文含义:返回1号从站输入线圈10197-10255,共29个线圈的状态值 ,返回字节数为4个,分别为CD、6B、B2、05。


2.3.3 读取输出寄存器
  • 发送报文格式
从站地址功能码起始(高)起始(低)数量(高)数量(低)校验码
0x010x030x000x6B0x000x02XXXX

发送报文含义:读取1号从站输出寄存器,起始地址为0x6B=107,对应地址为40108,寄存器数量为0x02=2,即读取1号从站输出寄存器,地址从40108-40109,共2个寄存器的数值

  • 返回报文格式
从站地址功能码字节计数1高1低2高2低校验
0x010x030x040x020x2B0x010x06XXXX

返回报文含义:返回1号从站输出寄存器40108-40109,共2个寄存器的数值,返回字节数为4个,分别为02、2B、01、06,40108对应数值为0x022B,40109对应数值为0x0106


2.3.4 读取输入寄存器
  • 发送报文格式
从站地址功能码起始(高)起始(低)数量(高)数量(低)校验码
0x010x040x000x6B0x000x02XXXX

发送报文含义:读取1号从站输入寄存器,起始地址为0x6B=107,对应地址为30108,寄存器数量为0x02=2,即读取1号从站输入寄存器,地址从30108-30109,共两个寄存器

  • 返回报文格式
从站地址功能码字节计数1高1低2高2低校验
0x010x040x040x020x2B0x010x06XXXX

返回报文含义:返回1号从站输入寄存器30108-30109,共2个寄存器的数值,返回字节数为4个,分别为02、2B、01、06,30108对应数值为0x022B,30109对应的数值为0x0106


2.3.5 写入单个输出线圈
  • 发送报文格式
从站地址功能码线圈(高)线圈(低)断通标志断通标志校验
0x010x050x000xAC0xFF0x00XXXX

发送报文含义:预置1号从站单个线圈的值,线圈地址为0x00AC=172,对应地址为00173,断通标志0xFF表示置位,0x0000表示复位,即置位1号从站输出线圈00173

  • 返回报文格式
从站地址功能码线圈(高)线圈(低)断通标志断通标志校验
0x010x050x000xAC0xFF0x00XXXX

返回报文含义:预置单输出线圈原报文返回


2.3.6 写入单个输出寄存器
  • 发送报文格式如下:
从站地址功能码寄存器高寄存器低写入值高写入值低校验
0x010x060x000x870x030x9EXXXX

发送报文含义:预置1号从站单个输出寄存器的值,寄存器地址为0x0087=135,对应地址为40136,写入值为0x039E,即预置1号从站输出寄存器40136值为0x039E。

  • 返回报文格式如下:
从站地址功能码寄存器高寄存器低写入值高写入值低校验
0x010x060x000x870x030x9EXXXX

返回报文含义:预置单输出寄存器原报文返回。


2.3.7 写入多个输出线圈
  • 发送报文格式如下:
从站地址功能码起始高起始低数量高数量低字节数字节1字节2字节N校验
0x010x0F0x000x130x000x0A0x020xCD0x00XXXXXXXX

发送报文含义:预置1号从站多个线圈的值,线圈地址为0x0013=19,对应地址为00020,线圈数为0x0A=10,写入值为0xCD00,即预置1号从站线圈00020-00027=0xCD=11001101,00028-00029=0x00=0000 0000。

  • 返回报文格式如下:
从站地址功能码起始高起始低数量高数量低校验
0x010x0F0x000x130x000x0AXXXX

返回报文含义:预置多输出线圈返回报文是在原报文基础上除去字节数及具体字节后返回。


2.3.8 写入多个输出寄存器
  • 发送报文格式如下:
从站地址功能码起始高起始低数量高数量低字节数字节校验
0x010x100x000x870x000x020x040x01050A10XXXX

发送报文含义:预置1号从站多个寄存器的值,寄存器地址为0x0087=135,起始地址为40136,寄存器数量为0x02=2,结束地址为40137,写入值为0x0105和0x0A10,即预置1号从站寄存器40136=0x0105,40137=0x0A10。

  • 返回报文格式如下:
从站地址功能码起始高起始低数量高数量低校验
0x010x100x000x870x000x02XXXX

返回报文含义:预置多输出寄存器返回报文是在原报文基础上除去字节数及具体字节后返回。


3、ModbusASCII传输模式

1)ModbusRTU与ModbusASCII在报文数据发送格式上几乎一样,但也存在一些区别,具体体现在:

  • ModbusASCII有开始字符和结束字符(CR LF),可以作为一帧数据开始和结束的标志,而ModbusRTU没有这样的标。
  • 两者校验方式不同,ModbusRTU是CRC循环冗余校验,ModbusASCII是LCR纵向冗余校验。
  • 在Modbus标准中,RTU是必须要求的,而ASCII是可选项,即作为一个Modbus通信设备可以只支持RTU,也可以同时支持RTU和ASCII,但不能只支持ASCII。

2)当控制器设为在Modbus网络上以ASCII(美国标准信息交换代码)模式通信,在消息中的每个8Bit字节都作为两个ASCII字符发送。这种方式的主要优点是字符发送的时间间隔可达到1秒而不产生错误。报文中字符间的时间间隔可以达一秒,但如果有更大的间隔,则接受设备认为发生了错误。

代码系统:

  • 十六进制,ASCII字符0-9,A-F
  • 消息中的每个ASCII字符都是一个十六进制字符组成
  • 1 起始位、7 数据位, 首先发送最低有效位、1 位作为奇偶校验、1 停止位(有校验是1个停止位,无校验时2个停止位)
  • 错误检测域:LRC(纵向冗长检测)

在这里插入图片描述
在这里插入图片描述


4、ModbusTCP

4.1 ModbusTCP介绍

在Modbus TCP/IP协议中,串行链路中的主/从设备分别演变为客户端/服务器端设备。即客户端相当于主站设备,服务器端相当于从站设备。基于TCP/IP网络的传输特性,串行链路上一主多从的构造也演变为多客户端/多服务器端的构造模型。Modbus TCP/IP服务器端通常使用端口502作为接收报文的端口, IANA(Internet Assigned Numbers Authority,互联网编号分配管理机构)给Modbus协议赋予TCP端口号为502,这是目前在仪表与自动化行业中唯一分配到的端口号。

其通信过程:

A、connect 建立TCP连接

B、准备Modbus报文

C、使用send命令发送报文

D、在同一连接下等待应答

E、使用recv命令读取报文,完成一次数据交换

F、通信任务结束时,关闭TCP连接

格式:

MBAP(7 byte) + 功能码(1 byte) + 数据(N byte)

在这里插入图片描述

MBAP为报文头,长度为7字节。

报文头能提供一些与串行链路上使用的 MODBUS RTU 应用数据单元比较的差别:

  • 用MBAP报文头中的单个字节单元标识符取代MODBUS串行链路上通常使用的MODBUS
    从地址域。这个单元标识符用于设备的通信,这些设备使用单个 IP 地址支持多个独立
    MODBUS 终端单元,例如:网桥、路由器和网关。
  • 用接收者可以验证完成报文的方式设计所有 MODBUS 请求和响应。对于 MODBUS PDU
    有固定长度的功能码来说,仅功能码就足够了。对于在请求或响应中携带一个可变数据的
    功能码来说,数据域包括字节数。
  • 当在 TCP 上携带 MODBUS 时,即使将报文分成多个信息包来传输,办事在 MBAP 报文头
    上携带附加长度信息,以便接收者能识别报文边界。显式和隐式长度规则的存在以及
    CRC-32 差错校验码的使用(在以太网上)将对请求或响应报文产生极小的未检出干扰。

组成如下:

在这里插入图片描述

  • 事务处理标识符:用于事务处理配对。在响应中,MODBUS 服务器复制请求的事务处理标识符。没有实质意义,就像序号一样。
  • 协议标识符:用于系统内的多路复用。通过值 0 识别 MODBUS 协议。
  • 长度:长度域是下一个域的字节数,包括单元标识符和数据域。
  • 单元标识符:为了系统内路由,使用这个域。专门用于通过以太网 TCP-IP 网络和 MODBUS 串行链路之间的网关对 MODBUS 或 MODBUS+串行链路从站的通信。MODBUS 客户机在请求中设置这个域,在响应中服务器必须利用相同的值返回这个域。(也就是从站地址)

3.2 功能码描述

其只是报文头与RTU模式有区别,同时没有校验码,中间数据域是完全一致的

例如读输出寄存器:

  • 发送报文格式
事务/协议长度单元标识功能码起始高起始低数量高数量低
0x000000000x00060x010x030x000x6B0x000x02

发送报文含义:读取服务器1号从站输出寄存器,起始地址为0x6B=107(相对地址),对应地址为40108,寄存器数量为0x02=2,即读取1号从站输出寄存器,地址从40108-40109,共两个寄存器的数值。

  • 返回报文格式
事务/协议长度单元标识功能码字节计数1高1低2高2低
0x000000000x00070x010x030x040x020x2B0x010x06

返回报文含义:返回服务器1号从站输出寄存器40108-40109,共2个寄存器的数值,返回字节数为4个,分别为02、2B、01、06,40108对应数值为0x022B,40109对应数值为0x0106


3、功能码

3.1 功能码分类

一共有三类Modbus功能码:公共功能码、用户定义功能码、保留功能码

在这里插入图片描述

​ 图3-1 Modbus 功能码分类

1)公共功能码

  • 是较好地被定义的功能码
  • 保证是唯一的
  • MODBUS 组织可改变的
  • 公开证明的
  • 具有可用的一致性测试
  • MB IETF RFC 中证明的
  • 包含已被定义的公共指配功能码和未来使用的未指配保留供功能码

2)用户定义功能码

  • 有两个用户定义功能码的定义范围,即 65 至 72 和十进制 100 至 110
  • 用户没有 MODBUS 组织的任何批准就可以选择和实现一个功能码
  • 不能保证被选功能码的使用是唯一的
  • 如果用户要重新设置功能作为一个公共功能码,那么用户必须启动 RFC,以便将改变引入
    公共分类中,并且指配一个新的公共功能码。

3)保留功能码

  • 一些公司对传统产品通常使用的功能码,并且对公共使用是无效的功能码

3.2 常用功能码

  • 读取输出线圈 0x01
  • 读取输入线圈 0x02
  • 读取输出寄存器 0x03
  • 读取输入寄存器 0x04
  • 写入单个输出线圈 0x05
  • 写入多个输出线圈 0x0F
  • 写入单个输出寄存器 0x06
  • 写入多个输出寄存器 0x10


4、Modbus异常响应

4.1 响应结果

当客户机设备向服务器设备发送请求时,客户机希望一个正常响应。从主站询问中出现下列四种可能事件之一:

  • 如果服务器设备接收到无通信错误的请求,并且可以正常地处理询问,那么服务器设备将
    返回一个正常响应。
  • 如果由于通信错误,服务器没有接收到请求,那么不能返回响应。客户机程序将最终处理
    请求的超时状态。
  • 如果服务器接收到请求,但是检测到一个通信错误(奇偶校验、LRC、CRC、…),那么不
    能返回响应。客户机程序将最终处理请求的超时状态。
  • 如果服务器接收到无通信错误的请求,但不能处理这个请求(例如,如果请求读一个不存
    在的输出或寄存器),服务器将返回一个异常响应,通知用户错误的本质特性。

4.2 异常响应报文

异常响应报文有两个与正常响应不同的域:

  • **功能码域:**在正常响应中,服务器利用响应功能码域来应答最初请求的功能码。所有功能码的最高有效位(MSB)都为 0(它们的值都低于十六进制 80)。在异常响应中,服务器设置功能码的MSB 为 1。这使得异常响应中的功能码值比正常响应中的功能码值高。通过设置功能码的 MSB,客户机的应用程序能够识别异常响应,并且能够检测异常码的数据域。
  • **数据域:**在正常响应中,服务器可以返回数据域中数据或统计表(请求中要求的任何报文)。在异常响应中,服务器返回数据域中的异常码。这就定义了产生异常的服务器状态。

在这里插入图片描述

​ 图4-1 Modbus事务处理_无差错

在这里插入图片描述

​ 图4-2 Modbus事务处理_异常响应


4.3 异常码

代码名称含义
01非法功能对于服务器(或从站)来说,询问中接收到的功能码是不可允许的操作。这也许是因为功能码仅仅适用于新设备而在被选单元中是不可实现的。同时,还指出服务器(或从站)在错误状态中处理这种请求,例如:因为它是未配置的,并且要求返回寄存器值。
02非法数据地址对于服务器(或从站)来说,询问中接收到的数据地址是不可允许的地址。特别是,参考号和传输长度的组合是无效的。对于带有 100 个寄存器的控制器来说,带有偏移量 96 和长度 4 的请求会成功,带有偏移量 96 和长度 5 的请求将产生异常码 02。
03非法数据值对于服务器(或从站)来说,询问中包括的值是不可允许的值。这个值指示了组合请求剩余结构中的故障,例如:隐含长度是不正确的。并不意味着,因为MODBUS 协议不知道任何特殊寄存器的任何特殊值的重要意义,寄存器中被提交存储的数据项有一个应用程序期望之外的值。
04从站设备故障当服务器(或从站)正在设法执行请求的操作时,产生不可重新获得的差错。
05确认与编程命令一起使用。服务器(或从站)已经接受请求,并且正在处理这个请求,但是需要长的持续时间进行这些操作。返回这个响应防止在客户机(或主站)中发生超时错误。客户机(或主站)可以继续发送轮询程序完成报文来确定是否完成处理。
06从属设备忙与编程命令一起使用。服务器(或从站)正在处理长持续时间的程序命令。当服务器(或从站)空闲时,用户(或主站)应该稍后重新传输报文。
0A不可用网关路径与网关一起使用,指示网关不能为处理请求分配输入端口至输出端口的内部通信路径。通常意味着网关是错误配置的或过载的。
0B网关目标设备响应失败与网关一起使用,指示没有从目标设备中获得响应。通常意味着设备未在网络中。

5、Modbus功能码与线圈类型对比

功能码功能解释数据类型(对应于Modbus的数据区0x 1x 3x 4x)Function(对应于ModbusSlave软件的Function)
16(0x10)写多个输出寄存器【4x】【03】
15(0x0F)写多个输出线圈【0x】【01】
06(0x06)写单个输出寄存器【4x】【03】
05(0x05)写单个输出线圈【0x】【01】
04(0x04)读输入寄存器【3x】【04】
03(0x03)读输出寄存器【4x】【03】
02(0x02)读输入线圈【1x】【02】
01(0x01)读输出线圈【0x】【01】
  • 39
    点赞
  • 142
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值