通信网络
Modbus是一种通信协议,常用于工业自动化领域的数据通信和设备控制。其最初由Modicon公司开发并于1979年发布,在工业领域得到广泛应用。Modbus通信协议支持串口、以太网、无线等多种通信方式,具有数据传输简单高效、易于实现等特点。Modbus协议并非开源协议,但它的使用和实现并没有什么限制。
协议类型
Modbus通信协议主要分为以下三种类型:
1. Modbus RTU:基于串口通信,并采用二进制格式,速度快、可靠。 2. Modbus ASCII:同样基于串口通信,采用ASCII码格式,实现简单、易于调试。 3. Modbus TCP/IP:基于以太网通信,具有速度快、网络连接稳定等优点,但需要网络设备的支持。Modbus-RTU 协议采用二进制编码和CRC错误校验, RTU设备通常使用RS232、RS485和RS422通信接口,一般通信距离小于15米选RS232,通信距离大于15米选RS485和RS422。本文主要介绍和学习 RS-485 总线通信控制下的标准 Modbus-RTU 协议。
协议理解
Modbus协议的信息帧共有两种类型,分别为请求帧和响应帧。其中,请求帧由主机发送给从机,用于请求数据或控制从机;响应帧则由从机发送给主机,用于响应主机的请求。 帧描述:
报文帧由时长至少 3.5 个字符时间的空闲间隔区分,称为 t3.5,RTU 帧传输空闲间隔区分示意图:
数据类型:
在Modbus协议中,数据类型主要分为两类:线圈和寄存器。其中线圈又分为离散输出线圈和离散输入线圈,寄存器又分为只读寄存器和通用寄存器。
数据类型 | 类型码 | 字节数 | 描述 |
---|---|---|---|
离散输出线圈 | 01 | 1 | 可读可写,代表系统输出状态 |
离散输入线圈 | 02 | 1 | 只读,代表系统输入状态 |
只读寄存器 | 03 | 2 | 只读,代表系统参数或状态 |
通用寄存器 | 04 | 2 | 可读可写,代表系统参数或状态 |
功能码:
这些是常用Modbus功能码的简介,具体的功能码及其参数格式请参考Modbus协议文档。
功能码 | 名称 | 描述 |
---|---|---|
01 | Read Coil Status(读取线圈状态) | 用于读取远程设备的多个线圈状态。 |
02 | Read Input Status(读取输入状态) | 用于读取远程设备的多个输入状态。 |
03 | Read Holding Registers(读保持寄存器) | 用于读取远程设备的多个保持寄存器值。 |
04 | Read Input Registers(读输入寄存器) | 用于读取远程设备的多个输入寄存器值。 |
05 | Write Single Coil(写单个线圈) | 用于控制远程设备的单个线圈状态。 |
06 | Write Single Register(写单个保持寄存器) | 用于设置一个远程设备的单个保持寄存器。 |
15 | Write Multiple Coils(写多个线圈) | 用于设置远程设备的多个线圈状态。 |
16 | Write Multiple Registers(写多个保持寄存器) | 用于设置远程设备的多个保持寄存器值。 |
简单理解
只有是人为规定的就有规律可循, 最简单的就是看厂家的手册, 理论上的东西和实际是有区别的, 这就是为啥市面上那些教程, 明明讲了很多, 但是啥也没学到。协议协议实际就是有规律的数据,这和协议栈是不同概念的,直接看厂家给的通信实例:
然后再根据功能码阅读相关说明:
根据说明把地址以及参数找出来,再把这些数据进行CRC算法计算:
// CRC校验 static uint8_t modbus_crc(uint8_t *data, uint16_t length) { uint16_t crc = 0xFFFF; uint16_t i, j; for (i = 0; i < length; i++) { crc ^= data[i]; for (j = 0; j < 8; j++) { if (crc & 0x0001) crc = (crc >> 1) ^ 0xA001; else crc = crc >> 1; } } // 低位在前高位在后 if ((uint8_t)(crc & 0x00ff) == data[i++] && (uint8_t)((crc & 0xff00) >> 8) == data[i]) { return 0; }; return 1; }
最后把这些数据整合,就形成了一帧数据,把这些数据发出去,从机就会返回数据了,根据业务对从机返回的数据进行处理即可!
审核编辑:汤梓红
全部0条评论
快来发表一下你的评论吧 !