modbus学习笔记.md

前言

因为modbus是一个工业上面常用的通讯协议,一般在PLC上面用的比较多,主要i是定义了一种数据传输
规范,数据是干吗的,数据有没有出错,接受到数据的从机告诉我数据有没有接受到等等。这里大部分是
采用485形式进行传输,当然也可以使用can总线,232,甚至是以太网的形式来进行,当然这会和之前的
形式有一定的区别。

modbus简介

在使用232或者485作为modbus底层通信协议的时候,整个系统只允许一个设备作为master设备,其他
设备作为salve,也就是说只有master端可以初始化整个通讯网络,并且发起会话,salve之间不允许
直接通讯。

之所以这样是因为在232网络或者485网络中没有冲突检测,要是存在两个master设备,数据容易会发生
混乱。在使用TCP的时候由于协议的物理层已经做过了冲突检测工作,就不需要担心数据冲突。

modbus数据传输的协议模型如下

1
2
3
4
5
6
ADU
├── 地址码
├── PDU
│ ├── 功能码
│ └── 数据
└── CRC

modbus的开头是地址帧,在modbus的网络中,每一个从机都存在一个地址,主机访问从机的时候依靠这
个唯一的地址来进行识别,多个从机接受到主机的数据的时候,匹配接收数据和自身地址,匹配上的那个
从机作出响应,其他的从机都忽略这个响应。

第二个位是功能码,功能码决定这一帧数据是做什么的,比如说输入数据,输出数据,读取控制量等等,

第三个是数据,可以有也可以没有。

第四是差错校验,用来对之前发送的数据校验,防止发送过程中因为电磁干扰,数据出错。

在使用RTU模式的时候,消息的发送至少要以3.5个字符的时间停顿间隔开始。在网络波特率下多样的
字符时间,这是最容易实现的。传输的第一个域是设备地址。可以使用的传输字符是16进制的0~F。网
络设备不断检测总线,包括停顿间隔时间。当第一个域(地址域)接受到的时候,每个设备都进行解码判
断,该消息是否发往自己的。当最后一个字符结束之后,一个至少3.5个字符时间的停顿标定了消息的结
束。一个新的消息可以在这个停顿之后开始。

整个消息帧必须作为一个连续的流进行传输。如果在帧完成之前存在超过1.5个字节的停顿时间,接受
设备将刷新不完整的消息,并假定下一个字节是一个新的消息地址域。同样的,如果一个消息在小于3.5
个字符时间内接着前个消息开始,接受设备将认为它是前一个消息的延续。这将导致一个错误,这样会导
致最后的crc校验值不正缺。

在modbus协议中。主设备通过将要联络的从设备地址放入到消息中的地址来选通从设备。当从设备回应
消息时,从设备会将自己的地址放入到回应消息中,以便主设备知道是哪一个设备作出回应,地址0是用
作广播地址,以使所有的从设备都能够接收到这个消息。

modbus 功能码

代码 中文名称 寄存器 位操作/字操作 操作数量
01 读线圈状态 00001-09999 位操作 单个或多个
02 读离散输入状态 10001-19999 位操作 单个或多个
03 读保持寄存器 40001-49999 字操作 单个或多个
04 读输入寄存器 30001-39999 字操作 单个或多个
05 写单个线圈 00001-09999 位操作 单个
06 写单个保持寄存器 40001-49999 字操作 单个
15 写多个线圈 00001-09999 位操作 多个
16 写多个保持寄存器 40001-49999 字操作 多个

modbus的一些注意事项

  1. modbus的3.5T如何计算:

T = 1000ms * (1起始位 + 数据位 + 奇偶校验 + 停止位) / 波特率

如果你的通讯方式是:波特率9600(表示每秒传输9600个字符),数据位8,无奇偶校验。那么你发送一个
字符的时间是:T = 1000*(1起始位 + 8数据位 + 0奇偶校验位 + 1停止位)/ 9600 = 1.04ms

发送端:发送一帧后延时7*T (其中3.5T 是停止时间 3.5T是起始时间)再发送第二帧,保证一帧数据里
头各字节间间隔时间不能超过1.5T。

接收端:接受一个字节,查询2T时间,是否有接受到下一个字节,有则这帧数据未完成,继续循环接收;没有
则默认这帧数据已经接收完成。

modbus信息中的数据地址

modbus中所有信息都是 以数据0 作为基准,各项数据的第一个地址数据的编号为0,如:

  • 线圈1在modbus信息中的数据位地址编号为0;
  • 线圈127(10进制)在modbus中的地址位为007EH(16进制);
  • 保持寄存器 40001 ,在信息中数据地址为寄存器0000,功能代码区为保持寄存器规定的操作,因此,“4XXX”
    是缺省的地址类型;
  • 保持寄存器 40108 寻址寄存器地址为 006BH(16进制)。

modbus异常码

除广播外,主机向从机设备发送查询并希望有一个正常的响应,主机查询可能产生4种事件:

  • 从机接收查询,通讯错误正常处理信息,则返回一个正常的响应事件。
  • 由于通讯出错,从机不能接收查询数据,因而不返回响应。此时,主机依靠处理程序给出查询超时事件。
  • 若从机接收查询,发现有(LRC或CRC通讯错误),并且返回响应,此时,依靠主机处理程序给出查询超时
    事件;
  • 从机接收查询,无通讯错误,但是无法处理,如读不存在的线圈和寄存器,向主机报告错误的性质。

不正常的响应信息有两个与正常响应不相同的区域:

功能代码区: 正常响应时,从机的响应功能代码区。带原查询功能代码。所有的功能代码的MSB为0(其
值低于80H)。不正常响应时,从机把功能码MSB设为1,使功能代码值大于80H,高于正常响应值。这样,主机
应用程序能时别不正常响应事件,能检查不正常代码的数据区。

数据区: 正常响应中,数据区含有(按查询要求给出)数据或者统计值,在不正常响应中,数据区为一
个不正常的代码值,它说明从机产生不正常的响应条件和原因。示例如下:

1
2
3
4
#master
0a 01 04 a1 00 01 crc crc
#salve
0a 81 02 crc crc

异常码:

代码 名称 含义
01 不合法的功能代码 从机接收的是一种不能执行功能代码。发出查询命令后,该代码指示无程序功能。
02 不合法数据地址 接收的数据地址,是从机不允许的地址。
03 不合法数据 查询数据区的值是从机不允许的值。
04 从机设备故障 从机执行主机请求的动作时出现不可恢复的错误。
05 确认 从机已接收请求处理数据,但需要较长 的处理时间,为避免主机出现超时错误而发送该确认响应。主机以此再发送一个“查询程序完成”未决定从机是否已完成处理。
06 从机设备忙碌 从机正忙于处理一个长时程序命令,请求主机在从机空闲时发送信息。
07 否定 从机不能执行查询要求的程序功能时,该代码使用十进制 13 或 14 代码,向主机返回一个“不成功的编程请求”信息。主机应请求诊断从机的错误信息。
08 内存奇偶校验错误 从机读扩展内存中的数据时,发现有奇偶校验错误,主机按从机的要求重新发送数据请求。