Modbus通信介绍 网络高级工具使用

目录

Modbus简介

ModbusTCP协议格式

》1.报文头(共7字节)

》2.功能码

》3.数据

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

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

模拟器使用

windows的地址获取

1. 按下ctrl+r

2. 输入cmd运行

3. 输入ipconfig获取ip

4. 查看ip

ModbusSlave(从机)界面介绍

ModbusPoll(主机)界面介绍

salve和poll使用例

网络调试助手界面介绍

网路助手的测试

Wireshark的基础使用教程

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

2. 编写客户端程序实现对Slave单个线圈的控制


Modbus简介

Modbus通信协议具有多个变种,其中有支持串口,以太网多个版本,其中最著名的是

Modbus RTU的特点:

  1. 运行在串口上的协议
  2. 采用二进制表示形式
  3. 紧凑的数据结构
  4. 通信效率高,应用广

Modbus ASCII的特点:

  1. 运行在串口上的协议
  2. 采用ASCII码传输
  3. 利用特殊字符作为字节开始和结束标志
  4. 传输数据低,只用传输数据量少的时候才考虑使用

Modebus TCP的特点:

运行在以太网上的协议

  1. 采用主从问答方式进行通信
  2. Modbus Tcp是应用层协议,基于传输层Tcp协议实现
  3. Modbus Tcp端口号默认是502

ModbusTCP协议格式

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

》1.报文头(共7字节)

组成事务处理符:2字节

可以理解为报文的序列号,一般每次通信之后就要加1以区别不同的通信数据报文

协议标识符:2字节

00 00表示Modbus TCP协议(一般不改变)

长度:2字节

表示接下来的字节长度,单位字节

单元标识符:1字节

串行链路或其他,总线上连接的远程从站地址

》2.功能码

先了解寄存器

包含四种寄存器

  1. 线圈
    1. 位寄存器(每个寄存器数据占1字节)
    2. 主要用于控制IO设备
    3. 线圈寄存器,类比为开关量
    4. 一个byte就可以同时控制8路的信号
    5. 可读可写,写分为写单个写多个
    6. 共三种状态:读,写单个,写多个
  1. 离散量输入
    1. 位寄存器(每个寄存器数据占1字节)
    2. 主要用于控制IO设备
    3. 线圈寄存器的只读模式
    4. 只有一种状态:只能读
  1. 保持寄存器
    1. 字寄存器(每个寄存器数据占2个字节)
    2. 存储工业设备的值
    3. 可读可写,写分为写单个写多个
    4. 共三种状态:读,写单个,写多个
  1. 输入寄存器
    1. 字寄存器(每个寄存器数据占2个字节)
    2. 存储工业设备的值
    3. 只有一种状态:只能读

功能码详表:

Modbus通信介绍 网络高级工具使用_第1张图片

》3.数据

数据格式可以看下面分享

实例分享 | ModbusTCP报文详解

字寄存器:

Modbus通信介绍 网络高级工具使用_第2张图片

位寄存器:

Modbus通信介绍 网络高级工具使用_第3张图片

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

从机给主机回复:0x0000 0000 0005 01 03 02 0012

解析:

0x0000事务处理标识符

0000 协议类型

0006 字节长度

01 从机ID(单元标识符)

03 功能码

02 字节计数

0012 数据长度

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

主机给从机:

0x0000 0x0000 0x0006 0x01 0x05 0x000b 0xFF00

从机给主机:

0x0000 0x0000 0x0006 0x01 0x05 0x000b 0xFF00

模拟器使用

windows的地址获取

1. 按下ctrl+r

    1. Modbus通信介绍 网络高级工具使用_第4张图片

2. 输入cmd运行

    1. Modbus通信介绍 网络高级工具使用_第5张图片

3. 输入ipconfig获取ip

    1. Modbus通信介绍 网络高级工具使用_第6张图片

4. 查看ip

    1. Modbus通信介绍 网络高级工具使用_第7张图片

ModbusSlave(从机)界面介绍

模拟的是实际的控制设备,相当于服务器端,用于响应主机的请求。

Modbus通信介绍 网络高级工具使用_第8张图片

Modbus通信介绍 网络高级工具使用_第9张图片

Modbus通信介绍 网络高级工具使用_第10张图片

ModbusPoll(主机)界面介绍

模拟的是主机,相当于客户端

Modbus通信介绍 网络高级工具使用_第11张图片

Modbus通信介绍 网络高级工具使用_第12张图片

Modbus通信介绍 网络高级工具使用_第13张图片

Modbus通信介绍 网络高级工具使用_第14张图片

salve和poll使用例

网络调试助手界面介绍

Modbus通信介绍 网络高级工具使用_第15张图片

网路助手的测试

》1.协议分析

网络助手需要用到下面的协议

00 00 00 00 00 06 01 06 00 01 00 01

Modbus通信介绍 网络高级工具使用_第16张图片

这串协议的意思是向主机号为01的0001地址写入0001值

我们可以使用网络助手进行验证

》2.slave(从机相当于服务器)设置

Modbus通信介绍 网络高级工具使用_第17张图片

》3.网络调试助手设置

Modbus通信介绍 网络高级工具使用_第18张图片

》4.开始通信测试

Modbus通信介绍 网络高级工具使用_第19张图片

