Modbus主要分为Modbus TCP和Modbus RTU/ASCII两种方式。
Modbus 串行消息帧格式
Modbus ASCII或RTU模式仅使用于标准的Modbus协议串行网络,它定义了在这些网络上连续传输的消息段的每一个字节,以及决定怎样将信息打包成消息域和如何解码等功能。
ASCII消息帧格式
当控制器设为在Modbus网络上以ASCII模式通信时,在消息中每个8位(bit)的字节都将作为两个ASCII字符发送。这种方式的主要优点是字符发送的时间间隔可达到1s而不产生错误。
在ASCII模式下,消息以冒号(:)字符(ASCII码0x3A)开始,以回车换行符结束(ASCII码0x0D,0x0A)。消息帧的其他字段可以使用的传输字符是十六进制的09,AF。处于网络上的Modbus设备不断侦测 “:” 字符,当有一个冒号接收到时,每个设备进入解码阶段,并解码下一个字段(地址域)来判断是否是发给自己的。消息帧中的字符间发送的时间间隔最长不能超过1s,否则接收的设备将认为发生传输错误。
起始 | 地址 | 功能代码 | 数据 | LRC校验 | 结束 |
---|---|---|---|---|---|
1字符 | 2字符 | 2字符 | 0~2*252字符 | 2字符 | 2字符 |
RTU消息帧格式
传输设备将Modbus报文放置在带有已知起始和结束电的消息帧中,这就要求接收消息真的设备在报文的起始处开始接收,并且要知道报文传输何时结束。另外还必须能够检测到不完整的报文,且能够清晰地设置错误标志。
在RTU模式中,消息的发送和接收以至少3.5个字符时间的停顿间隔为标志。实际使用中,网络设备不断侦测网络总线,计算字符间的停顿间隔时间,判断消息帧的起始点。当接收到第一个域(地址域)时,每个设备都进行解码以判断时否时发给自己的。在最后一个传输字符结束之后,一个至少3.5个字符时间的停顿标定了消息的结束,而一个新的消息可以在此停顿后开始。另外,在一帧报文中,必须以连续的字符流发送整个报文帧。如果两个字符之间的空闲间隔大于1.5个字符时间,那么认为报文帧不完整,该报文将丢失。简单来说,3.5个字符时间间隔的目的是作为区别前后两帧数据的分隔符。
例如:
串口参数设置为1位起始位,8位数据位,1位校验位,1位停止位。这样1个字符就博爱阔11位,那么3.5个字符就是3.5*11=38.5位。此时波特率设置位9600bps,即每秒传输数据为9600个位的数据。那么换算一下,38.5个二进制位数据需要的时间就是38.5*(1000/9600)=4.0104167ms。那么在波特率9600bps的情况下,相邻的两帧数据的起始和结束之间至少有≥4.0104167ms的时间间隔。
为了时间RTU通信中的时间间隔管理,定时器将引起大量的中断处理,在较高的通信波特率下将导致CPU沉重负担。为此,规定当波特率≤19200bps时,需要严格遵守时间间隔。在波特率>19200bps时,时间间隔使用固定值。
地址域
地址域即通信帧中的地址字段,内容为从设备地址。Modbus消息帧的地址域包含2个字符(ASCII模式)或者1个字节(RTU模式)。
从设备的地址是0~247(十进制),单个设备的实际地址范围是1~247,地址0作为广播地址。主设备发送消息时将从设备地址放到地址域中以便从设备识别此消息是否是发给自己的。从设备回复主设备时会将自己的地址放到回应消息的地址域中以便主设备识别是哪个从设备返回的数据。
功能码域
功能吗用于表示消息帧的功能。功能码域由1个字节构成,取值范围为1~255(十进制)。从设备根据功能码执行相应的功能,执行完成后在响应消息帧中设置同样的功能码。如果出现异常,返回的消息帧中将功能码最高位(MSB)设置为1。
数据域
数据域存放功能码需要操作的具体数据。数据域以字节为单位,长度可变。
Modbus差错校验
在Modbus串行通信中,更具传输模式(ASCII和RTU)的不同,差错校验域采用了不同的校验方式。
ASCII模式
在ASCII模式中,报文包含一个错误校验字段。该字段由两个字符组成,其值基于对全部报文内容执行的纵向冗余校验(LRC)计算的结果而来,计算对象不包括起始字符(:)和结束字符(回车换行符号CRLF)RTU模式
在RTU模式中,报文同样包含一个错误校验字段。该字段由16个bit位共两个字节组成。其值基于对全部报文内容执行的循环冗余校验(CRC)计算的结果而来,计算对象包括校验域之前的所有字节。
Modbus TCP消息帧格式
在Modbus TCP/IP协议中,串行链路中的主/从设备分别演变位客户端/服务器端设备。
Modbus协议在TCP/IP上的实现实在TCP/IP协议层上的应用,它需要一个完整的TCP/IP协议栈作为支撑,Modbus TCP/IP服务器端通常使用端口502作为接收报文的端口。
为了便于传输或者提取各报文,保证报文传输的完整性,Modbus协议在应用数据单元(ADU)中引入了附加字段。如串行链路中的报文分隔符+LRC校验和时间间隔+CRC校验。同样的,在TCP/IP网络上的Modbus协议也引入了一个称为MBAP(Modbus Application Header)报文头的字段。
Modbus TCP/IP协议最大帧数据长度为260字节,其中字节0~6构成MBAP报头。
单元标识符
如果是Modbus服务器连接到Modbus+或Modbus串行链路子网,并通过一个网桥或网关配置这个服务器的IP地址,则Modbus单元标识符对识别连接到网桥或网关后的子网的从站设备是必须的。TCP连接中的目的IP地址识别了网桥本身的地址,而网桥则使用Modbus单元标识符将请求转交给正确的从站设备。
对单纯的Modbus TCP/IP设备来说,利用IP地址即可寻址Modbus服务器端设备,此时Modbus单元标识符是无用的,必须使用0xFF填充。当对直接连接到TCP/IP网络上的Modbus服务器寻址时,建议不要在“单元标识符”域使用有效的Modbus从站地址。
实际在Modbus TCP/IP传输过程中,服务端返回的响应报文中同样包含MBAP报头,除了Length字段外,其他字段与客户端一致。Modbus消息帧由TCP/IP层提供,不需要像串行链路那样自己判断一帧是否结束,所有数据传输由TCP/IP层处理。因为底层的TCP/IP协议保证了端到端的连接,而且TCP/IP链路层已确保传输数据的准确性,所以Modbus TCP/IP协议中不需要LRC或CRC等校验功能。
查询与响应报文举例
- 查询报文:00 00 00 00 00 06 09 03 00 04 00 01
0x06:后续还有6各字节
0x09:单元标识符为9
0x03 :功能码为3
0x00 0x04:Modbus起始地址4(即40005)
0x00 0x01:读取寄存器个数为1 - 响应报文:00 00 00 00 00 05 09 03 02 00 05
0x05:表示后续还有5个字节
0x09:同查询报文,单元表示符
0x03:功能码,同查询报文
0x02:返回数据字节数
0x00 0x05:寄存器的值
在Modbus TCP/IP模式下,不需要校验字段。但在特殊场合,例如串行Modbus协议转Modbus TCP的情况下,串行协议数据可以完整的装在到Modbus TCP协议的数据字段,这时CRC或者LRC差错校验字段仍然存在。例如Modbus RTU Over TCP/IP或modbus ASCII Over TCP/IP等。