资讯详情

modbus协议学习笔记

前言

??在学习modbus在协议之前,读者最好有串行通信的基本知识。串行通信是指通过串行传输数据的通信,即只使用一条数据线一个接一个地传输数据,每个数据占据一个固定的时间长度。这样,设备之间的数据交互只需要几条线。UART、IIC、SPI等都是使用串行通信方式。

??我们最熟悉的单片UART一开始,我们知道数据交互可以通过串口电路和已经制定的串口通信协议来实现。然而,由于导线中的电平容易受到外界的干扰,因为导线中的电平容易受到外部干扰,可能导致信息传输错误。为了解决这个问题,出现了RS-485传输标准。如图是RS-485电路示意图,MCU_生成发送端TTL电平通过电平转换电路后,变成AB两根导线之间的差异信号。当MCU转换器输入低电平时,转换器会使B的电压高于A,反之,A电压高于B。然后通过电平转换电路将差分信号转换成MUC_2能够识别的TTL信号。

在这里插入图片描述

??RS-485传输方式具有以下特点:

??1)差异传输增加噪声抗扰度,降低噪声辐射; ??2)长距离链路最长可达4000英尺(约1219米); ??3)数据速率高达10Mbps(40英寸内约12英寸.2米); ??4)同一总线可连接多个驱动器和接收器; ??5)宽共模范围允许驱动器和接收器之间的地电位差,允许最大共模电压-7-12V ?

? ?由此可见,RS-485电路是单片机串口的扩展,可以提高通信电路的抗干扰能力,增加传输距离。

??到目前为止,设备之间的数据传输问题已经得到了解决,但显然还有一些问题没有考虑。首先,如果通信网络上有多个设备,发送设备应该如何指定哪个设备应该接收这个消息?第二,接收设备收到消息后,如何分析消息?要想解决这些问题,设备厂家们可以定义一种在UART协议上的上层协议约定了一些规则。但是,如果每个制造商都设计了不同的协议,则不同制造商的设备之间存在通信问题。由此,Modbus显示了协议的意义。

1 Modbus协议概要

??Modbus通信协议由Modicon公司(现施耐德电气)Schneider Electric)可编程逻辑控制于1979年(即PLC)发布通信。目前,Modbus已成为工业通信协议的行业标准,是工业电子设备之间常用的连接方式。Modbus与其他通信协议相比,作为工业领域应用最广泛的协议,具有以下特点:

??1. Modbus协议标准开放、公开发布,无版权要求。

??2.Modbus协议支持各种电气接口,包括RS232、RS485、TCP/IP等,还可以在各种介质上传输,如双绞线、光纤、红外、无线等。

??3.Modbus协议信息帧格式简单、紧凑、易于理解。用户理解和使用简单,制造商易于开发和集成,便于形成工业控制网络。

??该协议定义了控制器可以知道的信息结构,无论它们通过什么网络通信;并描述了控制器请求访问其他设备的过程,如何响应其他设备的请求,以及如何检测和记录错误;并制定了统一的信息域结构和内容。

??Modbus协议是单主/多从的通信协议。同时,总线上只能有一个主设备,但可以有一个或多个从设备(最多247个)。Modbus通信总是由主设备启动,当设备没有收到独立设备的请求时,数据不会主动发送。设备之间不能相互通信。

??主设备可以通过两种方式向设备发送modbus请求:

  • 单播模式:主设备仅从设备寻址,从设备接收处理请求后,将响应报告返回主设备。

  • 广播模式:主设备向总线上的所有设备发送请求,设备收到请求指令后,只处理相关事项而不返回响应。因此,在广播模式下,请求指令只能是modbus在标准功能中写指令,而不是读指令。地址0被保留为广播地址。

2 Modbus消息帧

??寻找简单的通信格式,Modbus协议定义了PDU(Protocol Data Unit)模型,即功能码 数据帧格式;在PDU在此基础上,增加了必要的前缀(如地址域)和后缀(如错误验证),形成了ADU(Application Data Unit)模型。

???图2-1 通用消息帧格式 ??Modbus协议包含ASCII、RTU、TCP三种传输方式。使用串口传输数据时可选择ASCII或RTU模式。所有设备必须保持同一网络的统一模式。新闻帧格式在不同模式下有所不同。

2.1 Modbus ASCII消息帧