Wireshark的基础使用教程

Modbus通信介绍 网络高级工具使用_第20张图片

Modbus通信介绍 网络高级工具使用_第21张图片

先将双方建立通信

Modbus通信介绍 网络高级工具使用_第22张图片

Modbus通信介绍 网络高级工具使用_第23张图片

输入ip.addr == 192.168.8.140后,按下enter键

然后用网络调试助手给slave发送数据,wireshark就抓到数据了

Modbus通信介绍 网络高级工具使用_第24张图片

对抓到的数据进行基础分析

注:wireshark在嵌入式领域中并不常用,上面操作只是单纯为了抓包而抓包

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

//练习1
#include 
#include 
#include 
#include 
#include 
 #include 
#define MY_PORT 502
#define MY_ADDRESS "192.168.8.140" //根据自己情况输入


enum num{
    Length =0x06,//长度
    Unitid =0x01,//单元标识
    Fucode =0x03,//功能码
    Flowad =0x00,//起始寄存器高位
    Fhigad =0x00,//起始寄存器低位
    NUMlow =0x00,//数量高位
    NUMhig =0x01//数量低位
};

int main(int argc, char const *argv[])
{
     uint8_t buf[12]={0x00};
    //1.创建套接子
    int sockid;
    sockid = socket(AF_INET, SOCK_STREAM, 0);
    if (sockid < 0)
    {
        perror("socket err.");
        return -1;
    }
    //2.填充结构提
    struct sockaddr_in caddr;
    memset(&caddr,0,sizeof(caddr));
    caddr.sin_family = AF_INET;
    caddr.sin_port = ntohs(MY_PORT);
    caddr.sin_addr.s_addr = inet_addr(MY_ADDRESS);

    //3.connect链接服务器
    int conid = connect(sockid, (struct sockaddr *)&caddr, sizeof(caddr));
    if (conid < 0)
    {
        perror("connect err");
        return -1;
    }
    //4.发送消息
    buf[5]=Length;//长度
    buf[6]=Unitid;//单元标识
    buf[7]=Fucode;//功能码
    buf[8]=Flowad;//起始寄存器高位
    buf[9]=Fhigad;//起始寄存器低位
    buf[10]=NUMlow;//数量高位
    buf[11]=NUMhig;//数量低位

    int sendid = send(sockid, buf, sizeof(buf), 0);
    if (sendid < 0)
    {
        perror("send err.");
        return -1;
    }
    int recid = recv(sockid, buf, sizeof(buf), 0);
    if (recid < 0)
    {
        perror("recv err.");
        return -1;
    }
    for (int i = 0; i < sizeof(buf)-1; i++)
    {
        printf("%02x  ", buf[i]);
    }
    close(sockid);
    return 0;
}

开启slave端链接

Modbus通信介绍 网络高级工具使用_第25张图片

读到值为0x14,对用十进制是20

2. 编写客户端程序实现对Slave单个线圈的控制

//练习2
#include 
#include 
#include 
#include 
#include 
 #include 

#define MY_PORT 502
#define MY_ADDRESS "192.168.8.140"

struct Coil{ 
    uint8_t  Length;//长度
    uint8_t  Unitid;//单元标识
    uint8_t  Fucode;//功能码
    uint8_t  CoilHeight;//线圈地址(高位)
    uint8_t  CoilLow;//线圈地址(低位)
    uint8_t  DisMkHeight;//断通标志
    uint8_t  DisMkLow;//断通标志
};

struct Coil num={0x06,0x01,0x05,0x00,0x00,0xff,0x00};

int main(){

    uint8_t	buf[12]={0x00};

    int sockfd=socket(AF_INET,SOCK_STREAM,0);
    if (sockfd<0)
    {
        perror("socket err.");
        return -1;
    }

    struct sockaddr_in caddr;
    memset(&caddr,0,sizeof(caddr));
    caddr.sin_family=AF_INET;
    caddr.sin_port=ntohs(MY_PORT);
    caddr.sin_addr.s_addr=inet_addr(MY_ADDRESS);

    int conid=connect(sockfd,(struct sockaddr*)&caddr,sizeof(caddr));
    if (conid<0)
    {
        perror("connect err.");
        return -1;
    }

     //4.发送消息
    buf[5]=num.Length;//长度
    buf[6]=num.Unitid;//单元标识
    buf[7]=num.Fucode;//功能码
    buf[8]=num.CoilHeight;//线圈地址(高位)
    buf[9]=num.CoilLow;//线圈地址(低位)
    buf[10]=num.DisMkHeight;//断通标志
    buf[11]=num.DisMkLow;//断通标志

    int sendid = send(sockfd, buf, sizeof(buf), 0);
    if (sendid < 0)
    {
        perror("send err.");
        return -1;
    }
    int recid = recv(sockfd, buf, sizeof(buf), 0);
    if (recid < 0)
    {
        perror("recv err.");
        return -1;
    }
    for (int i = 0; i < sizeof(buf); i++)
    {
        printf("%02x  ", buf[i]);
    }
    printf("\n");
    close(sockfd);
    return 0;
    
}

Modbus通信介绍 网络高级工具使用_第26张图片

Modbus通信介绍 网络高级工具使用_第27张图片

你可能感兴趣的:(网络编程,网络,tcp/ip)