modbus协议及modbus TCP协议

news2024/9/20 10:57:22
一、Modbus协议
  • 1.起源

Modbus由Modicon公司于1979年开发,是一种工业现场总线协议标准

Modbus通信协议具有多个变种,其中有支持串口,以太网多个版本,其中最著名的是Modbus RTU(通信效率最高,基于串口)、Modbus ASCII和Modbus TCP(基于以太网)三种

其中Modbus TCP是在施耐德收购Modicon后1997年发布的。

2.分类

1)Modbus RTU

运行在串口上的协议,采用二进制表现形式以及紧凑的数据结构,通信效率较高,应用比较广泛

2)Modbus ASCII

运行在串口上的协议,采用ASCII码进行传输,并且每个字节的开始和结束都有特殊字符作为标志,传输效率远远低于Modbus RTU,一般只有通讯量比较少时才会考虑它。

3)Modbus TCP

运行在以太网上的协议

3.优势:

免费、简单、容易使用

4.应用场景:

Modbus协议是现在国内工业领域应用最多的协议,不只PLC设备,各种终端设备,比如水控机、水表、电表、工业秤、各种采集设备

二、Modbus tcp协议

1.特点

1)采用主从问答式通信

(一个主机可以对应多个从机,可以发出请求采集数据,发出请求控制设备)

2)Modbus TCP是应用层协议,基于传输层的TCP进行通信的

3)Modbus TCP端口号默认502

2.组成

ModbusTcp协议包含三部分:报文头、功能码、数据        

报文头7个字节,功能码1个字节,Modbus TCP/IP协议最大数据帧长度为260字节,最大252,(1 byte = 8 bit)

1)报文头

包含一个7字节报文头

事物处理标识符:没有限制,主机按照啥发,从机按照什么回

协议标识符:为啥是4个0?写一个0行不行?每一位都是16进制数 一位十六进制由4位2进制组成,8位2进制为一个字节

长度:

单元标识符:从机id

注意:报文头包含内容个数顺序均不可调换

2)寄存器

Modbus TCP通过寄存器的方式存储数据。

一共有四种类型的寄存器,分别是:离散量输入、线圈、输入寄存器、保持寄存器

离散量和线圈其实就是位寄存器(每个寄存器数据占1字节),工业上主要用于控制IO设备输入和保持寄存器是字寄存器(每个寄存器数据占2个字节),工业上主要用于存储工业设备的值

1) 离散量和线圈其实就是位寄存器(每个寄存器数据占1字节),工业上主要用于控制IO设备

线圈寄存器,类比为开关量,每一个bit都对应一个信号的开关状态。所以一个byte就可以同时控制8路的信号。比如控制外部8路io的高低。 线圈寄存器支持读也支持写,写在功能码里面又分为写单个线圈寄存器和写多个线圈寄存器。

离散输入寄存器离散输入寄存器就相当于线圈寄存器的只读模式,他也是每个bit表示一个开关量,而他的开关量只能读取输入的开关信号,是不能够写的。比如我读取外部按键的按下还是松开。

2) 输入和保持寄存器是字寄存器(每个寄存器数据占2个字节),工业上主要用于存储工业设备的值

保持寄存器,这个寄存器的单位不再是bit而是两个byte,也就是可以存放具体的数据量的,并且是可读写的。比如我我设置时间年月日,不但可以写也可以读出来现在的时间。写也分为单个写和多个写

输入寄存器,这个和保持寄存器类似,但是也是只支持读而不能写。一个寄存器也是占据两个byte的空间。类比我我通过读取输入寄存器获取现在的AD采集值 

3)功能码(16进制)

寄存器PLC地址和寄存器的对应关系:

00001-09999 :线圈

10001-19999:离散量输入

30001-39999:输入寄存器

40001-49999:保持寄存器

点亮一个灯:05

读温湿度:04 03

具体协议分析:

实例分享 | ModbusTCP报文详解

4)总结

读数据:

主机--》从机:

报文头--功能码--起始地址--数量

从机--》主机:

报文头(长度可能发生变化)--功能码(不变)--字节计数--数据

在读数据和写单个的时候,字节长度都是0x06( 一个字节的单元标识符,一个字节的功能码,两个字节的地址,两个字节的数据)

写数据:

写单个:

主机--》从机:

报文头--功能码--地址--数据/断通标志(保持寄存器:数据:线圈:断通标志)

从机--》主机:

原文返回

写多个:

主机--》从机:

报文头----功能码----起始地址----数量----字节计数----数据

从机--》主机:  

原文返回

5)练习

练习一

主机询问数据流

00 03 00 00 00 06 01 03 00 63 00 02

00 00:事务处理标识符 

00 00:协议标识符

00 06 :字节 长度

