Modbus_tcp

目录

一:modbus起源

1.起源

2.  分类:

3.  优势:

4.  应用场景:

5.ModbusTCP特点(掌握):

二、  ModbusTCP的协议

1.  报文头

2.  寄存器

1. 线圈(Coils)

2. 离散量输入(Discrete Inputs)

3. 输入寄存器(Input Registers)

总结

3.功能码

01功能码分析

05功能码分析

0F功能码分析

练习:封装函数实现03,05功能码的作用


一: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,一般只有通讯量比较少时才会考虑它。

注:在ASCII模式下,每个8位的字节被拆分成两个ASCII字符进行发送,比如十六进制0xAF(1010 1111),会被分解成ASCII字符“A”(0100 0001)和”F”(0100 0110)进行发送,其发送量显然比RTU增加一倍。

3)Modbus TCP

运行在以太网上的协议

3.  优势:

免费、简单、容易使用

4.  应用场景:

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

5.ModbusTCP特点(掌握):

1)采用主从问答式通信

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

注:更好的理解网络模型的分层特点:

各层之间独立,每一层不需要知道下一层如何实现

当任何一层发生变化时,只要层间接口关系保持不变,则这层以上或以下层不受影响。

3)Modbus TCP端口号默认502

二、  ModbusTCP的协议

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

MBAP:Modbus Application Protocol (modbus报文头)

PDU:Protocol Data Unit(协议数据单元)

Modbus TCP/IP协议最大数据帧长度为260字节

1.  报文头

包含7个字节

2.  寄存器

1. 线圈(Coils)

  • 定义:线圈在Modbus协议中通常被类比为开关量,每一个bit都对应一个信号的开关状态。它主要用于控制IO设备的开关状态,如继电器、阀门等。
  • 访问类型:可读可写。通过发送特定的功能码(如01H、05H、0FH),可以读取或修改线圈的状态。
  • 应用场景:用于控制外部设备的开/关状态,如控制灯的亮灭、电机的启停等。

2. 离散量输入(Discrete Inputs)

  • 定义:离散量输入寄存器相当于线圈寄存器的只读模式,每个bit表示一个开关量,但只能读取输入的开关信号,不能修改。
  • 访问类型:只读。通过发送功能码02H,可以读取离散量输入寄存器的状态。
  • 应用场景:用于读取外部设备的状态,如按钮是否被按下、开关是否处于打开状态等。

3. 输入寄存器(Input Registers)

  • 定义:输入寄存器与保持寄存器类似,但它是只读的。每个输入寄存器占据两个byte的空间,可以存储16位的数据。
  • 访问类型:只读。通过发送功能码04H,可以读取输入寄存器的值。
  • 应用场景:用于读取工业设备的模拟量输入值,如温度、压力、流量等传感器的读数。

4. 保持寄存器(Holding Registers)

  • 定义:保持寄存器是Modbus协议中最重要的数据类型之一,它既可以读取也可以修改。每个保持寄存器同样占据2个byte的空间,可以存储16位的数据。
  • 访问类型:可读可写。通过发送功能码03H、06H或10H,可以读取或修改保持寄存器的值。
  • 应用场景:用于存储和修改设备的设定值、状态值等,如设置温度控制器的目标温度、读取设备的运行时间等。

总结

数据类型定义访问类型功能码应用场景
线圈开关量,每个bit对应一个信号的开关状态可读可写01H, 05H, 0FH控制外部设备的开/关状态
离散量输入类似线圈的只读模式,每个bit表示一个开关量只读02H读取外部设备的状态
输入寄存器类似保持寄存器的只读模式,每个寄存器占两个byte只读04H读取工业设备的模拟量输入值
保持寄存器既可以读取也可以修改,每个寄存器占两个byte可读可写03H, 06H, 10H存储和修改设备的设定值、状态值等

3.功能码

01功能码分析

05功能码分析

0F功能码分析

