qt modbus

有时为了调试,需要在程序中实现modbus主机的功能,网上有一个现成的libmodbus C库,支持Linux, Mac OS X, FreeBSD, QNX 和 Win32。

下载地址为:http://libmodbus.org/download/

本文档主要说明这个库在Qt中使用的方法。

我下载的是libmodbus-3.0.6.tar.gz, 使用的Qt版本为Qt 5.3.2,  QtCreator版本为QtCreator 3.2.1。

解压压缩包的到源码文件夹,然后使用mingw自带的msys工具来运行源码文件夹中的configure配置脚本,生成下面需要的config.h头文件。

注:我的msys工具所在路径为:D:\MingW\msys\1.0\msys.bat,运行这个bat文件会出来一个命令行窗口,在这个命令行窗口中切换到源码文件夹中使用./configure命令来运行配置脚本生成config.h头文件,如图。


将源码文件夹中src目录下的所有.h和.c文件都拷贝到Qt工程目录(*.pro所在目录)下一个新建的名为libmodbus(可以是任意合法的名字)的文件夹中(使用msys配置前复制也不会出错,但为了统一最好是配置完后再复制),然后将源码文件夹中生成的config.h头文件也复制到libmodbus文件夹下。
在QtCreator工程中“添加现有文件”将modbus文件夹下所有的.h和.c文件都选中添加。
修改libmodbus文件夹下的modbus-private.h和modbus.c代码中的”#include <config.h>”为”#include <libmodbus/config.h>”,保存。
该modbus库依赖于windows系统的ws2_32.dll库文件,在C盘中搜索到并复制到Qt工程根目录(*.pro文件所在目录)下名为dll(可以是任何合法的名字)的文件夹中。在*.pro文件中加上”LIBS += -Ldll -lws2_32”,这样编译时就可以找到该链接库了。
建立测试代码,我的测试代码是分别使用RTU和TCP实现对modbus从机的查询,相关代码和运行效果在下面给出。

Qt工程文件树:


下面是一些源码:

LibModbusTest2.pro

[plain]  view plain  copy
  1. #-------------------------------------------------  
  2. #  
  3. # Project created by QtCreator 2015-04-03T11:38:46  
  4. #  
  5. #-------------------------------------------------  
  6.   
  7. QT       += core gui  
  8.   
  9. greaterThan(QT_MAJOR_VERSION, 4): QT += widgets  
  10.   
  11. TARGET = LibModbusTest2  
  12. TEMPLATE = app  
  13.   
  14.   
  15. SOURCES += main.cpp\  
  16.         mainwindow.cpp \  
  17.     libmodbus/modbus.c \  
  18.     libmodbus/modbus-data.c \  
  19.     libmodbus/modbus-rtu.c \  
  20.     libmodbus/modbus-tcp.c  
  21.   
  22. HEADERS  += mainwindow.h \  
  23.     libmodbus/modbus.h \  
  24.     libmodbus/modbus-private.h \  
  25.     libmodbus/modbus-rtu.h \  
  26.     libmodbus/modbus-rtu-private.h \  
  27.     libmodbus/modbus-tcp.h \  
  28.     libmodbus/modbus-tcp-private.h \  
  29.     libmodbus/modbus-version.h \  
  30.     libmodbus/config.h  
  31.   
  32. LIBS += -Ldll -lws2_32  

mainwindow.cpp

[cpp]  view plain  copy
  1. #include "mainwindow.h"  
  2. #include "ui_mainwindow.h"  
  3. #include <QVBoxLayout>  
  4. #include <QMessageBox>  
  5. #include "libmodbus/modbus.h"  
  6.   
  7. MainWindow::MainWindow(QWidget *parent) :  
  8.     QMainWindow(parent)  
  9. {  
  10.     this->resize(200, 60);  
  11.     this->setWindowTitle("libmodbus slave test");  
  12.   
  13.     pbRtu=new QPushButton("以modbus rtu方式读取地址1中前20个寄存器值"this);  
  14.     pbRtu->resize(200, 30);  
  15.   
  16.     pbTcp=new QPushButton("以modbus tcp方式读取地址1中前20个寄存器值"this);  
  17.     pbRtu->resize(200, 30);  
  18.   
  19.     QWidget *w=new QWidget();  
  20.   
  21.     QVBoxLayout *layout=new QVBoxLayout();  
  22.     layout->addWidget(pbRtu);  
  23.     layout->addWidget(pbTcp);  
  24.   
  25.     w->setLayout(layout);  
  26.   
  27.     this->setCentralWidget(w);  
  28.   
  29.     connect(pbRtu, SIGNAL(clicked()), this, SLOT(doRtuQuery()));  
  30.     connect(pbTcp, SIGNAL(clicked()), this, SLOT(doTcpQuery()));  
  31. }  
  32.   
  33. MainWindow::~MainWindow()  
  34. {  
  35.   
  36. }  
  37.   
  38. void MainWindow::doRtuQuery()  
  39. {  
  40.     modbus_t *mb;  
  41.     uint16_t tab_reg[32]={0};  
  42.   
  43.     mb = modbus_new_rtu("COM1", 9600, 'N', 8, 1);   //相同的端口只能同时打开一个  
  44.     modbus_set_slave(mb, 1);  //设置modbus从机地址  
  45.   
  46.     modbus_connect(mb);  
  47.   
  48.     struct timeval t;  
  49.     t.tv_sec=0;  
  50.     t.tv_usec=1000000;   //设置modbus超时时间为1000毫秒  
  51.     modbus_set_response_timeout(mb, &t);  
  52.   
  53.     int regs=modbus_read_registers(mb, 0, 20, tab_reg);  
  54.   
  55.     QMessageBox::about(NULL, "报告", QString("Rtu读取寄存器的个数:%1").arg(regs));  
  56.     modbus_close(mb);  
  57.     modbus_free(mb);  
  58. }  
  59.   
  60. void MainWindow::doTcpQuery()  
  61. {  
  62.     modbus_t *mb;  
  63.     uint16_t tab_reg[32]={0};  
  64.   
  65.     mb = modbus_new_tcp("127.0.0.1", 5101);  //由于是tcp client连接,在同一个程序中相同的端口可以连接多次。  
  66.     modbus_set_slave(mb, 1);  //从机地址  
  67.   
  68.     modbus_connect(mb);  
  69.   
  70.     struct timeval t;  
  71.     t.tv_sec=0;  
  72.     t.tv_usec=1000000;   //设置modbus超时时间为1000毫秒,注意:经测试,如果没有成功建立tcp连接,则该设置无效。  
  73.     modbus_set_response_timeout(mb, &t);  
  74.   
  75.     int regs=modbus_read_registers(mb, 0, 20, tab_reg);  
  76.   
  77.     QMessageBox::about(NULL, "报告", QString("Tcp读取寄存器的个数:%1").arg(regs));  
  78.     modbus_close(mb);  
  79.     modbus_free(mb);  
  80. }  

猜你喜欢

转载自blog.csdn.net/u011057439/article/details/79246518
今日推荐