网络高级day01(Modbus 通信协议:Modbus TCP)

news2024/9/21 8:21:35

目录

1》modbus分类

1> Modbus RTU

2> Modbus ASCLL

3> Modbus TCP

 2》Modbus TCP的特点

 3》Modbus TCP协议

 1> 报文头(一共7个字节)

 2> 寄存器

3> 功能码

 4> 数据

 01H  功能码分析

 05H 功能码分析

0FH 功能码分析


1》modbus分类

1> Modbus RTU

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

2> Modbus ASCLL

 运行在串口上的协议,采用ASCLL码进行传输,并且每个字节的开始和结束都有特殊字符作为标志,传输效率远远低于Modbus RTU,一般只有通讯量比较少的时候才会考虑它。注:在ASCII模式下,每个8位的字节被拆分成两个ASCII字符进行发送,比如十六进制0xAF(1010 1111),会被分解成ASCII字符“A”(0100 0001)和”F”(0100 0110)进行发送,其发送量显然比RTU增加一倍。

3> Modbus TCP

 运行在以太网上的协议

 2》Modbus TCP的特点

1> 主从应答式通信

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

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

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

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

3> Modbus TCP 端口号默认为502

 3》Modbus TCP协议

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

MBAP:Modbus Application Protocol (modbus报文头)

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

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

 1> 报文头(一共7个字节)

 2> 寄存器

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

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

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

线圈寄存器,类比为开关量。 线圈寄存器支持读也支持写,写在功能码里面又分为写单个线圈寄存器和写多个线圈寄存器。

读单个或多个 写单个 写多个 3个功能码实现

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

对应功能码1个 读单个或多个

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

保持寄存器,这个寄存器的单位不再是bit而是两个byte,也就是可以存放具体的数据量的,并且是可读写的。比如空调检测到的室温,这是不可以修改的,因为室温是根据实际的物理环境决定的。

功能码有对应的三个

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

对应的功能码也就一个

3> 功能码

 4> 数据

 01H  功能码分析

读数据:

主机-》从机

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

从机-》主机

报文头---功能码---字节计数---数据

 05H 功能码分析

写单个:

主机--》从机

报文头---功能码---地址---通断标志/数据

从机--》主机

原文返回

0FH 功能码分析

写多个:

主机-->从机

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

从机--->主机

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

练习

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

#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <arpa/inet.h>
#include <string.h>
#include <unistd.h>
void set_slaveid(uint8_t *p, uint8_t id);
int sockfd;
void read_registers(uint8_t *p, uint16_t addr, uint16_t num, uint8_t *dest);
void write_coil(uint8_t *p, uint16_t addr, int op, uint8_t *dest);
int main(int argc, char const *argv[])
{

    if (argc != 2)
    {
        printf("usage:<ip>\n");
        return -1;
    }
    // 1.创建套接字
    sockfd = socket(AF_INET, SOCK_STREAM, 0);
    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]);
    socklen_t addrlen = sizeof(saddr);
    // 3.连接
    if (connect(sockfd, (struct sockaddr *)&saddr, addrlen) < 0)
    {
        perror("connect err");
        return -1;
    }
    // 创建数组
    uint8_t req[32] = {0};
    uint8_t date[128] = {0};
    set_slaveid(req, 0x01);
    read_registers(req, 0x0000, 0x0002, date);//03
    for (int i = 0; i < date[8]; i++)
    {
        printf("%02x ", date[9 + i]);
    }
    putchar(10);
    write_coil(req,0x0000,1,date);//05
    printf("seq:%02x\n",date[1]);
    return 0;
}

