通信协议——Modbus 讲明白了
目 录
- Modbus通信协议
- 一、说明
- 1.1 描述
- 1.2 查询
- 1.3 响应
- 二、异常
- 三、功能码
Modbus通信协议
Modbus由Modicon公司(也是现在的施耐德电气)于1979年开发,是一种工业现场总线协议标准。最初是为使用PLC(可编程逻辑控制器)通信而发表,即该协议最先是在PLC通信上使用的。
因以下特点而广泛使用:
1、免费 —— 使用在任何产品上
2、简单 —— 协议格式简单易用
3、接口丰富 —— 可以在串口、以太网、蓝牙等介质上传输
Modbus通信协议就像是一种特殊的语言规则,让不同的设备能够相互理解和交流。
比方说,有多个设备(控制器、温度传感器等)连接在系统网络中,它们原本可能各说各的话,谁也听不懂谁。但有了Modbus协议,就好像大家都学会了一种通用语言。通过这个语言,控制器可以询问温度传感器 “现在的温度是多少呀?”,控制器也可以告诉阀门驱动器 “把这个阀门打开”。
再比方说,五十六个民族各有各的方言,为了相互之间能够沟通和交流,普通话普及后解决了语言差异问题。
这个通信协议规定了信息怎么传递,用了什么样的格式,以及包含哪些具体内容等,让不同设备能够协同工作,实现数据交换和命令传达。
提示:要想熟悉Modbus通信协议,建议下载这两个小工具进行学习和实践,在Help > Help Topics中查看说明,很快你就掌握了。
Modbus主机设备角色:Modbus Poll
Modbus从机设备角色:Modbus Slave
一、说明
1.1 描述
Modbus协议是一种消息传递结构,广泛用于智能设备之间建立主从通信。
从主机(Host)发送到从机(Slave)的Modbus消息包含:
从机的地址 + 命令 + 数据 + 校验 (LRC或CRC)
1、命令类型:读寄存器(可理解为查询)或写寄存器(可理解为设置)
2、校验和方式:LRC或CRC,用于确保消息的完整性和正确性。
由于Modbus协议只是一个消息传递结构,它独立于底层物理层。传统上使用了RS232, RS422或RS485实现。
在标准Modbus网络上可以使用两种传输模式之一进行通信:
1、ASCII (美国信息交换标准代码)
2、RTU (远程终端单元)
Modbus 协议的帧结构使得主设备(通常是计算机或控制器)可以向从设备发送请求,并接收从设备的响应。通过解析帧结构中的各个字段,可以实现不同设备之间的数据交换和控制操作。
Modbus通信方式是:
1、主机广播或者单播发送指令,从机分析请求,并且给主机应答(如果出错就返回异常功能码)。
2、从机只能响应主机,不能主动发送数据。
- ASCII 模式
消息结构中是ASCII字符
当控制器设置在Modbus网络上使用ASCII模式进行通信时,消息中的每个8位字节作为两个ASCII字符(高4位,低4位)发送。这种模式的主要优点是,它允许字符之间出现最多一秒的时间间隔,而不会导致错误。
在ASCII模式下,消息以冒号(:)字符(0x3A)开始,以回车换行(CR LF)对结束(0x0D和0x0A)。
错误校验:纵向冗余校验(LRC)
所有其他字段允许传输的字符是十六进制0…9、a…F、网设备连续监视网络总线的冒号字符。当接收到一个时,每个设备解码下一个字段(地址字段),以确定它是否是被寻址的设备。
从机地址范围:0-255
消息中字符之间的间隔可以长达一秒。如果出现较大的间隔,则接收设备假定发生了错误。一个典型的消息框架(其中字符是指ASCII字符)如下所示:
开始 | 地址 | 功能码 | 数据 | LRC | 结束 |
---|---|---|---|---|---|
: | 2个字符 | 2个字符 | 多个字符 | 2个字符 | \r\n |
举例,读取温度数据
1、主机(控制器)发送请求消息
:01030000000174\r\n
01是从机地址,03是功能码,0000是访问的寄存器起始地址,0001是访问的寄存器数量,74是校验值
2、从机(温度传感器)收到请求后,处理并响应
:0103020019C4\r\n
01是从机地址,03是功能码,02是返回的数据字节数,0019是温度值对应的十六进制,C4是校验值
当字符帧使用ASCII模式时,错误检查字段包含两个ASCII字符。错误检查字符是对消息内容执行LRC(纵向冗余检查)计算的结果,不包括开始冒号和结束CRLF字符。LRC字符作为CRLF字符前面的最后一个字段附加到消息中。
//LRC 例子
BYTE LRC (BYTE *nData, WORD wlength)
{
BYTE nLRC = 0;
for(int i = 0;i < wlength; i++)
nLRC += *nData++;
return (BYTE)(-nLRC);
}
- RTU 模式
消息结构中是十六进制字符
当控制器设置为使用RTU模式在Modbus网络上通信时,消息中的每个8位字节包含两个4bit的十六进制字符。
这种模式的主要优点是,在相同的波特率下,它具有比ASCII更高的字符密度,允许更好的数据吞吐量。每条消息必须在连续的流中传输。
在RTU模式下,消息以至少3.5个字符时间的静默间隔开始。这是最容易实现的,在网络上使用的波特率上的多个字符时间。然后传输的第一个字段是设备地址。
所有字段允许传输的字符为十六进制0…9、a…F、连网设备连续监视网络总线,包括在静默间隔期间。当接收到第一个字段(地址字段)时,每个设备对其进行解码,以确定它是否是被寻址的设备。在最后一个传输字符之后,至少3.5个字符时间的类似间隔标志着消息的结束。在此间隔之后,可以开始发送新消息。
整个消息帧必须作为连续流传输。如果在帧完成之前出现超过1.5个字符时间的静默间隔,接收设备将刷新不完整的消息,并假定下一个字节将是新消息的地址字段。
从机地址范围:0-247
类似地,如果一条新消息在前一条消息之后开始的时间小于3.5个字符,接收设备将认为它是前一条消息的延续。这将设置一个错误,因为最终CRC(循环冗余校验)字段中的值对合并的消息无效。一个典型的消息框架如下所示:
开始 | 地址 | 功能码 | 数据 | CRC16 | 结束 |
---|---|---|---|---|---|
3.5个字符时间 | 1个字节 | 1个字节 | 多个字节 | 2个字节 | 3.5个字符时间 |
当RTU模式用于字符帧时,错误检查字段包含一个16位值,实现为两个8位字节。错误检查值是对消息内容执行周期性冗余检查计算的结果。
CRC字段作为消息中的最后一个字段附加到消息中。完成此操作后,首先附加字段的低阶字节,然后是高阶字节。CRC高序字节是消息中要发送的最后一个字节。
举例,读取电表电量
1、主机(能源管理系统)发送请求
01 03 00 01 00 01 84 0A
01是从机地址,03是功能码,00 01是访问的寄存器起始地址,00 01是访问的寄存器数量,84 0A是校验值
2、从机(智能电表)收到请求后,处理并响应
01 03 02 03 E8 39 44
01是从机地址,03是功能码,02是返回的数据字节数,03 E8是电量值对应的十六进制,39 44是校验值
// CRC 例子
unsigned short CRC16 (const unsigned char *nData, unsigned short wLength)
{
static const unsigned short wCRCTable[] = {...};
unsigned char nTemp;
unsigned short wCRCWord = 0xFFFF;
while (wLength--)
{
nTemp = *nData++ ^ wCRCWord;
wCRCWord >>= 8;
wCRCWord ^= wCRCTable[nTemp];
}
return wCRCWord;
}
1.2 查询
查询是主机给从机发送命令来请求消息。
查询消息结构中各个代码的意义:
- 地址代码 ——指明消息是发送给哪个从机设备。
- 功能代码 ——告诉所寻址的从机设备要执行哪种操作。
- 数据字节 ——包含从机设备执行该功能所需的任何附加信息。例如,函数代码03将查询从机以读取保持寄存器并响应其内容。
- 数据字段 ——必须包含告诉从机设备该从哪个寄存器开始以及读取多少个寄存器的信息。
- 错误检查字段——为从机设备提供了验证消息内容完整性的方法。
地址码 —— 就像是设备的“门牌号”。想象一下有很多房间,每个房间里都有不同的设备。地址码就是用来区分这些不同设备的标志。比如在一个工厂里,有很多传感器和控制器,每个设备都被分配了一个唯一的地址码。当主设备要和某个特定的从设备通信时,就会在信息中包含这个从设备的地址码,这样只有那个具有相应地址码的从设备才会响应,其他设备就会忽略这个信息。就好像你给某个特定的房间送快递,快递单上的地址就是那个房间的“地址码”,只有那个房间的人会出来接收快递。
功能码 —— 则决定了这次通信要做什么事情。它就像是一个指令代码,告诉从设备要执行什么样的操作。比如功能码可以是读取某个寄存器的值(比如读取温度传感器的当前温度)、写入一个数值到寄存器(比如设置控制器的某个参数)、启动或停止一个设备等等。不同的功能码代表着不同的操作指令。就好比你给别人一个指令,“去拿一本书”“把灯打开”“关上门”等,这些指令就相当于功能码,告诉对方具体要做什么事情。
1.3 响应
响应是从机回应主机的请求。
正常响应 —— 则响应中的功能码是查询中的功能码的一样。数据字节包含从机收集的数据,如寄存器值或状态。
错误响应 —— 则修改功能码以表明响应是错误响应,并且数据字节中包含描述错误的代码。错误检查字段允许主机确认消息内容是否有效。
二、异常
持续更新中
三、功能码
持续更新中