Part3 windows10下使用Qt5.6实现modbus主站功能

1.软件信息
1.1 开发工具:
QT版本5.6.2,Qt Creator 版本4.0.3。
Part3 windows10下使用Qt5.6实现modbus主站功能
1.2 类库:
为实现modbus功能,使用现成的libmodbus C库,支持Linux, Mac OS X, FreeBSD, QNX 和 Win32。
下载地址为:http://libmodbus.org/download/。
版本:libmodbus-3.1.4.tar.gz

1.3GNU工具:
MinGW版本5.1.6。
安装教程:https://blog.****.net/AAlonso/article/details/81504404
2.准备工作
2.1 解压libmodbus-3.1.4.tar.gz压缩包的到源码文件夹,
2.2 然后使用mingw自带的msys工具来运行源码文件夹中的configure配置脚本,生成下面需要的config.h头文件。
注:我的msys工具所在路径为:F:\MinGW\msys\1.0\msys.bat,运行这个bat文件会出来一个命令行窗口,在这个命令行窗口中切换到2.1的源码文件夹中使用./configure命令来运行配置脚本生成config.h头文件,如图。
Part3 windows10下使用Qt5.6实现modbus主站功能
Part3 windows10下使用Qt5.6实现modbus主站功能
Part3 windows10下使用Qt5.6实现modbus主站功能
2.3将源码文件夹中src目录下的所有.h和.c文件都拷贝到Qt工程目录(*.pro所在目录)下一个新建的名为libmodbus(可以是任意合法的名字)的文件夹中(使用msys配置前复制也不会出错,但为了统一最好是配置完后再复制),然后将源码文件夹中生成的config.h头文件也复制到libmodbus文件夹下。

2.4在QtCreator工程中“添加现有文件”将modbus文件夹下所有的.h和.c文件都选中添加。
修改libmodbus文件夹下的modbus-private.h、modbus.c、modbus-data.c代码中的”#include <config.h>”为”#include <libmodbus/config.h>”,保存。

2.5该modbus库依赖于windows系统的ws2_32.dll库文件,在C盘中搜索到并复制到Qt工程根目录(.pro文件所在目录)下名为dll(可以是任何合法的名字)的文件夹中。
.pro文件中加上”LIBS += -Ldll -lws2_32”,这样编译时就可以找到该链接库了。

2.6建立测试代码,我的测试代码是分别使用RTU和TCP实现对modbus从机的查询,相关代码和运行效果在下面给出。
mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QVBoxLayout>
#include <QMessageBox>
#include "libmodbus/modbus.h"

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::on_btn_RTU_clicked()
{

    modbus_t *mb;
    uint16_t tab_reg[32]={0};

    mb = modbus_new_rtu("COM2", 9600, 'N', 8, 1);   //相同的端口只能同时打开一个
    modbus_set_slave(mb, 1);  //设置modbus从机地址

    modbus_connect(mb);

    struct timeval t;
    t.tv_sec=0;
    t.tv_usec=1000000;   //设置modbus超时时间为1000毫秒
    modbus_set_response_timeout(mb, t.tv_sec,t.tv_usec);

    int regs=modbus_read_registers(mb, 0, 20, tab_reg);

    QMessageBox::about(NULL, "报告", QString("Rtu读取寄存器的个数:%1").arg(regs));
    modbus_close(mb);

}

void MainWindow::on_btn_TCP_clicked()
{
    modbus_t *mb;
        uint16_t tab_reg[32]={0};

        mb = modbus_new_tcp("10.168.1.112", 502);  //由于是tcp client连接,在同一个程序中相同的端口可以连接多次。
        modbus_set_slave(mb, 1);  //从机地址

        modbus_connect(mb);

        struct timeval t;
        t.tv_sec=0;
        t.tv_usec=1000000;   //设置modbus超时时间为1000毫秒,注意:经测试,如果没有成功建立tcp连接,则该设置无效。
        modbus_set_response_timeout(mb, t.tv_sec,t.tv_usec);

        int regs=modbus_read_registers(mb, 0, 20, tab_reg);

        QMessageBox::about(NULL, "报告", QString("Tcp读取寄存器的个数:%1").arg(regs));
        //ui->lb1->text();
        modbus_close(mb);
        modbus_free(mb);

}