void set_slaveid(uint8_t *p, uint8_t id)
{
    p[6] = id;
}
void read_registers(uint8_t *p, uint16_t addr, uint16_t num, uint8_t *dest)
{
    p[5] = 0x06;
    p[7] = 0x03;
    p[9] = addr;
    p[8] = addr >> 8;
    p[11] = num;
    p[10] = num >> 8;
    send(sockfd, p, 12, 0);
    recv(sockfd, dest, 128, 0);
}
void write_coil(uint8_t *p, uint16_t addr, int op, uint8_t *dest)
{   
    p[1]=0x01;
    p[5] = 0x06;
    p[7] = 0x05;
    p[9] = addr;
    p[8] = addr >> 8;
    if (op == 1)
    {
        p[10] = 0xFF;
    }
    else
    {
        p[10] = 0x00;
    }
    p[11] = 0x00;
    send(sockfd, p, 12, 0);
    recv(sockfd, dest, 128, 0);
}

今天的分享就到这里结束啦,如果有哪里写的不好的地方,请指正。
如果觉得不错并且对你有帮助的话点个关注支持一下吧!

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

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

相关文章

Springboot常见问题(bean找不到)

如图错误显示userMapper bean没有找到。 解决方案&#xff1a; mapper包位置有问题&#xff1a;因为SpringBoot默认的包扫描机制会扫描启动类所在的包同级文件和子包下的文件。注解问题&#xff1a; 比如没有加mapper注解 然而无论是UserMapper所在的包位置还是Mapper注解都是…

虚拟机ens33网卡不显示inet地址(已设置NOBOOT为yes)

在虚拟机中输入ifconfig或ip addr时&#xff0c;出现如下情况&#xff1a; sudo dhclient ens33sudo ifconfig ens33依次执行上面两行&#xff0c;之后发现ens33中可以显示inet了 本虚拟机的地址就是192.168.244.131

Unity屏幕震动效果

基于Cinemachine 1、为Cinemachine设置拓展 2、选择ImpulseListener 3、为摄像机跟随的角色添加脚本 4、设置Impulse 5、选择类型 6、设置内置6DShake并调节振幅 7、运行时invoke即可

STM32F1+HAL库+FreeTOTS学习11——延时函数API

STM32F1HAL库FreeTOTS学习11——延时函数API 延时函数API1. vTaskDelay()2. vTaskDelayUntil()3. xTaskDelayUntil()相对延时和绝对延时的区别4. xTaskAbortDelay() 上一期&#xff0c;我们学习了任务相关API使用&#xff0c;这一期我们开始学习FreeRTOS延时函数的API使用 延时…

Python使用YOLOv5图像识别教程包成功-以识别桥墩缺陷详细步骤分享

前置环境资源下载 提示&#xff1a;要开外网才能下载的环境我都放在了网盘里&#xff0c;教程中用到的环境可从这里一并下载&#xff1a; https://pan.quark.cn/s/f0c36aa1ef60 1. 下载YOLOv5源码 官方地址&#xff1a;GitHub - ultralytics/yolov5: YOLOv5 &#x1f680; …

【源码+文档+调试讲解】微信小程序的投票系统

摘 要 伴随着我国社会的发展&#xff0c;人民生活质量日益提高。于是对各种需求进行规范而严格是十分有必要的&#xff0c;所以许许多多的微信小程序应运而生。此时单靠人力应对这些事务就显得有些力不从心了。所以本论文将设计一套微信小程序的投票系统&#xff0c;进行作品信…

python画图|曲线分段设置颜色基础教程

前期已经学习了大量的python画图教程&#xff0c;但颜色的设计一直是次要角色&#xff0c;今天我们就一起学习一下如何对图形分段设置颜色。 一些前期通过颜色区分图形的文章链接如下&#xff1a; python画图|极坐标下的3D surface_python 根据经纬度 海拔高度 绘制三维立体-…

AIDI工业AI视觉检测软件

AIDI工业AI视觉检测软件 AIDI2.4&#xff0c;工业AI视觉检测软件&#xff0c;全模块永久使用最高权限&#xff0c;支持8卡同时运算&#xff0c;提供远程测试

对接阿里asr和Azure asr

1&#xff1a;对接阿里asr 1.1&#xff1a;pom <dependency><groupId>com.alibaba.nls</groupId><artifactId>nls-sdk-recognizer</artifactId><version>2.2.1</version> </dependency>1.2&#xff1a;生成token package c…