03:功能码(保持寄存器)

0063:起始地址:6*16+3=99,40100

0002:寄存器的数量  40100-40101

00 03 00 00 00 07 01 03 04 05 83 00 76

00 00:事务处理标识符

00 00:协议标识符

00 07:字节长度

03:功能码

04:字节计数

0583:40100寄存器的数据

0076:40101寄存器的数据

练习2

1.读传感器数据,读1个寄存器数据,写出主从数据收发协议。

00 00 00 00  00 06 01 03 00 60 00 01

00 00 00 00  00 05 01 03 02 00 62

  1. 写出控制IO设备开关的协议数据,操作1个线圈,置1。

线圈单个置零:0000 置一:FF00

00 00 00 00  00 06 01 05 00 60 FF 00

00 00 00 00  00 06 01 05 00 60 FF 00

  • 工具安装
    1. Modbus Salve/Poll

1)安装过程:软件默认安装

2)破解:点击connection-》connect,输入序列号(序列号在SN.txt)

3)使用

从机:

先设置,先打开salve端,

再连接:点击connection-》connect

主机:

    1. 网络调试助手

    1. Wireshark

捕获器选择:

windows如果连接有线网络,选择本地连接/以太网

     如果连接无线网络,选择WLAN

如果只是在本机上的通信,选择NPCAP Loopback apdater

或Adapter for loopback traffic capture

过滤条件:

过滤端口:tcp.port==502

过滤IP:ip.addr == 192.168.3.11(windows 的ip)

  1. 练习

在虚拟机写程序实现poll端功能,编写客户端实现和Slave通信。

发送:发送Modbus TCP协议   03功能码

发送:uint8_t data[12]={0x00,0x00,0x00,0x00,0x00,0x06,0x01,0x03,0x00,0x00,0x00,0x02};

接收:recv

#include <stdio.h>
#include <stdlib.h> // atoi
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <arpa/inet.h>
#include <unistd.h>

int main(int argc, char const *argv[])
{
    uint8_t data[12] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x06,
                        0x01, 0x03, 0x00, 0x00, 0x00, 0x03};
    uint8_t buf[32] = {0};
    //1.创建套接字
    int sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sockfd < 0)
    {
        perror("socket err");
        return -1;
    }

    //2.填充结构体
    struct sockaddr_in caddr;
    caddr.sin_family = AF_INET;
    caddr.sin_port = htons(502);
    caddr.sin_addr.s_addr = inet_addr(argv[1]);
    //3.链接
    if (connect(sockfd, (struct sockaddr *)&caddr, sizeof(caddr)) < 0)
    {
        perror("connect err");
        return -1;
    }
    //4.发送
    send(sockfd, data, sizeof(data), 0);
    //5.接收
    recv(sockfd, buf, sizeof(buf), 0);
    for (int i = 0; i < buf[8]; i++)
        printf("%#x ", buf[9+i]);
    putchar(10);
    //6.关闭
    close(sockfd);
    return 0;
}

作业:

  1. 复习今天内容
  2. 完成05功能码  ,写一个线圈
  3. 封装函数。。

/*客户端创建代码 */
#include <stdio.h>
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h> /* superset of previous */
#include <arpa/inet.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
int sockfd;
uint8_t buf[32];
void writecoil(uint8_t *p, int addr, int num)
{
    p[7] = 0x05;
    p[8] = addr >> 8;   //寄存器高位
    p[9] = addr & 0xff; //寄存器低位
    if (num == 1)
    {
        p[10] = 0xff; //置1
    }
    else if (num == 0)
    {
        p[10] = 0x00; //置0
    }
    p[11] = 0x00;
    for (int j = 0; j < 12; j++)
    {
        printf("%#x ", *(p+j));
    }
    send(sockfd, p, 12, 0);
    recv(sockfd, buf, sizeof(buf), 0);
    for (int i = 0; i < 12; i++)
    {
        printf("%#x ", buf[i]);
    }
    putchar(10);
}
void readregster(uint8_t *p, int addr, int num)
{
    p[7] = 0x03;
    p[8] = addr >> 8;   //寄存器高位
    p[9] = addr & 0xff; //寄存器低位
    p[10] = num >> 8;   //数量高位
    p[11] = num & 0xff; //数量低位
    for (int j = 0; j < 12; j++)
    {
        printf("%#x ", *(p + j));
    }
    putchar(10);
    send(sockfd, p, 12, 0);
    recv(sockfd, buf, sizeof(buf), 0);

    for (int i = 0; i < buf[8]; i++)
    {
        printf("%#x ", buf[9 + i]);
    }
    putchar(10);
}
void set_selve_id(uint8_t *p)
{
    p[6] = 0x01;
}
int main(int argc, char const *argv[])
{
    if (argc < 3)
    {
        printf("input err\n");
        return -1;
    }
    //创建套接字
    sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sockfd < 0)
    {
        perror("socket err.");
        return -1;
    }
    //填充结构体
    struct sockaddr_in caddr;
    caddr.sin_family = AF_INET;
    caddr.sin_port = htons(atoi(argv[2]));
    caddr.sin_addr.s_addr = inet_addr(argv[1]);
    socklen_t len = sizeof(caddr);
    //链接
    if (connect(sockfd, (struct sockaddr *)&caddr, len) < 0)
    {
        perror("connect err.");
        return -1;
    }
    // uint8_t data[12] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x01, 0x01, 0x00, 0x07, 0xFF, 0x00};
    // uint8_t data1[12] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x01, 0x01, 0x00, 0x00, 0x00, 0x03};
    uint8_t data[12] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x06};
    int th = sizeof(data);
    int addr = 0x0101;
    int num = 0x0000;
    set_selve_id(data);
    // readregster(data, 0, 2);
    writecoil(data, 6, 1);
    return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1238616.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

