目录
Modbus RTU与Modbus TCP 的区别及RTU特性
合。与请求数据相关的最常使用的请求头是Content-Type和Content-Length。
Modbus协议概述
1. 起源与发展
- 起源: Modbus协议由Modicon公司于1979年开发,旨在为工业控制系统提供一种可靠的串行通信手段。
- 发展: 经历了多个版本的演变,包括Modbus RTU、Modbus ASCII和Modbus TCP等。
- Modbus TCP: 1997年由施耐德电气在收购Modicon后推出,适应了网络化的工业环境需求。
2. 协议分类
- Modbus RTU: 一种高效、紧凑的二进制串行通信协议,适用于大多数工业场景。
- Modbus ASCII: 采用ASCII编码的串行通信协议,适用于小数据量传输,但效率较低。
- Modbus TCP: 基于以太网的协议,利用TCP/IP网络实现设备间的高速数据交换。
3. 优势
- 免费: 开放标准,无需支付许可费用。
- 简单: 易于理解和实施。
- 易用: 广泛的支持和成熟的生态系统。
4. 应用场景
- 广泛应用: 在国内及全球工业领域中,Modbus是最常用的标准之一,不仅限于PLC,还包括水表、电表、工业秤等各种终端设备。
5. Modbus TCP特点
- 主从问答通信: 设备间通信遵循主从模式,由主设备发起请求,从设备响应。
- 应用层协议: Modbus TCP位于OSI模型的应用层,使用TCP作为传输层协议。
- 默认端口号: Modbus TCP服务默认监听在TCP端口502上。
Modbus TCP协议格式
报文结构
- 报文头
- 功能代码
- 数据
报文长度
- 最大数据帧长度: Modbus TCP/IP协议允许的最大数据帧长度为260字节,包括所有头部和负载信息。
2.2 报文头
Modbus寄存器类型与功能
位寄存器
-
线圈寄存器: 类似于开关量,每个比特位代表一个信号的状态,适合控制IO设备的开关。一个字节(8比特)可同时控制8个信号状态。
- 读写操作: 支持读取和写入,功能码包括读取单个线圈(0x01)、写单个线圈(0x05)、写多个线圈(0x0F)。
-
离散输入寄存器: 类似线圈寄存器,但仅支持读取,用于接收外部输入信号的状态,如按键的按下与释放。
字寄存器
-
保持寄存器: 单位为两个字节,用于存储具体的数值,支持读写操作,如设置或读取时间等。
- 读写操作: 功能码涵盖读取保持寄存器(0x03)、写单个保持寄存器(0x06)、写多个保持寄存器(0x10)。
-
输入寄存器: 类似保持寄存器,但只支持读取,用于获取如AD采样值等输入数据,每个寄存器占用两个字节空间。
- 读取操作: 对应功能码为读取输入寄存器(0x04)。
- 功能码
例如将一个灯点亮就是用05 看一个灯开没开就是01 读温湿度就用03
读数据操作
主机 -> 从机
- 发送报文:
- 报文头
- 功能码
- 起始地址
- 数据数量
- 接收报文:
- 报文头
- 功能码
- 字节计数
- 数据
写单个数据
主机 -> 从机
- 发送报文:
- 报文头
- 功能码
- 地址
- 断通标志(如:开/关)
写多个数据
主机 -> 从机
- 发送报文:
- 报文头
- 功能码
- 起始地址
- 数据数量
- 字节计数
- 数据(包含多个值)
3 网络调试助手
1)软件默认安装
2)破解
点击connection->connect,输入序列号即可
3)使用
先设置
后连接(连接时注意先开启slave端(相当于服务器),后起poll端(相当于客户端))
查询windows ip:
win +R输入cmd
输入ipconfig
3.2. 网络调试助手
捕获器选择
- Windows有线网络: 选择“本地连接”或“以太网”适配器。
- 无线网络: 选择“WLAN”适配器。
- 本机通信: 选择“NPCAP Loopback Adapter”或“Adapter for loopback traffic capture”。
过滤条件设定
- 过滤端口: 使用
tcp.port == 502
来过滤ModbusTCP协议的通信。 - 过滤IP: 使用
ip.addr == 192.168.3.11
来过滤特定IP地址的通信。
通信(TCP)与数据发送格式
- 功能码:
03
表示读取保持寄存器。 - 数据格式:
Cuint8_t data[12] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00, 0x01 };
#include <arpa/inet.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <stdlib.h>
#include <string.h>
#include <sys/select.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
#include <pthread.h>
int sockfd;
uint8_t buf[32];
void set_value(uint8_t *p, int id)
{
p[6] = id;
}
void read_value(uint8_t *p, int addr, int nb)
{
p[5] = 06;
p[7] = 06;
p[8] = addr >> 8;
p[9] = addr & 0xff;
p[10] = nb >> 8;
p[11] = nb & 0xff;
send(sockfd, p, 12, 0);
}
int main(int argc, char const *argv[])
{
//1.创建套接字
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
{
perror("soclfd error\n");
return -1;
}
//2.填充结构体
struct sockaddr_in saddr;
saddr.sin_family = AF_INET;
saddr.sin_port = htons(atoi(argv[2]));
saddr.sin_addr.s_addr = inet_addr(argv[1]);
//3.链接
if (connect(sockfd, (struct sockaddr *)&saddr, sizeof(saddr)) < 0)
{
perror("connecting error\n");
return -1;
}
set_value(buf, 1);
read_value(buf, 0, 888);
close(sockfd);
return 0;
}
Modbus RTU与Modbus TCP 的区别及RTU特性
Modbus RTU 特性
Modbus RTU (Remote Terminal Unit) 是一种用于串行链路的Modbus协议版本,它主要应用于工业控制领域,特别是在需要通过串行接口如RS-232或RS-485进行通信的场合。其特点如下:
- 串行通信: 基于串行通信标准,如RS-232/RS-485。
- CRC校验: 使用CRC16校验算法来确保数据传输的完整性,这是因为串行通信可能受到电磁干扰的影响。
- 实时性: 由于串行通信的性质,RTU在实时性上可能略逊于TCP,尤其是在长距离通信中。
- 简单可靠: RTU协议结构相对简单,易于实现,且在工业环境中具有较高的可靠性。
Modbus TCP 与 RTU 区别
- 通信介质: Modbus TCP基于以太网(TCP/IP)进行通信,而Modbus RTU基于串行链路。
- 数据包格式: Modbus TCP包含一个额外的报文头MBAP (Modbus Application Protocol Data Unit),而RTU则在其数据帧末尾添加了CRC校验码。
- 错误检测: TCP/IP协议本身提供了错误检测和重传机制,因此Modbus TCP不需额外的CRC校验;而RTU由于基于串行链路,通常需要CRC校验来增强数据完整性。
- 实时性与速度: Modbus TCP通常具有更好的实时性和速度,尤其是在局域网内。
RTU协议格式详解
以功能码03
(读取保持寄存器)为例,RTU的报文格式如下:
- 地址码: 识别接收设备的唯一标识符。
- 功能码: 指定请求或响应的类型。
- 数据: 包括起始地址、数量以及(对于响应报文)实际读取的数据值。
- CRC校验码: 确保数据在传输过程中未被破坏。
主机给从机的请求报文格式
101 : 从机ID
203 : 功能码
300 00 : 起始地址
400 01 : 数量
584 0A : CRC校验码
从机给主机的响应报文格式
101 : 从机ID
203 : 功能码
302 : 字节计数
400 14 : 实际读取的数据
5b8 44 : CRC校验码
模拟器的使用
由于实际硬件产品成本较高,我们这里可以使用Modbus软件模拟器,进行数据模拟从而分析Modbus协议。
使用工具:
1. ModbusPoll(模拟主机)和ModbusSlave(模拟从机)
2. vspd虚拟串口
3. UartAssist串口调试工具
设置串口参数要求:波特率为9600 8位数据位 1位停止位 无流控 无校验
虚拟串口的使用:
- 虚拟串口的安装
1.将压缩包解压后,双击vspd.exe文件进行安装
2.安装完成后,找到安装目录,将Cracked下的文件复制到软件安装目录
3.打开软件,添加COM1和COM2端口(用完之后记得删除端口)
4.添加完端口后,打开设备管理器,这里出现如下图所示即可。
或
二、虚拟机绑定端口
- 将虚拟机在系统关机(必须是关机状态,挂起不行)状态下,点击虚拟机->设置->硬件->添加串行端口,添加COM1
- 添加完成后,第一次使用需要将电脑重启
- 重启之后,打开虚拟机,点击虚拟机->可移动设备->串行端口->连接
- 当连接上虚拟串口后,在终端输入dmesg | grep tty,可以查看到对应的设备文件,其中默认的会有ttyS0文件,剩下的就是虚拟串口对应的设备文件。
三、测试通信
1.Windows打开串口调试工具,选择好串口COM2->COM1,设置对应的波特率
2.在虚拟机运行minicom
minicom
是 Linux 中一个非常实用的串行通信工具,主要用于通过串行端口(例如 RS-232 或 RS-485 接口)与外部设备进行通信。它可以充当终端仿真器,允许用户与各种嵌入式系统、调制解调器、路由器、交换机或其他任何通过串行端口进行通信的设备进行交互。
在虚拟机安装minicom软件
sudo apt-get install minicom
在终端执行sudo minicom -s
1)选择serial port setup,回车
2)设置设备文件,波特率,关闭流控,按如下图设置(文件改成自己的)
3)修改完成后,回车,保存修改,选择save setup as dfl,敲回车,再次选择exit回车
4)退出后就可以和windows下的串口调试工具进行通信测试
5)也可以在这个界面输入字符,查看串口助手的显示情况。
6)退出:ctrl+A、Z,在弹出的界面里输入X,即可退出。
四、将Modbus Slave模拟器作为RTU设备的从机
虚拟机绑定COM1端口,slave连接COM2端口,虚拟机通过编程测试串口通信
Modbus Slave端的配置如下:
五、可能会遇到的问题
虚拟串口完成主机与vmware下虚拟机进行串口通信_xcom2v2.0怎么用-CSDN博客
『实用教程』VSPD虚拟串口工具——从此告别硬件串口调试_虚拟串口vspd-CSDN博客
3. vmware虚拟机检测不到vspd虚拟串口问题
4.6 库的安装和使用
安装libmodbus
-
解压压缩包
Bash1tar -xvf libmodbus-3.1.7.tar.gz
-
进入源码目录并创建安装目录
Bash1cd libmodbus-3.1.7 2mkdir install
-
执行configure进行安装配置
Bash1./configure --prefix=$PWD/install
-
编译与安装
Bash1make 2make install
配置编译环境
-
编译示例
Bash1gcc xx.c -I ./install/include/modbus -L./install/lib -lmodbus 2./a.out
-I
指定头文件路径-L
指定库文件路径-l
指定库名
-
简化编译,将头文件和库文件复制到系统路径
Bash1sudo cp install/include/modbus/*.h /usr/include/ 2sudo cp -r install/lib/* /lib/
后续编译时,可以直接使用:
Bash1gcc xx.c -lmodbus
默认搜索路径
- 头文件:
/usr/include
、/usr/local/include
- 库文件:
/lib
、/usr/lib
libmodbus函数接口
-
创建Modbus实例
C1modbus_t* modbus_new_tcp(const char *ip, int port);
- 功能:以TCP方式创建Modbus实例并初始化。
- 参数:
ip
:IP地址port
:端口号
- 返回值:成功返回Modbus实例,失败返回NULL。
-
设置从机ID
C1int modbus_set_slave(modbus_t *ctx, int slave);
- 功能:设置从机ID。
- 参数:
ctx
:Modbus实例slave
:从机ID
- 返回值:成功返回0,失败返回-1。
-
建立连接
C1int modbus_connect(modbus_t *ctx);
- 功能:与从机建立连接。
- 参数:
ctx
:Modbus实例 - 返回值:成功返回0,失败返回-1。
-
释放Modbus实例
C1void modbus_free(modbus_t *ctx);
- 功能:释放Modbus实例。
- 参数:
ctx
:Modbus实例
-
关闭套接字
C1void modbus_close(modbus_t *ctx);
- 功能:关闭套接字。
- 参数:
ctx
:Modbus实例
-
读取线圈状态
C1int modbus_read_bits(modbus_t *ctx, int addr, int nb, uint8_t *dest);
- 功能:读取线圈状态。
- 参数:
ctx
:Modbus实例addr
:寄存器起始地址nb
:寄存器个数dest
:得到的状态值
-
读取输入状态
C1int modbus_read_input_bits(modbus_t *ctx, int addr, int nb, uint8_t *dest);
- 功能:读取输入状态。
- 参数:
ctx
:Modbus实例addr
:寄存器起始地址nb
:寄存器个数dest
:得到的状态值
合。与请求数据相关的最常使用的请求头是Content-Type和Content-Length。
HTTP协议详解
5.1 HTTP协议简介
- 定义: Hyper Text Transfer Protocol,用于Web浏览器与Web服务器之间进行数据交互的传输协议,属于应用层协议。
- 工作原理: 基于TCP通信协议,工作于B/S架构上,浏览器作为客户端通过URL向服务器发送请求,服务器响应请求并返回信息。
- 默认端口: 80,可配置为其他端口如8080。
5.2 HTTP特点
- 短连接: 每次连接只处理一个请求,处理完毕后断开连接,提高传输效率。
- 媒体独立: 支持多种类型数据传输,通过MIME-type指定数据类型。
- 无状态: 协议本身不保存会话信息,每次请求独立处理,适合高并发场景。
5.3 HTTP协议格式
请求结构
- 请求行: 包含请求方法、URL、HTTP版本,如
GET /example.html HTTP/1.1
。 - 请求头: 包括客户端信息、请求偏好等,如
Accept: text/html
。 - 空行: 分隔请求头和请求体,由回车符和换行符组成。
- 请求体: POST方法中携带的请求数据,GET方法中不使用。
请求方法
- GET: 获取资源。
- POST: 发送数据到服务器,创建/更新资源。
- PUT: 更新资源。
- DELETE: 删除资源。
- HEAD: 获取资源头部信息。
- OPTIONS: 查询支持的HTTP方法。
- TRACE: 跟踪请求路径。
- CONNECT: 建立代理连接。
常见请求头
- Accept: 客户端可接受的响应类型。
- Accept-Charset: 可接受的字符集。
- Accept-Language: 可接受的语言。
- Connection: 是否保持连接。
- Content-Length: 请求体长度。
- Content-Type: 请求体数据类型。
1. 客户端
客户端发送一个HTTP请求到服务器的请求消息包括以下格式:请求行、请求头部、空行和请求数据四个部分组成,下图给出了请求报文的一般格式。
- 服务器响应消息格式:
HTTP响应也由四个部分组成,分别是:状态行、消息报头、空行和响应正文。
状态行:由三部分组成,HTTP协议的版本号、状态码、以及对状态码的文本描述。例如:HTTP/1.1 200 OK (CRLF) 。(200表示请求已经成功)