Linux网络高级——Modbus TCP及Modbus库

Modbus是一种用于PLC通信的工业标准协议,支持ASCII、RTU、TCP三种报文类型。它定义了主站和从站的通信方式,主站发起请求,从站响应。ModbusTCP协议在物理层可使用多种接口,如RS232、RS485和以太网。文章列举了不同功能代码(如读线圈、写单个线圈、读保持寄存器等)的请求和响应格式,并提供了Linux下使用Modbus库的示例代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  • Modbus是一种串行通信协议,是Modicon公司(现在的施耐德电气 Schneider Electric)于1979年为使用可编程逻辑控制器(PLC)通信而发表。Modbus已经成为工业领域通信协议的业界标准(De facto),并且现在是工业电子设备之间常用的连接方式。

  • Modbus协议是一项应用层报文传输协议,包括ASCII、RTU、TCP三种报文类型。

  • 标准的Modbus协议物理层接口有RS232、RS422、RS485和以太网接口,采用master/slave方式通信。

  1. Modbus TCP协议格式

ModbusTCP的数据帧可分为两部分:MBAP+PDU

1)报文头MBAP

2)功能代码

3)PDU详细结构

0x01:读线圈

在从站中读1~2000个连续线圈状态,ON=1,OFF=0

请求:MBAP 功能码 起始地址H 起始地址L 数量H 数量L(共12字节)

响应:MBAP 功能码 数据长度 数据(一个地址的数据为1位)

0x05:写单个线圈

将从站中的一个输出写成ON或OFF,0xFF00请求输出为ON,0x000请求输出为OFF

请求:MBAP 功能码 输出地址H 输出地址L 输出值H 输出值L(共12字节)

响应:MBAP 功能码 输出地址H 输出地址L 输出值H 输出值L(共12字节)

0x0F:写多个线圈

将一个从站中的一个线圈序列的每个线圈都强制为ON或OFF,数据域中置1的位请求相应输出位ON,置0的位请求响应输出为OFF

请求:MBAP 功能码 起始地址H 起始地址L 输出数量H 输出数量L 字节长度 输出值H 输出值L

响应:MBAP 功能码 起始地址H 起始地址L 输出数量H 输出数量L

0x02:读离散量输入

从一个从站中读1~2000个连续的离散量输入状态

请求:MBAP 功能码 起始地址H 起始地址L 数量H 数量L(共12字节)

响应:MBAP 功能码 数据长度 数据(长度:9+ceil(数量/8))

0x04:读输入寄存器

从一个远程设备中读1~2000个连续输入寄存器

请求:MBAP 功能码 起始地址H 起始地址L 寄存器数量H 寄存器数量L(共12字节)

响应:MBAP 功能码 数据长度 寄存器数据(长度:9+寄存器数量×2)

0x03:读保持寄存器

从远程设备中读保持寄存器连续块的内容

请求:MBAP 功能码 起始地址H 起始地址L 寄存器数量H 寄存器数量L(共12字节)

响应:MBAP 功能码 数据长度 寄存器数据(长度:9+寄存器数量×2)

0x06:写单个保持寄存器

在一个远程设备中写一个保持寄存器

请求:MBAP 功能码 寄存器地址H 寄存器地址L 寄存器值H 寄存器值L(共12字节)

响应:MBAP 功能码 寄存器地址H 寄存器地址L 寄存器值H 寄存器值L(共12字节)

0x10:写多个保持寄存器

在一个远程设备中写连续寄存器块(1~123个寄存器)

请求:MBAP 功能码 起始地址H 起始地址L 寄存器数量H 寄存器数量L 字节长度 寄存器值(13+寄存器数量×2)

响应:MBAP 功能码 起始地址H 起始地址L 寄存器数量H 寄存器数量L(共12字节)

  1. Modbus TCP协议通信

1)通信方式

Modbus设备可分为主站(poll)和从站(slave)。主站只有一个,从站有多个,主站向各从站发送请求帧,从站给予响应。在使用TCP通信时,主站为client端,主动建立连接;从站为server端,等待连接。

  • 主站请求:功能码+数据

  • 从站正常响应:请求功能码+响应数据

  • 从站异常响应:异常功能码+异常码,其中异常功能码即将请求功能码的最高有效位置1,异常码指示差错类型

2)通信过程

  • connect 建立TCP连接

  • 准备Modbus报文

  • 使用send命令发送报文

  • 在同一连接下等待应答

  • 使用recv命令读取报文,完成一次数据交换

  • 通信任务结束时,关闭TCP连接

  1. Modbus 库

Linux下Modbus库的使用

#include <stdio.h>
#include <modbus-tcp.h>
#include <modbus.h>
#include <stdlib.h>
#include<unistd.h>
int main(int argc, char const *argv[])
{
    modbus_t *ctx;
    uint16_t data[64] = {0};
    //1.创建modbus实例
    ctx = modbus_new_tcp(argv[1], atoi(argv[2]));
    if (ctx == NULL)
    {
        perror("modbus new tcp err");
        return -1;
    }
    //2.设置从机id
    modbus_set_slave(ctx, 1);
    //3.和从机建立联系
    modbus_connect(ctx);
    //4.03 读取寄存器
    while (1)
    {
        modbus_read_registers(ctx, 0, 1, data);
        printf("%d \n", data[0]);
        sleep(2);
    }
    //5.关闭套接字
    modbus_close(ctx);
    //6.释放实例
    modbus_free(ctx);
    return 0;
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值