读不懂客户,就不足以谈商业成功

数字化的背后&#xff0c;是对顾客心理和行为的深度洞察。因此&#xff0c;品牌营销运营数字化&#xff0c;不仅仅是为了收集转化率数据&#xff0c;也需要通过设计数据指标&#xff0c;更深地了解顾客。 门店管理也是如此&#xff0c;打造未来空间的数智化管理方式&#xff0c…

中低压MOSFET 2N7002T 60V 300mA 双N通道 SOT-523封装

2N7002KW小电流双N通道MOSFET&#xff0c;电压60V电流300mA&#xff0c;采用SOT-523封装形式。低Ros (on)的高密度单元设计&#xff0c;压控小信号开关&#xff0c;具有高饱和电流能力&#xff0c;ESD保护。可应用于直流/直流转换器&#xff0c;电池开关&#xff0c;便携式设备…

IDEA 配置maven结合案例使用篇

1. 项目需求和结构分析 需求案例&#xff1a;搭建一个电商平台项目&#xff0c;该平台包括用户服务、订单服务、通用工具模块等。 项目架构&#xff1a; 用户服务&#xff1a;负责处理用户相关的逻辑&#xff0c;例如用户信息的管理、用户注册、登录等。 spring-context 6.0.…

CentOS 7 升级gcc/g++ 至7.3、8.3、9.3

功能需求&#xff1a;CentOS 7 编译安装spdlog-1.12.0 提示如下错误信息&#xff1a; [rootlocalhost build]# cmake .. && make -j -- Build spdlog: 1.12.0 -- Build type: Release -- Generating example(s) -- Generating install -- Configuring done -- Generat…

02房价预测

目录 代码 评分算法&#xff1a; 代码 import numpy as np from sklearn import datasets from sklearn.linear_model import LinearRegression# 指定版本才有数据集 # C:\Users\14817\PycharmProjects\pythonProject1\venv\Scripts\activate.bat # pip install scikit-le…

云服务器-从零搭建前后端服务

使用须知 选择0M带宽不能访问公网&#xff08;不分配公网IP&#xff09;&#xff0c;如需分配公网IP请增加带宽值。云服务器ECS默认不开启虚拟内存如您需要使用请登录云服务器内部操作。Linux开启swap&#xff08;虚拟内存&#xff09;、Windows虚拟内存的设置若您购买了数据盘…

2023-11-21 LeetCode每日一题(美化数组的最少删除数)

2023-11-21每日一题 一、题目编号 2216. 美化数组的最少删除数二、题目链接 点击跳转到题目位置 三、题目描述 给你一个下标从 0 开始的整数数组 nums &#xff0c;如果满足下述条件&#xff0c;则认为数组 nums 是一个 美丽数组 &#xff1a; nums.length 为偶数对所有满…

如何使用 Navicat 连接 GaussDB 主备版

Navicat Premium&#xff08;16.2.8 Windows版或以上&#xff09; 已支持对GaussDB 主备版的管理和开发功能。它不仅具备轻松、便捷的可视化数据查看和编辑功能&#xff0c;还提供强大的高阶功能&#xff08;如模型、结构同步、协同合作、数据迁移等&#xff09;&#xff0c;这…

Leetcode——169 多数元素

