MODBUS通信协议学习二通信方式
MODBUS通信协议学习(二):通信方式
目录
前言
初步了解了链接: .现在具体学习通信模式。
这篇文章在学习过程中作为总结,如有错误,请多指教。
MODBUS通信模式
MODBUS目前有串口形式的Modbus RTU、Modbus ASCII,以及互联网层面的Modbus TCP。
串行链路
Modbus RTU、Modbus ASCII,都是使用的异步串行通信。在报文形式上有所不同。
modbus在串行链路上每一帧数据长度不超过256字节。
ASCII模式的优点在于允许一帧数据字符之间可以停顿,但是传输时间较长。
RTU模式要求一帧数据连续传送,不能间断。传输速度高于ASCII模式。
Modbus ASCII
通信格式
ASCII模式下,每一个字符传送格式
位 | 说明 |
---|---|
起始位 | 1位 |
数据 | 数据长度 7位 ,低位先发送 |
校验位 | 1位(有校验),0位(无校验) |
停止位 | 1位(有校验),2位(无校验) |
波特率 | 用户自选 |
在该模式下发送一个字符需要10位二进制。
数据格式
起始码 | 地址码 | 功能码 | 数据区 | 校验码 | 停止码 |
---|---|---|---|---|---|
: | 01-F7 | 功能码 | N个字符 | LRC | CR LF |
1字符 | 2字符 | 2字符 | n个字符 | 两字符 | 两字符 |
地址码00是广播模式
ASCII模式之所以叫ASCII模式,就是因为他发送数据数按照ASCII码表来发送的。这也就解释了为什么数据是一个字节,但长度是两位字符。比如地址码为01表示一号从机,但是在发送的时候,发送的是’0’ 和 ‘1’ 。这样一来实际的发送长度就是两个字符。这样就可以更加直观的看到发送的帧信息。
个人理解就是发送的时候把数据串转化成了字符串,在串口助手里面接收区用文本模式查看。
起始码和停止码在ASCII中都有对应
DEC | OCT | HEX | BIN | 缩写/符号 | HTML实体 | 描述 |
---|---|---|---|---|---|---|
58 | 072 | 3A | 00111010 | : | :; | Colon |
10 | 012 | 0A | 00001010 | LF | 
; | Line Feed (换行键) |
13 | 015 | 0D | 00001101 | CR | 
; | Carriage Return (回车键) |
LRC
LRC是校验格式。
校验的范围 :从地址码到数据区所有数据。
算法 :相邻2个16进制符相加求和。
校验码 :取其和的低8位的补码为校验码。
起始码 | 地址码 | 功能码 | 数据区 | 校验码 | 停止码 |
---|---|---|---|---|---|
: | 01 | 03 | 21 02 00 02 | LRC | CR LF |
求和 H01+H03+H21+ H02 +H00 +H02 = H29
H29补码HD7
LRC校验应该是HD7,发送时为’D’ ‘7’。
Modbus RTU
通信格式
RTU模式下,每一个字符传送格式
位 | 说明 |
---|---|
起始位 | 1位 |
数据 | 数据长度 8位 ,低位先发送 |
校验位 | 1位(有校验),0位(无校验) |
停止位 | 1位(有校验),2位(无校验) |
波特率 | 用户自选选 |
在该模式下发送一个字符需要11位二进制。
数据格式
起始码 | 地址码 | 功能码 | 数据区 | 校验码 | 停止码 |
---|---|---|---|---|---|
至少3.5字符间隔时间 | 01-F7 | 功能码 | 0-252字节 | CRC | 至少3.5字符间隔时间 |
间隔时间 | 1字节 | 1字节 | 0-252字节 | 2字节(先发校验码低八位再发高八位) | 间隔时间 |
RTU模式的帧定义不再是和ASCII模式一样以特殊字符作为起始和结尾,而是用间隔时间来区分每一帧数据。
RTU模式采用的校验码是CRC,校验码是16位的,需要两字节。
RTU模式直接发送信息,不需要转换成ASCII模式,所以同样波特率下要比ASCII快两倍左右。在串口助手里,用HEX模式查看,收到的数据就是发送的数据。
字符间隔时间:RTU模式下传送一个字符需要11位二进制,至少3.5倍取4倍的话,就是44个二进制位。如果在9600波特率下,连续两帧信息之间需要间隔44/9600秒,也就是4.584毫秒。
在传输一帧信息时,两个字符之间间隔时间不能大于1.5个字符传送时间,否则会发生错误。
CRC
循环冗余校验(Cyclic Redundancy Check, CRC)是一种根据网络数据包或计算机文件等数据产生简短固定位数校验码的一种信道编码技术,主要用来检测或校验数据传输或者保存后可能出现的错误。它是利用除法及余数的原理来作错误侦测的。
在这里只说明modbus rtu 模式中 CRC 计算步骤。
校验的范围 :从地址码到数据区所有数据。
计算CRC码的步骤为:
异或 :相同为0,不同为1
起始码 | 地址码 | 功能码 | 数据区 | 校验码 | 停止码 |
---|---|---|---|---|---|
间隔 | 01 | 03 | 21 02 00 02 | CRC | 间隔 |
预置16位寄存器为十六进制FFFF(11111111 11111111)。称此寄存器为CRC寄存器;
把第一个8位数据与16位CRC寄存器的低位相异或,把结果放于CRC寄存器;
把寄存器的内容右移一位(朝低位),用0填补最高位,检查最低位;
如果最低位为0:重复第3步(再次移位);
如果最低位为1:CRC寄存器与多项式A001(1010 0000 0000 0001)进行异或;
重复步骤3和4,直到右移8次,这样整个8位数据全部进行了处理;
重复步骤2到步骤5,进行下一个8位数据的处理;
最后得到的CRC寄存器即为CRC码。
将高低字节互换得到modbus CRC。
写了一个C语言代码(VC++6.0)。
#include<stdio.h>
unsigned int GetCrcData(unsigned char *buffer, unsigned int len);
void main(void)
{
unsigned char report[6] = {0x01, 0x03, 0x21, 0x02, 0x00, 0x02};//模拟接收到的数据
GetCrcData(report, 6);
}
unsigned int GetCrcData(unsigned char *buffer, unsigned int len)
{
unsigned int CRC = 0XFFFF;//16位crc寄存器预置
unsigned int i = 0, j = 0;//计数
unsigned char CRC_L,CRC_H;//CRC码高低8位
for (i = 0; i < len; i++)//循环计算每个数据
{
CRC = buffer[i] ^ CRC;//将八位数据与crc寄存器异或
for (j = 0; j < 8; j++)//循环计算数据的
{
if ((CRC & 0X0001) == 1)//判断右移出的是不是1,如果是1则与多项式进行异或。
{
CRC >>= 1;//先将数据右移一位
CRC ^= 0xa001;//与多项式进行异或
}
else//如果是0
{
CRC >>= 1;//直接移出
}
}
}
CRC_L = CRC;//crc的低八位
CRC_H = CRC >> 8;//crc的高八位
printf("CRC_L = %hX, CRC_H = %hX \r\n", CRC_L, CRC_H);
return CRC;
}
结果正确
网络链路
通信格式
Modbus TCP/IP 是基于TCP协议的通信方式。
TCP
TCP是TCP/IP体系中非常复杂的协议,这里只介绍主要特点。
- TCP是面向连接的运输层协议。 在使用tcp连接前,需要建立tcp连接。传输数据结束后,需要释放之前建立的tcp连接。
- 每一条TCP连接只能有两个端点,是 一对一 的。建立tcp连接需要知道双方的IP地址和端口号,其中从机(服务器)端口为502,主机(客户端)端口大于1024。
- TCP提供可靠交付服务。 通过tcp传输数据,无差错、不丢失、不重复、并且按顺序到达
- TCP提供全双工通信
Modbus TCP/IP
Modbus TCP/IP是对于连接至TCP/IP网络的Modbus TCP/IP客户机和服务器之间的通信方式。
对于那些不支持tcp连接的设备,需要使用网关。
modbus tcp 可以有多个客户机(主机)。
Modbus TCP模式主机(客户机)主动发起通信,主机(客户机)作为tcp客户端。从机(服务器)作为tcp服务器。
数据格式
TCP/IP上的MODBUS数据帧格式为:
MBAP报文头 | 功能码 | 数据 |
---|---|---|
7字节 | 1字节 | 最大252字节 |
功能码和数据与串行链路上一致。
MODBUS TCP数据帧与串行数据帧区别:
MBAP报头文:
域 | 长度 | 描述 | 客户机 | 服务器 |
---|---|---|---|---|
事物处理标识符 | 2字节 | modbus请求/响应事物处理识别码。理解为报文的序列号,一般每次通信之后就要加1以区别不同的通信数据报文。 | 客户机启动 | 服务器复制 |
协议标识符 | 2字节 | 00 00表示ModbusTCP协议 | 客户机启动 | 服务器复制 |
长度 | 2字节 | 以下字节的数量。包含单元标识符,功能码,数据。 | 客户机启动 | 服务器响应 |
单元标识符 | 1字节 | 串行链路上或其他主线上服务器的识别码。理解成地址码 | 客户机启动 | 服务器复制 |
由于使用的是tcp模式,所以不用再需要校验位,认为数据传输一定正确。
MBAP报头文中的 单元标识符 ,理解成设备地址,也就不再需要地址码。