当前位置: 首页 > news >正文

Modbus RTU与TCP通信示例

准备工作

  1. 安装 libmodbus 库

    • Linux (Debian/Ubuntu):

      sudo apt-get install libmodbus-dev
    • Windows: 下载预编译库 libmodbus for Windows,并配置开发环境。


示例

1.Modbus RTU (串行通信)

#include <stdio.h>
#include <modbus/modbus.h>
​
int main() {
    modbus_t *ctx;
    int rc;
    uint16_t tab_reg[1]; // 存储读取的寄存器值
​
    // 创建RTU上下文
    ctx = modbus_new_rtu("/dev/ttyUSB0", 9600, 'N', 8, 1);
    if (ctx == NULL) {
        fprintf(stderr, "无法创建RTU上下文\n");
        return -1;
    }
​
    // 设置从机地址
    modbus_set_slave(ctx, 1);
​
    // 设置超时时间(毫秒)
    modbus_set_response_timeout(ctx, 1, 0);
​
    // 连接设备
    if (modbus_connect(ctx) == -1) {
        fprintf(stderr, "连接失败: %s\n", modbus_strerror(errno));
        modbus_free(ctx);
        return -1;
    }
​
    // 读取保持寄存器(地址0,读取1个寄存器)
    rc = modbus_read_registers(ctx, 0, 1, tab_reg);
    if (rc == -1) {
        fprintf(stderr, "读取失败: %s\n", modbus_strerror(errno));
    } else {
        printf("寄存器值: %d\n", tab_reg[0]);
    }
​
    // 写入单个寄存器(地址0,值0xFF)
    rc = modbus_write_register(ctx, 0, 0xFF);
    if (rc == -1) {
        fprintf(stderr, "写入失败: %s\n", modbus_strerror(errno));
    }
​
    // 关闭连接
    modbus_close(ctx);
    modbus_free(ctx);
    return 0;
}

2. Modbus TCP (以太网通信)

#include <stdio.h>
#include <modbus/modbus.h>
​
int main() {
    modbus_t *ctx;
    int rc;
    uint16_t tab_reg[2]; // 存储读取的寄存器值
​
    // 创建TCP上下文
    ctx = modbus_new_tcp("192.168.1.100", 502);
    if (ctx == NULL) {
        fprintf(stderr, "无法创建TCP上下文\n");
        return -1;
    }
​
    // 设置从机地址(部分TCP设备需要)
    modbus_set_slave(ctx, 1);
​
    // 连接服务器
    if (modbus_connect(ctx) == -1) {
        fprintf(stderr, "连接失败: %s\n", modbus_strerror(errno));
        modbus_free(ctx);
        return -1;
    }
​
    // 读取输入寄存器(地址0,读取2个寄存器)
    rc = modbus_read_input_registers(ctx, 0, 2, tab_reg);
    if (rc == -1) {
        fprintf(stderr, "读取失败: %s\n", modbus_strerror(errno));
    } else {
        printf("寄存器值: [%d, %d]\n", tab_reg[0], tab_reg[1]);
    }
​
    // 写入多个寄存器(地址10,写入值255和128)
    uint16_t write_data[2] = {255, 128};
    rc = modbus_write_registers(ctx, 10, 2, write_data);
    if (rc == -1) {
        fprintf(stderr, "写入失败: %s\n", modbus_strerror(errno));
    }
​
    // 关闭连接
    modbus_close(ctx);
    modbus_free(ctx);
    return 0;
}

编译与运行

  1. Linux 编译命令

    gcc modbus_rtu_example.c -o rtu_demo -lmodbus
    gcc modbus_tcp_example.c -o tcp_demo -lmodbus
    • 运行前确保串口权限:

      sudo chmod 666 /dev/ttyUSB0
  2. Windows 编译 在 Visual Studio 中配置 libmodbus 的库路径和链接选项。


关键函数说明

功能函数
创建RTU上下文modbus_new_rtu()
创建TCP上下文modbus_new_tcp()
设置从机地址modbus_set_slave()
读取保持寄存器modbus_read_registers()
写入单个寄存器modbus_write_register()
写入多个寄存器modbus_write_registers()
关闭连接modbus_close() / modbus_free()

注意事项

  1. 地址对齐 Modbus 寄存器地址分为四类:

    • 线圈 (0x0000-0xFFFF): modbus_read_bits() / modbus_write_bit()

    • 离散输入 (0x0000-0xFFFF): modbus_read_input_bits()

    • 输入寄存器 (0x0000-0xFFFF): modbus_read_input_registers()

    • 保持寄存器 (0x0000-0xFFFF): modbus_read_registers()

  2. 错误处理 检查所有函数的返回值,使用 modbus_strerror(errno) 获取错误信息。

  3. 调试工具 推荐先用 QModMaster 或 Modbus Poll 验证设备通信参数。

http://www.dtcms.com/a/112606.html

相关文章:

  • Docker 镜像相关的基本操作
  • CCF-CSP认证练习题-第19次-线性分类器
  • 分布式锁算法——基于ZooKeeper的分布式锁全面解析
  • 质检LIMS系统在水产养殖企业的应用 水产养殖企业的现状
  • Jmeter脚本录制
  • 软件工程(应试版)图形工具总结(一)
  • 【为什么基本数据类型不能存储在集合、泛型中?】
  • HTML语言的空值合并
  • 蓝桥杯专项复习——双指针
  • T-SQL语言的自动化运维
  • STM32单片机入门学习——第13节: [6-1] TIM定时中断
  • # 深入解析 C 语言中的 memcpy 与 memmove:内存操作的双雄
  • 深度学习项目--分组卷积与ResNext网络实验探究(pytorch复现)
  • Redis Cluster 在网络分区场景下的处理机制
  • Laravel是否足以支持高并发以及为何需要选择Hyperf或Gin
  • Spring 核心技术解析【纯干货版】- XVI:Spring 网络模块 Spring-WebMvc 模块精讲
  • 了解 PoE 握手协议在网络配电中的重要性
  • 02 反射 泛型(II)
  • 洛谷题单3-P1423 小玉在游泳-python-流程图重构
  • Apache Doris 2.1.9 版本正式发布
  • 微信小程序实验室管理SSM系统设计与实现
  • 统计字符数(信息学奥赛一本通-1187)
  • 【多元线性回归的核心算法:深入解析最小二乘法原理】
  • Perl语言的文件系统
  • 网络协议之基础介绍
  • Leetcode——239. 滑动窗口最大值
  • C语言的操作系统
  • TypeScript 类 vs. ES6 类:深入对比与最佳实践
  • Logo语言的系统监控
  • 【idea设置文件头模板】