我的答案 class Solution {public int majorityElement(int[] nums) {int len nums.length;Arrays.sort(nums);int count 1;int res 0;if(len 1){return nums[0];}for(int i0; i<len-1; i){if(nums[i]nums[i1]){count;}else{count 1;}if(count>len/2){res nums[i]…

JavaDS —— 初识集合框架 + 时间/空间复杂度

目录 1. 初识集合框架 1.1 集合框架的初识 1.2 什么是数据结构&#xff1f; 2. 时间与空间复杂度 2.1 时间复杂度 2.2 大O的渐进表示法 2.3 常见时间复杂度计算举例 2.4 空间复杂度 1. 初识集合框架 1.1 集合框架的初识 什么叫集合&#xff1f;什么叫框架&#xff1f;什么又叫集…

用友NC Cloud uploadChunk任意文件上传漏洞复现 [附POC]

文章目录 用友NC Cloud uploadChunk任意文件上传漏洞复现 [附POC]0x01 前言0x02 漏洞描述0x03 影响版本0x04 漏洞环境0x05 漏洞复现1.访问漏洞环境2.构造POC3.复现 0x06 修复建议 用友NC Cloud uploadChunk任意文件上传漏洞复现 [附POC] 0x01 前言 免责声明&#xff1a;请勿利…

敏捷DevOps专家王立杰:端到端DevOps持续交付的5P法则 | IDCF

今天有一个流行的英文缩写词用来刻画这个风云变幻的时代&#xff1a;VUCA&#xff08;乌卡时代&#xff09;。四个英文字母分别表示动荡性&#xff08;Volatility&#xff09;、不确定性&#xff08;Uncertainty&#xff09;、复杂性&#xff08;Complexity&#xff09;和模糊性…

【精选】构建智能木材计数系统:深度学习与OpenCV完美结合(详细教程+源码)

1.研究背景与意义 随着科技的不断发展&#xff0c;计算机视觉技术在各个领域中得到了广泛的应用。其中&#xff0c;卷积神经网络&#xff08;Convolutional Neural Network&#xff0c;CNN&#xff09;作为一种强大的深度学习模型&#xff0c;已经在图像识别、目标检测、人脸识…

C语言--每日五道选择题-- Day22

第一题&#xff08;注意&#xff09; 1.下列 C 代码中&#xff0c;不属于未定义行为的有&#xff1a;______。 A&#xff1a;int i0; i(i); B&#xff1a;char *p"hello"; p[1]E; C&#xff1a;char *p"hello"; char ch*p; D&#xff1a;int i0; printf(&q…

2024年湖北省水利厅的安管人员水安ABC证报考指南

2024年湖北省水利厅的安管人员水安ABC证报考指南 关于水安ABC报考&#xff0c;很多企业乃至个人都不是很清楚流程&#xff0c;叙后尘来给大家科普一下报考详细细节。2023年年度仅剩一次的报考时间定于2023年11月23日至11月28日。在这个时间段才可以网上填写报考资料&#xff0…

JOSEF信号继电器 JX-18A/2 电压 220VAC辅助电源 板后接线

JX-18/2A系列信号继电器 JX-18A/2A1信号继电器&#xff1b; JX-18A/2A2信号继电器&#xff1b; JX-18B /2A1信号继电器; JX-18B/2A2信号继电器; JX-18C/2A1信号继电器; JX-18C/2A2信号继电器; JX-18E/2A1信号继电器; JX-18E/2A2信号继电器; JX-18D/2A1信号继电器; JX…

java继承和重写(代码演示)

java中的继承和重写 概念 继承 在 Java 中&#xff0c;继承是面向对象编程中的重要概念&#xff0c;它允许一个类&#xff08;称为子类&#xff09;继承另一个类&#xff08;称为父类&#xff09;的属性和方法。子类可以继承父类的非私有属性和方法&#xff0c;并且可以添加…

C++一个关于delete的幼稚错误

分析 在项目开发中&#xff0c;遇上这么一个错误&#xff1a; 0xc00000fd stack_overflow 这是一个栈溢出的错误&#xff0c;奇怪&#xff0c;我delete怎么会提示这么一个错误呢&#xff1f; 与是问题了群&#xff1a; 总结 这个错误实在是蠢啊&#xff01; 没有细想&am…

m4s格式视频文件如何转mp4?三个方法教会你!

m4s格式是一种视频分片格式&#xff0c;它将视频文件分成多个小块&#xff0c;方便网络传输和播放。这种格式常用于流媒体服务&#xff0c;如在线视频网站、直播平台等&#xff0c;比如B站哔哩哔哩下载下来的视频就是这种格式。 方法一&#xff1a;野葱视频转换器 一款音视频转…

【UE5】蓝图

在开发过程中&#xff0c;不可避免地会有一些蓝图的操作。同时&#xff0c;蓝图也是UE很有特色的一个内容。 了解蓝图是什么&#xff08;What is BP?&#xff09; 广义上&#xff1a;蓝图是UE内置的脚本语言&#xff0c;可以书写类似代码的逻辑。&#xff08;任何可以连那种块…