MODBUS 通讯协议在产品中的应用框架V20.docx
- 文档编号:8499777
- 上传时间:2023-01-31
- 格式:DOCX
- 页数:38
- 大小:78.83KB
MODBUS 通讯协议在产品中的应用框架V20.docx
《MODBUS 通讯协议在产品中的应用框架V20.docx》由会员分享,可在线阅读,更多相关《MODBUS 通讯协议在产品中的应用框架V20.docx(38页珍藏版)》请在冰豆网上搜索。
MODBUS通讯协议在产品中的应用框架V20
标准化指导性技术文件
Modbus通讯协议在天辰产品中的应用框架
发布部门:
开发部
发布时间:
2008-03-20
版本:
2.0
第一部分Modbus通讯协议概述
本部分为介绍性内容,已经熟悉Modbus协议或需要在产品中迅速实现协议的技术人员可以跳过此部分,直接参考第二部分。
1.术语
ADU(ApplicationDataUnit)应用数据单元
LSB(LeastSignificantBit)最低有效位
MB(ModbusProtocol)Modbus协议
MSB(MostSignificantBit)最高有效位
PDU(ProtocolDataUnit)协议数据单元
2.协议描述
Modbus协议定义了一个与基础通信层无关的简单协议数据单元(PDU)。
特定总线或网络上的Modbus协议映射能够在应用数据单元(ADU)上引用一些附加域,见图1。
图1通用Modbus帧
启动Modbus事务处理的客户机创建Modbus应用数据单元。
功能码向服务器指示将执行哪种操作。
Modbus协议建立了客户机启动的请求格式。
用一个字节编码Modbus数据单元的功能码域。
有效的码字范围是十进制1~255(128~255为异常响应保留)。
当从客户机向服务器设备发送报文时,功能码域通知服务器执行哪种操作。
从客户机向服务器设备发送的报文数据域包括附加信息,服务器使用这个信息执行功能码定义的操作。
这个域还包括离散量和寄存器地址、处理的项目数量以及域中的实际数据字节数。
在某种请求中,数据域可以是不存在的(0长度),在此情况下服务器不需要任何附加信息。
功能码仅说明操作。
如果在一个正确接收的ModbusADU中,不出现与所请求的Modbus功能有关的差错,那么服务器至客户机的响应数据域包含所请求的数据。
如果出现与所请求的Modbus功能有关的差错,那么该域包含一个异常码,服务器应用能够使用这个域确定下一个执行的操作。
当服务器对客户机响应时,它使用功能码域来指示正常(无差错)响应(见图2)或者出现某种差错(称为异常响应),见图3。
对于一个正常响应来说,服务器仅复制原始功能码。
图2Modbus事务处理(无差错)
对于异常响应,服务器将原始功能码的最高有效位设置逻辑1后返回。
图3Modbus事务处理(异常响应)
3.数据编码
Modbus使用最高有效字节在低地址存储的方式表示地址和数据项。
这意味着当发送多个字节时,首先发送最高有效字节。
例如:
寄存器大小值
16位0x1234发送的第一字节为0x12然后0x34
4.Modbus数据模型
Modbus的数据模型是以一组具有不同特征的表为基础建立的。
4个基本表见表1:
表1
基本表
对象类型
访问类型
注释
离散量输入
单个位
只读
I/O系统可提供这种类型数据
线圈
单个位
读写
通过应用程序可改变这种类型数据
输入寄存器
16位字
只读
I/O系统可提供这种类型数据
保持寄存器
16位字
读写
通过应用程序可改变这种类型数据
输入与输出之间以及位寻址的和字寻址的数据项之间的区别并不意味着应用特性的差别。
如果所有4个表相互覆盖是对该目标机器最自然的解释,也是完全可接收的,而且很普遍。
对于每个基本表,协议都允许单个的选择65536个数据项,而且其读写操作被设计为可以越过多个连续数据项直到数据大小规格限制,这个数据大小规格限制与事务处理功能码有关。
Modbus功能码中使用的Modbus寄存器逻辑编号是以0开始的无符号整数索引。
Modbus模型实现的实例
下列实例表示了两种在设备中组织数据的方法。
有多种组织数据的方法,在本部分中没有被全部描述。
每个设备根据其应用都有它自己的组织数据的方法。
实例1:
有4个独立块的设备
图4表示了含有数字量和模拟量、输入量和输出量的设备中的数据组织。
由于不同块中的数据不相关,每个块是独立的。
可通过不同Modbus功能码访问每个块。
图4带有独立块的Modbus数据模型
实例2:
仅有1个块的设备
图5实例中,设备仅有1个数据块。
通过几个Modbus功能码能够得到相同数据,既可通过16位访问也可通过1位访问。
图5仅带有1个块的Modbus数据模型
5.Modbus事务处理的定义
图6是状态图,描述了在服务器侧Modbus事务处理的一般处理过程。
图6Modbus事务处理的状态图
一旦处理器处理请求,使用合适的Modbus服务器事务处理建立Modbus响应。
根据处理结果,可以建立两种类型响应:
♦一个正常的Modbus响应:
响应功能码=请求功能码。
♦一个异常的Modbus响应
1)用来给客户机提供处理过程中与所发现的差错相关的信息;
2)异常功能码=请求功能码+0x80;
3)提供一个异常码来指示差错原因。
6.公共功能码定义
见表2。
表2
功能码
码
子码
(十六进制)
数
据
访
问
比特访问
物理离散量输入
读离散量输入
02
—
02
内部比特或物理线圈
读线圈
01
—
01
写单个线圈
05
—
05
写多个线圈
15
—
0F
16比特访问
输入寄存器
读输入寄存器
04
—
04
内部存储器或物理输出存储器
读多个寄存器
03
—
03
写单个寄存器
06
—
06
写多个寄存器
16
—
10
读/写多个寄存器
23
—
17
屏蔽写寄存器
22
—
16
读FIFO队列
24
—
18
文件访问记录
读文件记录
20
6
14
写文件记录
21
6
15
诊断
读异常状态
07
—
—
诊断
08
00-18
—
获得公用事件计数器
11
—
0B
获得公用事件记录
12
—
0C
报告从站ID
17
—
11
读设备识别码
43
14
2B
其他
封装接口传输
43
—
2B
7.功能码描述
7.1.01(0x01)读线圈
见表3~表5。
使用该功能码从一个远程设备中读1~2000个连续的线圈状态。
请求PDU指定了起始地址,即指定了第一个线圈地址和线圈数目。
在PDU中,从17(十六进制11)返回从站忙计数。
响应报文中的线圈按数据域的每位一个线圈进行打包。
状态被表示成1=ON和0=OFF。
第一个数据字节的LSB(最低有效位)包含询问中所寻址的输出。
其他线圈依次类推,一直到这个字节的高位端为止,并在后续字节中按照从低位到高位的顺序排列。
如果返回的输出数量不是8的倍数,将用零填充最后数据字节中的剩余位(一直到字节的最高位端)。
字节数量域说明了数据的全部字节数。
表3
请求
功能码
1字节
0x01
起始地址
2字节
0x0000~0xFFFF
线圈数量
2字节
1~2000(0x07D0)
表4
响应
功能码
1字节
0x01
字节计数
1字节
N*
线圈状态
n字节
n=N或N+1
*N=输出数量/8,如果余数不等于0,那么N=N+1。
表5
错误
功能码
1字节
功能码+0x80
异常码
1字节
01或02或03或04
7.2.02(0x02)读离散量输入
见表6~表8。
使用该功能从一个远程设备中读1~2000个连续的离散量输入状态。
请求PDU指定了起始地址,即指定了第一个离散量输入地址和离散量输入数目。
在PDU中,从零开始寻址离散量输入。
因此标号1~16的离散量输入寻址为0~15。
响应报文中的离散量输入按数据域的每位一个离散量输入进行打包。
状态被表示成1=ON和0=OFF。
第一个数据字节的LSB(最低有效位)包含讯问中所寻址的输入。
其他离散量输入依次类推,一直到这个字节的高位端为止,并在后续字节中按照从低位到高位的顺序排列。
如果返回的输出数量不是8的倍数,将用零填充最后数据字节中的剩余位(一直到字节的最高位端)。
字节数量域说明了数据的全部字节数。
表6
请求
功能码
1字节
0x02
起始地址
2字节
0x0000~0xFFFF
线圈数量
2字节
1~2000(0x07D0)
表7
响应
功能码
1字节
0x02
字节计数
1字节
N*
线圈状态
N*×1个字节
…
*N=输出数量/8,如果余数不等于0,那么N=N+1
表8
错误
差错码
1字节
0x82
异常码
1字节
01或02或03或04
7.3.03(0x03)读保持寄存器
见表9~表11。
使用该功能码从远程设备中读保持寄存器连续块的内容。
请求PDU说明了起始寄存器地址和寄存器数量。
在PDU中,从零开始寻址寄存器。
因此编号1~16的寄存器寻址为0~15。
将响应报文中的寄存器数据打包成每个寄存器有两字节。
对于每个寄存器,第一个字节为高位字节,第二个字节为低位字节。
表9
请求
功能码
1字节
0x03
起始地址
2字节
0x0000~0xFFFF
寄存器数量
2字节
1~125(0x007D)
表10
响应
功能码
1字节
0x03
字节数
1字节
2×N*
寄存器值
N*×2个字节
…
*N=寄存器的数量
表11
错误
差错码
1字节
0x83
异常码
1字节
01或02或03或04
7.4.04(0x04)读输入寄存器
见表12~表14。
使用该功能码从一个远程设备中读1~125个连续输入寄存器。
请求PDU说明了起始地址和寄存器数量。
在PDU中,从零开始寻址寄存器。
因此,标号为1~16的输入寄存器寻址为0~15。
将响应报文中的寄存器数据打包成每个寄存器为两字节。
对于每个寄存器,第一个字节包括高位位,第二个字节包括低位位。
表12
请求
功能码
1字节
0x04
起始地址
2字节
0x0000~0xFFFF
输入寄存器数量
2字节
0x0001~0x007D
表13
响应
功能码
1字节
0x04
字节计数
1字节
2×N*
输入寄存器
N*×2个字节
…
*N=输入寄存器的数量。
表14
错误
差错码
1字节
0x84
异常码
1字节
01或02或03或04
7.5.05(0x05)写单个线圈
见表15~表17。
使用该功能码将一个远程设备中的一个输出写ON或OFF。
请求数据域中的常数指定所请求的ON/OFF状态。
十六进制值FF00请求输出为ON。
十六进制值0000请求输出为OFF。
其他所有值均是非法的,并且对输出不起作用。
请求PDU说明了被强制的线圈地址。
从零开始寻址线圈。
因此,编号为1的线圈被寻址为0。
线圈值域的常数指定所请求的ON/OFF状态。
十六进制值0xFF00请求线圈为ON。
十六进制值0x0000请求线圈为OFF。
其他所有值均为非法的,并且对线圈不起作用。
正常的响应是请求的复制,在写入线圈状态后被返回。
表15
请求
功能码
1字节
0x05
输出地址
2字节
0x0000~0xFFFF
输出值
2字节
0x0000或0xFF00
表16
响应
功能码
1字节
0x05
输出地址
2字节
0x0000~0xFFFF
输出值
2字节
0x0000或0xFF00
表17
错误
差错码
1字节
0x85
异常码
1字节
01或02或03或04
7.6.06(0x06)写单个寄存器
见表18~20。
使用该功能码在一个远程设备中写一个保持寄存器。
请求PDU指定了被写入寄存器的地址。
从零开始寻址寄存器。
因此,编号为1的寄存器被寻址为0。
正常的响应是请求的复制,在写入寄存器内容之后被返回。
表18
请求
功能码
1字节
0x06
寄存器地址
2字节
0x0000~0xFFFF
寄存器值
2字节
0x0000~0xFFFF
表19
响应
功能码
1字节
0x06
寄存器地址
2字节
0x0000~0xFFFF
寄存器值
2字节
0x0000~0xFFFF
表20
错误
差错码
1字节
0x86
异常码
1字节
01或02或03或04
7.7.07(0x07)读异常状态
见表21~23。
使用这个功能码从一个远程设备中读8个异常状态输出的内容。
因为异常码输出参量是已知的(在这个功能中不需要输出参量),该功能提供一种简单的访问这种信息的方法。
正常的响应包括8个异常状态输出的内容。
将这些输出打包成一个字节,每个输出一个位。
在该字节的最低有效位中包含最低位输出参量的状态。
表21
请求
功能码
1字节
0x07
表22
响应
功能码
1字节
0x07
输出数据
1字节
0x00~0xFF
表23
错误
差错码
1字节
0x87
异常码
1字节
01或04
7.8.08(0x08)诊断
公司产品通讯协议中不使用该功能码,不进行描述。
7.9.11(0x0B)获得通信事件计数器
公司产品通讯协议中不使用该功能码,不进行描述。
7.10.12(0x0C)获得通信事件记录
公司产品通讯协议中不使用该功能码,不进行描述。
7.11.15(0x0F)写多个线圈
见表24~26。
该功能码将一个远程设备中的一个线圈序列的每个线圈强制为ON或OFF。
请求PDU指定了被强制的线圈编号。
从零开始寻址线圈。
因此,编号为1的线圈被寻址为0。
请求数据域的内容指定了被请求的ON/OFF状态。
数据域中为逻辑“1”的位请求相应输出为ON。
为逻辑“0”的位请求相应输出为OFF。
正常的响应返回功能码、起始地址和被强制的线圈数量。
表24
请求
功能码
1字节
0x0F
起始地址
2字节
0x0000~0xFFFF
输出数量
2字节
0x0001~0x07B0
字节计数
1字节
N*
输出值
N*×1字节
…
*N=输出数量/8,如果余数不等于0,那么,N=N+1。
表25
响应
功能码
1字节
0x0F
起始地址
2字节
0x0000~0xFFFF
输出数量
2字节
0x0001~0x07B0
表26
错误
差错码
1字节
0x8F
异常码
1字节
01或02或03或04
7.12.16(0x10)写多个寄存器
见表27~29。
使用该功能码在一个远程设备中写连续寄存器块(1~123个寄存器)。
在请求数据域中指定了请求写入的值。
将数据打包成每个寄存器两字节。
正常的响应返回功能码、起始地址和被写入寄存器的数量。
表27
请求
功能码
1字节
0x10
起始地址
2字节
0x0000~0xFFFF
寄存器数量
2字节
0x0001~0x007B
字节计数
1字节
2×N*
寄存器值
N*×2字节
值
*N=寄存器数量
表28
响应
功能码
1字节
0x10
起始地址
2字节
0x0000~0xFFFF
寄存器数量
2字节
1~123(0x007B)
表29
错误
差错码
1字节
0x90
异常码
1字节
01或02或03或04
7.13.17(0x11)报告从站ID
公司产品通讯协议中不使用该功能码,不进行描述。
7.14.20/6(0x14/0x06)读文件记录
公司产品通讯协议中不使用该功能码,不进行描述。
7.15.21/6(0x15/0x06)写文件记录
公司产品通讯协议中不使用该功能码,不进行描述。
7.16.22(0x16)屏蔽写寄存器
公司产品通讯协议中不使用该功能码,不进行描述。
7.17.23(0x17)读/写多个寄存器
公司产品通讯协议中不使用该功能码,不进行描述。
7.18.24(0x18)读FIFO队列
公司产品通讯协议中不使用该功能码,不进行描述。
7.19.43(0x2B)封装接口传输
公司产品通讯协议中不使用该功能码,不进行描述。
7.20.43/14(0x2B/0x0E)读设备标识
见表30~33。
这个功能码允许读取与远程设备的物理和功能描述相关的标识和附加信息。
读设备识别接口由包含一组可寻址数据元素组成的地址空间构成。
数据元素被称作对象,由对象Id识别它们。
接口由3类对象组成:
——基本设备识别。
所有此类对象都是必备的:
厂商名称、产品代码和修订版本号。
——常规设备识别。
除基本数据对象以外,设备提供了附加的和可选择的识别以及数据对象描述。
本标准定义了所有类别的对象,但是它们的实现是可选的。
——扩展设备识别。
除常规数据对象以外,设备提供了附加的和可选的识别以及专用数据描述。
所有这些数据都是与设备有关的。
表30
对象Id
对象名称/描述
类型
M/O
类别
0x00
厂商名称
ASCII字符串
强制的
基本
0x01
产品代码
ASCII字符串
强制的
基本
0x02
主要修订本
ASCII字符串
强制的
基本
0x03
厂商网址
ASCII字符串
可选的
常规
0x04
产品名称
ASCII字符串
可选的
常规
0x05
模式名称
ASCII字符串
可选的
常规
0x06
用户应用名称
ASCII字符串
可选的
常规
0x07
…
0x7F
保留
—
可选的
常规
0x80
…
0xFF
可选择的定义专用对象
范围(0x80~0xFF)与产品有关
ASCII字符串
可选的
扩展
表31
请求
功能码
1字节
0x2B
MEI类型
1字节
0x0E
ReadDevId码
1字节
01/02/03/04
对象Id
1字节
0x00~0xFF
表32
响应
功能码
1字节
0x2B
MEI类型
1字节
0x0E
ReadDevId码
1字节
01/02/03/04
一致性等级
1字节
…
接续标识
1字节
0x00/0xFF
下一个对象Id
1字节
对象ID号
对象数量
1字节
…
列表
对象ID
1字节
…
对象长度
1字节
…
对象值
对象长度
与对象ID有关
表33
错误
功能码
1字节
0xAB:
Fc0x2B+0x80
MEI类型
1字节
0x0E
异常码
1字节
01或02或03或04
第二部分天辰Modbus协议框架
Modbus协议定义了两种串行传输模式:
RTU模式和ASCII模式。
这两种模式定义了链路上串行传送报文域的位内容,确定了信息如何打包为报文域和如何解码。
Modbus要求每个设备必须实现RTU模式,ASCII模式作为可选模式。
考虑到我公司目前主流产品的协议都是基于ASCII码协议的。
因此,下面首先描述我们的ASCII实现方法,再描述RTU协议。
1.ASCII传输模式
在Modbus串行链路上通信时,用两个ASCII字符发送报文中的一个8位字节。
实例:
将字节0x5B编码为两个字符:
0x35和0x42。
ASCII模式中每个字节(10位)的格式为:
编码系统:
十六进制,ASCII字符0~9、A~F
报文中每个ASCII字符含有1个十六进制字符
每个字节的位:
1个起始位
7个数据位,首先发送最低有效位
1个奇偶校验位
1个停止位
注:
默认的校验模式是偶校验,但可以通过设置变更为无校验或奇校验。
帧校验域:
纵向冗余校验(LRC)。
通讯波特率:
可选范围为2400bps、4800bps、9600bps、19200bps。
1.1.Modbus报文ASCII帧
在ASCII模式中,用特定的字符将报文划分为帧起始和帧结束(这一点和天辰协议相同)。
一个报文必须以一个“冒号”(:
)字符(十六进制ASCII3A)起始,以“回车—换行”(CRLF)(十六进制ASCII0D和0A)结束。
图6表示了一个典型的报文帧。
图6
起始
地址
功能码
数据
LRC
结束
1个字符
2个字符
2个字符
0至0x252个字符
2个字符
2个字符
ModbusASCII帧的最大长度为513个字符。
1.2.LRC校验
在ASCII模式中,报文包含一个差错校验域,该域是基于对全部报文内容执行的纵向冗余校验(LRC)计算结果,不包括起始“冒号”和结束CRLF对。
LRC域是一个字节,包含一个8位二进制值。
发送设备计算LRC值,将LRC值附加到报文中。
在接收报文过程中,接收设备重新计算LRC值,并将计算值与LRC域中接收到的实际值相比较。
如果两个值不相等,则产生错误。
对报文中的所有连续8位字节相加,忽略任何进位,计算LRC,然后求出其二进制补码。
根据不包括报文起始“冒号”和报文结束CRLF对的整个ASCII报文域内容进行LRC。
在ASCII模式中,LRC的结果被编码为两个字节的ASCII,并将其放置CRLF之前的ASCII模式报文帧的结尾处。
2.RTU传输模式
在Modbus串行链路上通信时,报文中每个8位字节含有两个4位十六进制字符。
RTU模式中每个字节(11位)的格式为:
编码系统:
每个8位字节含有两个4位十六进制字符(0~9、A~F)
每个字节的位:
1个起始位
8个数据位,首先发送最低有效位
1个奇偶校验位
1个停止位
注:
默认的校验模式是偶校验,但可以通过设置变更为无校验或奇校验。
帧校验域:
循环冗余校验(CRC)。
通讯波特率:
可选范围为2400bps、4800bps、9600bps、19200bps。
2.1.Modbus报文RTU帧
在RTU模式中,时长至少为3.5个字符时间的空闲间隔将报文帧区分开。
这个时间称为t3.5。
图7表示了一个典型的报文帧。
图7
起始
地址
功能码
数据
CRC
结束
≥3.5字符
8位
8位
N×8位
16位
≥3.5字符
必须以连续的字符流发送整个报文帧。
如果字符之间的空闲间隔大于1.5个字符时间,那么认为报文帧不完整,并且接收站应该丢弃这个报文帧。
字符间间隔
所谓1个字符的时间t,是指发送完每个11位所用的时间,计算方法为“1÷波特率×11”。
但是,实现RTU的定时会对系统带来大量中断管理。
在较高的通讯波特率下,这将导致CPU负担加重。
因此,当波特率等于或低于19200bit/s时,必须严格遵守这两个定时;波特率大于19200bit/s时,两个定时器应该使用固定值:
建议字符间隔超时时间(t1.5)为750μs,帧间的超时时间(t3.5)为1.750ms。
2.2.CRC校验
RTU模式包含一个差错校验域,该域是基于冗余
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- MODBUS 通讯协议在产品中的应用框架V20 通讯 协议 产品 中的 应用 框架 V20