练习:封装函数实现03,05功能码的作用

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <string.h>
#include <stdlib.h>
void read_registers(uint8_t *p, uint16_t addr, uint16_t num, uint8_t *dest, int sockfd)
{
    p[8] = addr >> 8;
    p[9] = addr;
    p[10] = num >> 8;
    p[11] = num;
    send(sockfd, p, 12, 0);
    int ret = recv(sockfd, dest, 24, 0);
    if (ret < 0)
    {
        perror("recv err");
        close(sockfd);
        return;
    }
    else
    {
        for (int i = 0; i < ret; i++)
            printf("%02x ", dest[i]);
    }
    printf("\n");
}
void write_coil(uint8_t *p, uint16_t addr, int op, uint8_t *dest, int sockfd)
{
    p[8] = addr >> 8;
    p[9] = addr;
    p[11] = 0;
    if (op == 1)
    {
        p[10] = 0xFF;
    }
    else
    {
        p[10] = 0;
    }
    send(sockfd, p, 12, 0);
    int ret = recv(sockfd, dest, 24, 0);
    if (ret < 0)
    {
        perror("recv err");
        close(sockfd);
        return;
    }
    else
    {
        for (int i = 0; i < ret; i++)
            printf("%02x ", dest[i]);
    }
    printf("\n");
}
int main(int argc, char const *argv[])
{
    char buf[128] = {0};
    // 1.创建套接字(socket)------------》有手机
    int sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sockfd < 0)
    {
        perror("socket err");
        return -1;
    }
    printf("sockfd:%d\n", sockfd);
    // 2.指定(服务器)网络信息--------》有对方的号码
    struct sockaddr_in saddr;
    saddr.sin_family = AF_INET;
    saddr.sin_port = htons(502);
    saddr.sin_addr.s_addr = inet_addr(argv[1]);
    // 3.连接(connect)-------------------》拨打电话
    if (connect(sockfd, (struct sockaddr *)&saddr, sizeof(saddr)) < 0)
    {
        perror("connect err");
        return -1;
    }
    printf("connect okk\n");
    uint8_t data_reg[12] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x01, 0x03};
    uint8_t data_reg1[24] = {};
    uint16_t first;
    int num;
    printf("请输入读取保持寄存器起始地址:");
    scanf("%hx", &first);
    printf("请输入要查询的寄存器个数:");
    scanf("%d", &num);
    read_registers(data_reg, first, num, data_reg1, sockfd);
    uint8_t data_coil[12] = {0x00, 0x01, 0x00, 0x00, 0x00, 0x06, 0x01, 0x05};
    uint8_t data_coil1[24] = {};
    printf("请输入写入线圈起始地址:");
    scanf("%hx", &first);
    printf("请选择设置通断状态:");
    scanf("%d", &num);
    write_coil(data_coil, first, num, data_coil1, sockfd);
    close(sockfd);
    return 0;
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【无标题】rocket

rocketMQ集群双主双从同步模式(2m-2s-sync)搭建-CSDN博客 集群架构概念 在部署的时候首先要将nameserver启动起来&#xff0c;之后就是将broker启动起来&#xff0c;broker启动起来会将自己的信息注册到nameserver上面。之后再去创建topic&#xff0c;因为发消息的逻辑和收消…

虹科方案 | 精准零部件测试!多路汽车开关按键功能检测系统

欢迎关注虹科&#xff0c;为您提供最新资讯&#xff01; #LIN/CAN总线 #零部件测试 #CAN数据 导读 在汽车制造业中&#xff0c;零部件的安全性、功能性和可靠性是确保车辆整体性能的关键。虹科针对车辆零部件的LIN/CAN总线仿真测试&#xff0c;提出了基于虹科Baby-LIN系列产…

【教程】鸿蒙ARKTS 打造数据驾驶舱---前序

鸿蒙ARKTS 打造数据驾驶舱 ​ 前面2章我介绍了如何通过定义View绘制箭头以及圆形进度&#xff0c;初步了解了鸿蒙如何进行自定义View。接下来我将通过我最近在带的一个VUE的项目&#xff0c;简单实现了几个鸿蒙原生页面。帮助大家快速上手纯血鸿蒙开发. 本项目基于Api11Stage模…

Qt 弹出菜单右键菜单 QMenu 设置不同颜色的子项

概述 在Qt中&#xff0c;可以使用样式表&#xff08;StyleSheet&#xff09;来自定义 QMenu 的外观&#xff0c;包括其子项&#xff08;如菜单项QAction&#xff09;的颜色。但是&#xff0c;这通常可以设置 QMenu 的整体样式&#xff0c;而不能单独设置某个子项的颜色。不过&…

Cobalt Strike的下载与基本用法

CobaltStrike4.8 链接&#xff1a;百度网盘 请输入提取码 提取码&#xff1a;tgf3 what Cobalt Strike是一款渗透测试神器&#xff0c;常被业界人称为CS神器。Cobalt Strike已经不再使用MSF而是作为单独的平台使用&#xff0c;它分为客户端与服务端&#xff0c;服务端是一个&…

第六部分:1---进程间通信,匿名管道

目录 进程间通信 进程间通信的目的&#xff1a; 进程间通信的本质&#xff1a; 管道&#xff1a; 管道的定义&#xff1a; 匿名管道 单向通信的管道通路&#xff1a; 进程和文件之间的解耦&#xff1a; 单向管道的读写端回收问题&#xff1a; 管道通信主要实现动态数…

Java多线程-(线程的创建,线程安全,线程状态)