同态加密明文矩阵乘密文向量优化:BSGS小步大步法

摘要 本文介绍如何使用小步大步&#xff08;Baby-Step-Giant-Step&#xff0c;BSGS&#xff09;优化RLWE同态加密的明文矩阵和密文向量的乘法。使用 n n n\times n nn明文矩阵的对角打包和BSGS&#xff0c;可以将密文旋转的次数降低为 O ( n ) O(\sqrt{n}) O(n ​). 明文运算…

3、无线通信系统的组成

通常把实现信息传输的系统称为通信系统&#xff0c;下图表示一个通信系统的基本组成。在通信系统中&#xff0c;一般要进行两种变换与反变换。在发送端&#xff0c;第一个变换是输入变换器&#xff0c;它把要传输的信号变为电信号&#xff0c;该信号一般是低频的&#xff0c;而…

数字英文验证码识别 API 对接说明

数字英文验证码识别 API 对接说明 本文将介绍一种 数字英文验证码识别 API 对接说明&#xff0c;它是基于深度学习技术&#xff0c;可用于识别变长英文数字验证码。输入验证码图像的内容&#xff0c;输出验证码结果。 接下来介绍下 数字英文验证码识别 API 的对接说明。 注册…

【d45】【Java】【力扣】206.反转链表

思路 解法1&#xff1a;适用于数字不多的 1.把节点的数&#xff0c;都放进一个arraylist中 2.调用Collections.reverse(list)方法&#xff0c;将list转置 3.再遍历list&#xff0c;逐个放入数字 代码 解法1 import java.util.ArrayList; import java.util.Collections;p…

window批处理脚本:将本地的三个文件通过SCP传输到Linux设备上

文件名send_file.bat&#xff1a; echo off setlocal:: 提示用户输入远程IP地址 set /p remoteIpAddressplease input IP::: 定义本地文件名 set "localFile1111" set "localFile2222" set "localFile3333":: 获取本地文件的完整路径 set "…

【AI视频】Runway:Gen-2 图文生视频与运动模式详解

博客主页&#xff1a; [小ᶻZ࿆] 本文专栏: AI视频 | Runway 文章目录 &#x1f4af;前言&#x1f4af;仅图片生成视频方法一&#xff1a;通过Midjourney生成图片方法二&#xff1a;通过Runway预览生成图片注意点 &#x1f4af;图加文生成视频方式一&#xff1a;Midjourney…

百度飞浆Paddle OCR检测和识别【OCR数据收集、标注、数据集划分、检测识别模型训练、导出模型】

文章目录 前言一、OCR数据集采集二、OCR数据标注三、划分数据集四、数据训练五、导出模型 前言 1、我的电脑没有GPU&#xff0c;如果不使用AI Studio训练的话&#xff0c;第一遍我是按照CPU进行环境配置和训练的&#xff0c;可以参考这篇文章&#xff0c;我按着弄了一遍&#…

安克创新25届校招CATA北森测评:笔试攻略、真题题库、高分技巧

安克创新自适应能力CATA测评是该公司用于评估候选人认知能力的计算机自适应测评系统。该测评系统由北森题库提供支持&#xff0c;是国内唯一被国际计算机自适应测验协会(IACAT)收录的产品。测评主要评估以下几个维度&#xff1a; 言语能力&#xff1a;测试理解言语信息并基于这…

25届计算机专业毕设选题推荐-基于python+Django协调过滤的新闻推荐系统

&#x1f496;&#x1f525;作者主页&#xff1a;毕设木哥 精彩专栏推荐订阅&#xff1a;在 下方专栏&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb; 实战项目 文章目录 实战项目 一、基于协调过滤的新闻推荐系统…

浅谈穷举法

穷举法 穷举法是一种通过逐一列举所有可能情况来寻找解决方案的方法。就像找到一把钥匙打开一把锁&#xff0c;我们会尝试每一把钥匙直到找到正确的那一把。比如&#xff0c;如果你忘记了自己的密码&#xff0c;可以尝试每一种可能的组合直到找到正确的密码为止 穷举法的结构 …