Qt中使用ModbusTCP连接功能

在之前我还是小白的时候,我如果用这些外部库都是要从github上下载后,然后再vs中编译出对应的.dll和.lib文件,然后在vs设置环境中库库的设置,然后才能用
后来我接触了CMake和vcpkg,了解到可以用vcpkg进行全部的库的设置,非常方便
而今天这个方法是从github上直接下载下来libmodbus这个库,然后设置一个CMakeLists.txt文件,然后在整体项目编译的时候,先运行这个modbus的CMakeLists文件
然后就有.lib和.dll了,然后就可以直接在项目里面用,说实话就是把整个下载下来的文件夹都丢进去项目中即可
1、确保下载好这个libmodbus文件夹
image
然后那个CMake代码是这样的

点击查看代码
cmake_minimum_required(VERSION 3.10)

project(modbus LANGUAGES C)

# 将所有源码文件列出来
set(MODBUS_SOURCES
    modbus.c
    modbus-rtu.c
    modbus-tcp.c
    modbus-data.c
)

# 创建库目标
add_library(modbus SHARED ${MODBUS_SOURCES})

target_include_directories(modbus PUBLIC
    ${CMAKE_CURRENT_SOURCE_DIR}   # 让外部 target_link_libraries 时能找到 modbus.h
)

if(UNIX)
    target_link_libraries(modbus PRIVATE m pthread)
elseif(WIN32)
    target_compile_definitions(modbus PRIVATE _CRT_SECURE_NO_WARNINGS)
    target_link_libraries(modbus PRIVATE ws2_32)
endif()

2、然后在项目中把这个文件夹导入,顺便修改一下本项目的CMake 这是本项目的CMake代码
点击查看代码
cmake_minimum_required(VERSION 3.19)
project(TestModbusTcp LANGUAGES C CXX)##确保C语言的modbus可以被编译
find_package(Qt6 6.5 REQUIRED COMPONENTS Core Widgets Concurrent)

qt_standard_project_setup()
##进入libmodbus文件夹后执行Cmake操作
add_subdirectory(3rdparty/libmodbus)

qt_add_executable(TestModbusTcp
    WIN32 MACOSX_BUNDLE
    main.cpp
    mainwindow.cpp
    mainwindow.h
    mainwindow.ui
)

target_link_libraries(TestModbusTcp
    PRIVATE
        Qt::Core
        Qt::Widgets
        modbus
)

include(GNUInstallDirs)

install(TARGETS TestModbusTcp
    BUNDLE  DESTINATION .
    RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
    LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
)

qt_generate_deploy_app_script(
    TARGET TestModbusTcp
    OUTPUT_SCRIPT deploy_script
    NO_UNSUPPORTED_PLATFORM_ERROR
)
install(SCRIPT ${deploy_script})
整体的文件结构就是这样的

image
3、然后执行CMake就可以,有问题再按照bug修改
之后就是代码部分了,TCP连接需要下位机的ip和端口,我这里用的自己电脑模拟的,所以是127.0.0.1和502
寄存器位置你自己看着设置,我是0~9
这是核心代码

点击查看代码
ui->setupUi(this);
    modbus_t *ctx = modbus_new_tcp("127.0.0.1", 502);
    if (!ctx)
    {
        ui->label->setText("创建modbus上下文失败");
        qDebug() << "modbus_new_tcp error:" << modbus_strerror(errno);
        return;
    }
    modbus_set_slave(ctx, 1);//设置从站
    modbus_set_response_timeout(ctx, 0, 500000);//设置相应超时
    if (modbus_connect(ctx) == -1)
    {
        QString err = "TCP连接失败:" + QString(modbus_strerror(errno));
        ui->label->setText(err);
        qDebug() << err;
        modbus_free(ctx); // 连接失败也要释放!
        return;
    }

    uint16_t tab_reg[10];
    int readRet = modbus_read_registers(ctx, 0, 10, tab_reg);
    if (readRet == -1)
    {
        QString err = "读取寄存器失败:" + QString(modbus_strerror(errno));
        ui->label->setText(err);
        qDebug() << err;
        // 收尾释放资源
        modbus_close(ctx);
        modbus_free(ctx);
        return;
    }
    modbus_close(ctx);
    modbus_free(ctx);
    QString temp="";
    for (int i = 0; i < 10; i++)
    {
        temp += QString("地址%1:%2  ").arg(i).arg(tab_reg[i]);
    }
    ui->label->setText(temp);
这是寄存器的设置

image
记得别忘了从站连接
image
最后运行结果是这样的
image

posted on 2026-07-01 17:28  dd_l  阅读(4)  评论(0)    收藏  举报