??在ASCII在模式中,消息中的每个字节都将被用作两个字节ASCII发送字符,如0x53要分成0x35(5的ASCII码)和0x33(3的ASCII两个字节发送,传输效率低。

??在这种模式下,新闻帧冒号(:)字符(ASCII码为0x3A)从回车换行符开始(ASCII码为0x0A,0x0D)结束。其他字段可以使用的字符是16进制的0…9,A…F。网络上的设备不断检测:字符。当冒号收到时,每个设备进入解码阶段,解码下一个字段(地址域),判断信息是否发送给自己。字符间的发送间隔不得超过1秒,否则接收设备将被视为传输错误。 ??一个典型的ASCII如表所示:

???表2-1 Modbus ASCII消息帧格式

2.2 Modbus RTU消息帧

??在RTU在模式中,新闻帧没有起始字符和结束字符,而是使用T3.5作为两帧数据的分隔标志。在实际使用中,网络中的设备不断检测字符间的停顿时间间隔,判断信息帧的起点。在收到第一个字节(地址域)时,判断信息是否发给自己。最后一个字符传输结束后,至少一个T3.停顿代表消息的结束,而新消息可以在停顿后开始。此外,在一帧数据中,如果两个字符之间的空闲间隔大于T1.5.如果你认为报纸不完整,报纸将被丢弃。

??T3.5即3.在串行通信中,一个字符通常包括1个起始位、8个数据位、1个奇偶验证位和1个停止位。这样,一个字符包括11个,然后是3个.5个字符就是38.5位。

??在串行通信中,波特率代表每秒传输二进制位数,如波特率为9600bps每秒9600bit。那么传输38.5bit的时间为

(38.5/9600)*1000ms = 4.0104167ms

??在波特率为9600bps的情况下,ModbusRTU前一帧数据结束和后一帧数据开始的时间间隔大于4.0104167ms。

???2-2 Modbus RTU相邻帧间隔

???图2-3 Modbus RTU消息帧格式

??为了实现RTU对于通信中的时间间隔管理,定时器会导致大量的中断处理,这将导致高波特率CPU沉重的负担。因此,协议规定波特率大于19200bps建议时间间隔使用固定值T1.5为750us,T3.5为1750us。

2.3 地址域

??地址码是信息帧的第一个字节(8位),从0到255。每个机器都必须有一个唯一的地址。地址有三个功能:第一,主机发出指令时,可以指定哪个机器接受指令;第二,从机器回复消息时,主机可以知道信息来自哪里;第三,从机器回复消息时,其他机器不会误认为是主机发出的请求。

??如果地址为0,则视为广播命令,即所有从机器接收和处理主机发送的信息。 ???表2-2 Modbus寻址范围

2.4 功能码域

??功能代码域由一个字节组成,其值范围为1至127。从设备根据功能代码执行相应的动作。执行完成后,正常情况下,机器响应的功能代码与主机发布的功能代码相同。如有异常,功能代码的最高位置为1(129~255代表异常码)。因此,主设备可以从设备的执行中获得。

??此外,对于主设备发送的功能码,是否支持该功能码由设备根据具体配置决定,如果不支持,则返回异常响应。

??Modbus协议规定了三种功能码:

  • 公共功能码

    ??1)被明确定义的功能码;

    ??2)保证唯一性;

    ??3)由Modbus协会确认并提供公开文件;

    ??4)可进行一致性测试;

    ??5)包括协议定义的功能码和未来保留的功能码

  • 用户定制的功能码 ??1)有两个用户定制的功能码区域,即65~72和100~110;

    ??2)用户自定义,不保证唯一性。

  • 保留功能码/p>

  保留的功能码是因为历史遗留原因,某些公司传统产品上现行使用的功能码不作为公共使用。

  Modbus部分功能码如表所示:           表2-3 Modbus部分功能码

代码 中文名称 寄存器PLC地址 位/字操作 操作数量
01 线圈状态 00001-09999 位操作 单个或多个
02 读离散输入状态 10001-19999 位操作 单个或多个
03 读保持寄存器 40001-49999 字操作 单个或多个
04 读输入寄存器 30001-39999 字操作 单个或多个
05 写单个线圈 00001-09999 位操作 单个
06 写单个保持寄存器 40001-49999 字操作 单个
15 写多个线圈 00001-09999 位操作 多个
16 写多个保持寄存器 40001-49999 字操作 多个

2.4.1 功能码说明

​  功能码可以分为位操作和字操作两类。位操作的最小单位为BIT,字操作的最小单位为两个字节。    1)位操作指令:读线圈状态01H,读(离散)输入状态02H,写单个线圈06H和写多个线圈0FH。

​  2)字操作指令:读保持寄存器03H,写单个寄存器06H,写多个保持寄存器10H。