第一章.创建线程的方式 1.第一种方式_extends Thread 1.定义一个自定义线程类继承Thread 2.重写run方法(run方法是用于设置线程任务的) 3.创建自定义线程类对象 4.调用Thread类中的start方法(start方法:开启线程,jvm自动执行run方法) public class MyThread extends Thread{…

MacOS安装MAT教程

MAT下载地址MAT下载地址MAT下载地址MAT下载地址 如果不知道你的芯片类型, 可以执行如下命令 uname -m

VMware中安装win7和kail等虚拟机

主要内容 第一部分 安装win 7第二部分 安装kali第三部分 安装UbuntuUbuntu22.04上安装PwntoolsUbuntu上安装vim 第四部分 安装win 10office Word全套安装教程 第一部分 安装win 7 1.打开安装好的虚拟机 参考链接&#xff1a;虚拟机VMware安装windows7 64位操作系统&#x…

(娱乐)魔改浏览器-任务栏图标右上角加提示徽章

一、目标&#xff1a; windows中&#xff0c;打开chromium&#xff0c;任务栏中会出现一个chromium的图标。我们的目标是给这个图标的右上角&#xff0c;加上"有1条新消息"的小提示图标&#xff0c;也叫徽章(badge)注意&#xff1a;本章节纯属娱乐&#xff0c;有需要…

阿里巴巴搜索API返回值:电商市场竞争的新武器含

阿里巴巴搜索API返回值在电商市场竞争中扮演着至关重要的角色&#xff0c;它为企业提供了深入了解市场、分析竞争对手的宝贵资源。以下是对阿里巴巴搜索API返回值及其在电商市场竞争中应用的详细解析&#xff0c;并附上示例代码。 一、阿里巴巴搜索API返回值概述 阿里巴巴搜索…

【案例71】配置https之后 IE打不开登陆页面 Uclient没有问题

问题现象 配置https之后 IE打不开登陆页面 Uclient没有问题。 jvm控制台 显示如下 basic: 已调整小应用程序大小且已将其添加到父容器中 basic: PERF: AppletExecutionRunnable - applet.init() BEGIN ; jvmLaunch dt 170755 us, pluginInit dt 722531 us, TotalTime: 89328…

Spring4-IoC2-基于注解管理bean

目录 开启组件扫描 使用注解定义bean Autowired注入 场景一&#xff1a;属性注入 场景二&#xff1a;set注入 场景三&#xff1a;构造方法注入 场景四&#xff1a;形参注入 场景五&#xff1a;只有一个构造函数&#xff0c;无注解 场景六&#xff1a;Autowired和Quali…

4款AI生成PPT工具推荐,提升工作效率

在如今的工作环境中&#xff0c;PPT制作是许多技术人员不可避免的任务&#xff0c;尤其是在汇报、展示技术方案、以及项目进展时。随着AI技术的快速发展&#xff0c;使用AI生成PPT成为了提高效率的一种新趋势。本文将介绍几款适合程序员、技术人员的AI生成PPT工具&#xff0c;帮…

C++伟大发明--模版

C起初是不受外界关注的&#xff0c;别人觉得他和C语言没有本质上的区别&#xff0c;只是方便些&#xff0c;直到祖师爷发明了模版&#xff0c;开始和C语言有了根本的区别。 我们通过一个小小的例子来搞清楚什么是模版&#xff0c;模版的作用到底有多大&#xff0c;平时我们想要…

【HarmonyOS】鸿蒙头像上传-(编辑个人信息页- 头像上传)+实时数据更新

#效果图 #思路 ##步骤&#xff1a; ###一、利用picker api选择1张图片 实例化选择器参数(使用new PhotoSelectOptions())实例化图片选择器 (使用newPhotoViewPicker() )调用图片选择器的select方法传入选择器参数完成图片选取获得结果 利用picker api选择1张图片 async sele…

【Java】线程的同步——synchronized、ReentrantLock

对同一个线程&#xff0c;能否在获取到锁以后继续获取同一个锁? 答案是肯定可以获取同一个锁。因为JVM 允许同一个线程重复获取同一个锁&#xff0c;这种能被同一个线程反复获取的锁&#xff0c;就叫做可重入锁。 一、synchronized同步锁 在 Java中synchronized 同步锁…

Windows11 WSL2的ubuntu 22.04中拉取镜像报错

问题描述 在windows11 WSL2的ubuntu 22.04中拉取镜像报错。错误为&#xff1a; Error response from daemon: Get "https://registry-1.docker.io/v2/": net/http: request canceled while waiting for connection (Client.Timeout exceeded while awaiting header…

Java音视频文件解析工具

文章目录 一 jave-all-deps二 具体用法2.1 添加依赖2.2 视频转音频2.3 视频格式转换2.4 获取视频时长 三 总结 小伙伴们知道&#xff0c;松哥平时录了蛮多视频课程&#xff0c;视频录完以后&#xff0c;就想整理一个视频文档出来&#xff0c;在整理视频文档的时候&#xff0c;就…

[Python学习日记-25] 哈希(HASH)是个什么东西?

[Python学习日记-25] 哈希&#xff08;HASH&#xff09;是个什么东西&#xff1f; 简介 哈希的特性 哈希的用途 基于 HASH 的数据类型 简介 哈希&#xff08;Hash&#xff09;&#xff0c;也称为散列&#xff0c;或音译为哈希&#xff0c;是把任意长度的输入&#xff08;又…