Modbus简介以及NModbus学习分享 |
您所在的位置:网站首页 › EasyModbus说明书 › Modbus简介以及NModbus学习分享 |
Modbus以及上位机软件实际运用 Demo代码Git代码示例:https://github.com/chenheze90/Learning01_Modbus/tree/master Modbus简介Modbus是一种串行通讯协议,通常运用在电子设备之间的通讯上。在许多制造行业中应用极其广泛;进过多年的发展Modbus已经成为工业领域通信协议的业界标准(De facto),并且现在是工业电子设备之间常用的连接方式。 Modbus原本设计是针对PLC通讯问题而设计,目前Modbus协议主要用在串口、以太网和其他互联网协议的网络,基本上占大部分的Modbus是通过TCP或者485串口进行信息交互。 如下所示,Modbus是在应用层封装、解析、传递消息的。 协议版本 ModbusRTUModbus RTU是一种紧凑的,采用二进制表示数据的方式,使用串行通信(serial communication)方式。RTU格式后续的命令/数据带有循环冗余校验的校验和(CRC)。被配置为RTU变种的节点不会和设置为ASCII变种的节点通信,反之亦然。 ModbusASCIIModbus ASCII是一种人类可读的,冗长的表示方式。使用串行通信(serial communication)方式。ASCII格式采用纵向冗余校验的校验和(LRC)。相比之下,RTU格式的协议较为常用。 Modbus/TCP对于通过TCP/IP(例如以太网)的连接,存在多个Modbus/TCP变种,这种方式不需要校验和计算,目前较为广泛运用的是Modbus/TCP。 通讯简析Modbus协议是一个master/slave(或者server/client)架构的协议,简单点理解就是主从结构。有且仅有一个节点是主节点,其他使用Modbus协议参与通信的节点是子节点。每一个子设备都有一个唯一的地址。在以太网上,任何一个设备都能发送一个Modbus命令,但是通常也只有一个主节点设备启动指令。 一个ModBus命令包含了打算执行的设备的Modbus地址。所有设备都会收到命令,但只有指定位置的设备会执行及回应指令(地址0例外,指定地址0的指令是广播指令,所有收到指令的设备都会运行,不过不回应指令)。所有的Modbus命令包含了检查码,以确定到达的命令没有被破坏。基本的ModBus命令能指令一个RTU改变它的寄存器的某个值,控制或者读取一个I/O端口,以及指挥设备回送一个或者多个其寄存器中的数据。 有许多modems和网关支持Modbus协议,因为Modbus协议很简单而且容易复制。它们当中一些为这个协议特别设计的。有使用有线、无线通信甚至短消息和GPRS的不同实现。不过设计者需要克服一些包括高延迟和时序的问题。 错误通讯当主机传送的报文不符合格式、从机不支援此功能等问题时,这时从机就会回复一个错误信息,例子如下 请求数据: 从机地址 功能码 数据1 数据2 … 数据n CRCL CRCH 0x01 0x03 0x01 0x01 0x02 0xd5 0xdd 返回数据: 从机地址 功能码 异常码 CRCL CRCH 0x01 0x03 0x02 0xd5 0xdd 其中的异常码如下表所示: 功能码 名称 说明 01 ILLEGAL FUNCTION 不支援的功能 02 LLEGAL DATA ADDRESS 不合法的地址 03 ILLEGAL DATA VALUE 不合法的数值 04 SLAVE DEVICE FAILURE Slave 失效 05 ACKNOWLEDGE 命令执行中 06 SLAVE DEVICE BUSY Slave 忙碌 寄存器/暂存器寄存器分四类 类别区号读写值范围线圈状态0区可读可写布尔量00001-09999离散输入状态1区只读布尔量10001-19999输入寄存器3区只读寄存器30001-39999保持寄存器4区可读可写寄存器40001-49999并且Modbus还给每个区都划分了地址范围 主机向从机获取数据时,只需要告诉从机数据的起始地址,还有获取多少字节的数据,从机就可以发送数据给主机。 Modbus数据模型规定了具体的地址范围,每一个从机,都有实际的物理存储,跟modbus的存储区相对应,主机读写从机的存储区,实际上就是对从机设备对应的实际存储空间进行读写。 RTU协议帧结构RTU是常用的一种协议,一个报文就是一帧数据,实际上是一串有组织的数据串。 CRC占用两个字节包含了一个16位的二进制值,如上表所示的CRCL和CRCH。这两个值在发出的时候已经由发出的设备计算得出,然后附加到数据帧尾部,接收设备在接收数据时重新计算CRC值,然后与接收到的CRC域中的值进行比较,如果这两个值不相等就判断数据发生了错误。 功能码Modbus规定了多个功能,那么为了方便的使用这些功能,我们给每个功能都设定一个功能码,也就是指代码。 功能码 功能说明 01H 读取输出线圈 02H 读取输入线圈 03H 读取保持寄存器 04H 读取输入寄存器 05H 写入单线圈 06H 写入单寄存器 0FH 写入多线圈 10H 写入多寄存器 Modbus协议同时规定了二十几种功能码,但是常用的只有8种,用于对存储区的读写。 上位机代码实例 ModbusSlaveModbusSlave是modbus常见的调试工具,可以模拟32个子设备。首先下载ModbusSlave。地址: https://www.pcsoft.com.cn/soft/197832.html 安装过程此处省略,直接点下一步即可。 TCP协议Modbus-TCP协议与Modbus-RTU协议最大的不同就是多了一个MBAP报文头,这个是TCP独有的特征。 MBAP的长度是7个字节,如下图所示。 功能码如下: 功能码 功能说明 01H 读取输出线圈 02H 读取输入线圈 03H 读取保持寄存器 04H 读取输入寄存器 05H 写入单线圈 06H 写入单寄存器 0FH 写入多线圈 10H 写入多寄存器 线圈寄存器:实际上就可以类比为开关量(继电器状态),每一个bit对应一个信号的开关状态。所以一个byte就可以同时控制8路的信号。比如控制外部8路io的高低。 线圈寄存器支持读也支持写,写在功能码里面又分为写单个线圈寄存器和写多个线圈寄存器。对应上面的功能码也就是:0x01 0x05 0x0f离散输入寄存器:如果线圈寄存器理解了这个自然也明白了。离散输入寄存器就相当于线圈寄存器的只读模式,他也是每个bit表示一个开关量,而他的开关量只能读取输入的开关信号,是不能够写的。比如我读取外部按键的按下还是松开。所以功能码也简单就一个读的 0x02保持寄存器:这个寄存器的单位不再是bit而是两个byte,也就是可以存放具体的数据量的,并且是可读写的。一般对应参数设置,比如我我设置时间年月日,不但可以写也可以读出来现在的时间。写也分为单个写和多个写,所以功能码有对应的三个:0x03 0x06 0x10输入寄存器:这个和保持寄存器类似,但是也是只支持读而不能写,一般是读取各种实时数据。一个寄存器也是占据两个byte的空间。类比我我通过读取输入寄存器获取现在的AD采集值。对应的功能码也就一个 0x04 Modebus封装——NModbus在vs中打开nuget,下载NModbus插件 所有步骤之前,要先联接slave,使模拟器上线。 读取线圈数据首先要将模拟器设置成线圈
然后设置线圈的值 在代码中读取数据,本次读取的数据是从第1位开始()模拟器有0的位置)开始取5个值 代码执行结果如下图所示 同样的,读取离散线圈的数据,需要将模拟器的功能转成离散模式 此次模拟 读取0~6的数据 结果如下 读取保存寄存器的值: 我们只要读取从0之后的4个数据,代码如下 结果如下图所示 输入寄存器和离散线圈一样,都是只读。 先设置模拟器数据类型 本次读取从0开始的4个字符 结构如下所示 首先,将模拟器slave调整成线圈模式 模拟在1这个位置写入1,在方法中1即true,0即false 单寄存器是两个byte,主要存储复杂的数据,如时间,文本等。同样要先设置模拟器数据类型。 然后模拟在第四位写入一个56,结果如下图所示 代码示例 代码示例 |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |