首先我们要清楚:Modbus是一种串行链路上的主从协议,在通信线路上只能有一个主机存在,不会有多主机存在的情况。虽然主机只有一个,但是从机是可以有多个的。
Modbus的通信过程都是由主机发起的,从机在接收到主机的请求后再进行响应,从机不会主动进行数据的发送。并且从机之间也不会互相发送数据。
1、Modbus的地址规则
Modbus中的每个从机为了能在通信时被主机识别,都会有一个地址,也称为从节点地址。
从节点地址对从设备而言必须是唯一的,在总线上也只能有唯一的一个设备地址,即从机设备的地址在总线上也不能冲突。
从机是有唯一的设备地址的,而主机本身是没有地址的。
Modbus支持的寻址空间为256个,如下:
从上图中可以看到,给子节点使用的地址范围是1 ~ 247,248 ~255是被保留着的。非常重要的一点,0是广播地址,所有的子节点都必须要能够识别广播地址。
2、Modbus的通信模式
Modbus的通信模式有两种:单播模式和广播模式。
(1)单播模式
单播模式:主机要访问某个子节点的时候,是通过子节点的地址进行的一对一的访问方式。子节点在收到主节点发过来的请求以后,根据请求的类型完成相应处理后,子节点会向主节点返回一个报文,也就是我们常说的“应答”。示意图如下:
从上图中是可以看到的:主节点通过发送请求命令到从节点,从节点会从总线上接收到来自主节点的请求,然后解析主节点的请求指令,根据指令完成相应的动作,然后再给主节点的请求作出一个回应,便完成了一次单播通信的过程。
其实大家应该也能看到:在单播模式下,一个Modbus的事务它包含了两个报文,一个是由主机主动发出的“请求”报文,另一个是由从机返回的“应答”报文。
并且主机能准备访问到某个从机是通过从机的唯一地址实现的,从机识别主机发出的指令是否是发送到自己这边的,也是通过从机的唯一地址进行甄别的。
(2)广播模式
广播模式是主机用于向总线上的所有的从机发送请求的指令。
主机的广播指令一般都是用于写命令的,对于来自于主机的广播指令,从机是不需要进行应答的。广播模式的示意图如下:
从图中可以看出,广播模式时单向的,主机发送出广播指令,而从机不再对广播指令进行应答,数据流只在一个方向上流动。
注意:总线上所有的从机都必须要能够识别主机的广播指令,并且地址0是用于广播的,不能作为从机的地址。
3、主从机的状态特征
既然Modbus是主从机的通信模式,那么在通信过程中就需要清楚主从机之间的状态,通过状态去理解Modbus的通信流程。
(1)主机的状态特征
如下图:
根据上图可以分析得到主机的通信过程的一些信息:
1)"空闲" = 无等待的请求。 这一般是在初始上电之后所处的状态。 主机只有在"空闲"状态才能发送请求。发送一个请求后,主机会离开"空闲"状态, 进入“忙”的状态,此时不能再发送其他的请求。
2)当单播请求发送到一个从机上,主机将进入"等待应答" 状态, 同时一个临界超时定时计数器会启动。这个超时称为 "响应超时"。 它避免主节点永远处于"等待应答" 状态。 响应超时的时间依赖于实际的应用场景。
3)当收到一个应答时,主节点在处理数据之前检验应答。在某些情况下,检验的结果可能为错误。如收到来自非期望的子节点的应答,或接收的帧错误,响应超时继续计时;当检测到帧错时,可以执行一个重试。
4)响应超时但没有收到应答时,则产生一个错误。那么主节点会重新进入”空闲” 状态, 并发出一个重试请求。重试的最大次数取决于主节点 的设置。
5)当广播请求发送到串行总线上,没有响应从子节点返回。然而主节点需要进行延迟以便使子节点在发送新的请求处理完当前请求。该延迟被称作 "转换延迟"。因此,主节点会在返回能够发送另一个请求的“空闲”状态之前,到" 等待转换延迟"状态。
6)在单播方式,响应超时必须设置到足够的长度以使任何子节点都能处理完请求并返回响应。而广播转换延迟必须有足够的长度以使任何子节点都能只处理完请求而可以接收新的请求。 因此,转换延迟应该比响应超时要短。
帧错误常见的有:对每个字符的奇偶校验、 对整个帧的冗余校验。
(2)从机的状态特征
如下图:
从上图中可以知道:
1)“空闲” = 没有等待的请求。 这一般是初始上电后的状态。
2)当收到一个请求时,子节点在处理请求中要求的动作前要先检验报文包。当检测到错误时,必须向主节点发送应答告知错误。(错误包含:请求的格式错误、非法动作、非法的访问地址......)。
3)当要求的动作完成后,单播报文要求必须按格式应答主节点。
4)如果子节点在接收到的帧中检测到错误, 则没有响应返回到主节点。
5)任何子节点均应该定义并管理 Modbus 诊断计数器以提供诊断信息。通过使用 Modbus 诊断功能码,可以得到这些计数值。
最后再补充一个主从机的通信时序图:
上面的时序图中描述的就是上面所说的主从机状态特征,对比来看就能看明白是什么意思了。