2.4.2 寄存器地址分配

       表2-4 MODBUS寄存器地址分配

寄存器PLC地址 寄存器协议地址 适用功能 寄存器种类 读写状态
00001-09999 0000H-FFFFH 01H05H0FH 线圈状态 可读可写
10001-19999 0000H-FFFFH 02H 离散输入状态 可读
30001-39999 0000H-FFFFH 04H 输入寄存器 可读
40001-49999 0000H-FFFFH 03H06H0FH 保持寄存器 可读可写

2.4.3 寄存器种类说明

​          表2-5 MODBUS寄存器种类说明

寄存器种类 说明 PLC类比 举例说明
线圈状态 输出端口。可设定端口的输出状态,也可以读取该位的输出状态。可分为两种不同的执行状态,例如保持型或边沿触发型。 DO数字量输出 电磁阀输出,MOSFET输出,LED显示等。
离散输入状态 输入端口。通过外部设定改变输入状态,可读但不可写。 DI数字量输入 拨码开关,接近开关等。
保持寄存器 输出参数或保持参数,控制器运行时被设定的某些参数。可读可写。 AO模拟量输出 模拟量输出设定值,PID运行参数,变量阀输出大小,传感器报警上限下限。
输入寄存器 输入参数。控制器运行时从外部设备获得的参数。可读但不可写。 AI模拟量输入 模拟量输入

2.4.4 PLC地址和协议地址区别

​  PLC地址可以理解为协议地址的变种,在触摸屏和PLC编程中应用较为广泛。    1)寄存器PLC地址   寄存器PLC地址指存放于控制器中的地址,这些控制器可以是PLC,也可以是触摸屏,或是文本显示器。PLC地址一般采用10进制描述,共有5位,其中第一位代码寄存器类型。第一位数字和寄存器类型的对应关系如表2-4所示。PLC地址例如40001、30002等。

​  2)寄存器协议地址

​  寄存器协议地址指通信时使用的寄存器地址,例如PLC地址40001对应寻址地址0x0000,40002对应寻址地址0x0001,寄存器寻址地址一般使用16进制描述。再如,PLC寄存器地址40003对应协议地址0002,PLC寄存器地址30003对应协议地址0002,虽然两个PLC寄存器寄存器通信时使用相同的地址,但是需要使用不同的功能码访问,所以访问时不存在冲突。

2.4.5 数据域

​  数据域与功能码紧密相关,存放功能码需要操作的具体数据,数据域以字节为单位,长度不是固定的,对于有些功能码,数据域可以为空。

2.4.6差错校验

  校验码由发送设备计算,放置于发送消息帧的尾部。接受消息的设备再重新计算接收到的信息的校验码,比较计算得到的校验码是否与接收到的相符,如果不相符,则表明出错。它用于保证主机或从机对传送过程中出错的信息起不了作用,增加了系统的安全与效率。

​  在串行通信中,根据传输模式(RTU或ASCII)的不同,采用了不同的校验方法。

​  在ASCII模式中,校验域由两个字符组成,其值基于对全部报文内容执行纵向冗余校验(LRC)计算的结果而来,计算对象不包括冒号和回车换行符。

​  在RTU模式中,校验域由16bit即两个字节构成,其值基于对全部报文内容执行循环冗余校验(CRC)计算的结果而来,计算对象包括校验域之前所有字节。

​  产生CRC-16码的步骤如下:   1)预置一个16位的寄存器为全1(即十六进制FFFFH),称此寄存器为CRC寄存器;

​  2)把第一个8位数据与CRC寄存器的低8位相异或,结果放回CRC寄存器;

​  3)把16位CRC寄存器右移一位,用0添补最高位,检测移出位:

​  4)如果移出位为0,则重复第3步骤(再次移出);如果移出位为1,则CRC寄存器与多项式A001H相异或,结果放回CRC寄存器;

​  5)重复第3、4步骤,直至移出8位;

​  6)将下一个8位数据与CRC寄存器低8位相异或,结果放回CRC寄存器,重复第2、3、4、5步骤;

​  7)消息帧中所有字节按照上述步骤计算完成后,当放置CRC值于报文时,必须将得到的16位CRC寄存器高、低字节进行交换。

​  8)最后得到的CRC寄存器内容即为产生的CRC校验码。

3 Modbus功能码详解

​  有了以上理论基础之后,下面针对各个功能码进行详细分析。

3.1 读取输出线圈

​  发送报文格式如下:

从站地址 功能码 起始(高) 起始(低) 数量(高) 数量(低) 校验
0x01 0x01 0x00 0x13 0x00 0x1B XXXX

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

​  返回报文格式如下:

从站地址 功能码 字节计数 字节1 字节2 字节3 字节4 校验
0x01 0x01 0x04 0xCD 0x6B 0xB2 0x05 XXXX

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

​    CD=1100 1101 对应 00020-00027     6B=01101011 对应 00028-00035

​    B2=1011 0010 对应 00036-00043      05=00000101 对应 00044-00046

3.2 读取输入线圈

  发送报文格式如下:

从站地址 功能码 起始(高) 起始(低) 数量(高) 数量(低) 校验
0x01 0x02 0x00 0xC4 0x00 0x1D XXXX

​  发送报文含义:读取1号从站输入线圈,起始地址为0xC4=196,对应地址为10197,线圈数量为0x1D=29,即读取1号从站输入线圈,地址从10197-10225,共29个线圈的状态值。   返回报文格式如下:

从站地址 功能码 字节计数 字节1 字节2 字节3 字节4 校验
0x01 0x02 0x04 0xCD 0x6B 0xB2 0x05 XXXX

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

​    CD=1100 1101 对应 10197-10204    6B=01101011 对应 10205-10212

​    B2=1011 0010 对应 10213-10220     05=00000101 对应 10221-10225

3.3 读取保持寄存器

  发送报文格式如下:

从站地址 功能码 起始(高) 起始(低) 数量(高) 数量(低) 校验
0x01 0x03 0x00 0x6B 0x00 0x02 XXXX

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

​ 返回报文格式如下:

从站地址 功能码 字节计数 1高 1低 2高 2低 校验
0x01 0x03 0x04 0x02 0x2B 0x01 0x06 XXXX

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

3.4 读取输入寄存器

  发送报文格式如下:

从站地址 功能码 起始(高) 起始(低) 数量(高) 数量(低) 校验
0x01 0x04 0x00 0x6B 0x00 0x02 XXXX

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

​  返回报文格式如下:

从站地址 功能码 字节计数 1高 1低 2高 2低 校验
0x01 0x04 0x04 0x02 0x2B 0x01 0x06 XXXX

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

3.5 写单个线圈

   发送报文格式如下:

从站地址 功能码 线圈(高) 线圈(低) 断通标志 断通标志 校验
0x01 0x05 0x00 0xAC 0xFF 0x00 XXXX

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

​  返回报文格式如下:

从站地址 功能码 线圈(高) 线圈(低) 断通标志 断通标志 校验
0x01 0x05 0x00 0xAC 0xFF 0x00 XXXX

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

3.6 写单个保持寄存器

  发送报文格式如下:

从站地址 功能码 寄存器高 寄存器低 写入值高 写入值低 校验
0x01 0x06 0x00 0x87 0x03 0x9E XXXX

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

​  返回报文格式如下:

从站地址 功能码 寄存器高 寄存器低 写入值高 写入值低 校验
0x01 0x06 0x00 0x87 0x03 0x9E XXXX

​  返回报文含义:预置单保持寄存器原报文返回。

3.7 写多个线圈

​  发送报文格式如下:

从站地址 功能码 起始高 起始低 数量高 数量低 字节数 字节 校验
0x01 0x0F 0x00 0x13 0x00 0x0A 0x02 0xCD00 XXXX

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

  返回报文格式如下:

从站地址 功能码 起始高 起始低 数量高 数量低 校验
0x01 0x0F 0x00 0x13 0x00 0x0A XXXX

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

3.8 写多个保持寄存器

​  发送报文格式如下:

从站地址 功能码 起始高 起始低 数量高 数量低 字节数 字节 校验
0x01 0x10 0x00 0x87 0x00 0x02 0x04 0x01050A10 XXXX

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

从站地址 功能码 起始高 起始低 数量高 数量低 校验
0x01 0x10 0x00 0x87 0x00 0x02 XXXX

​  返回报文含义:预置多保持寄存器返回报文是在原报文基础上除去字节数及具体字节后返回。   存器地址为0x0087=135,起始地址为40136,寄存器数量为0x02=2,结束地址为40137,写入值为0x0105和0x0A10,即预置1号从站寄存器40136=0x0105,40137=0x0A10。

​  返回报文格式如下:

从站地址 功能码 起始高 起始低 数量高 数量低 校验
0x01 0x10 0x00 0x87 0x00 0x02 XXXX

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

标签: 2lrc4传感器

锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

锐单商城 - 一站式电子元器件采购平台