QT+R&SVisa控制LXI仪器
1.下载并安装visa
R&S®VISA - Rohde & Schwarz China
2.安装后的目录说明
安装了64位visa会默认把32位的安装上;
64位库和头文件目录为:C:\Program Files\IVI Foundation
32位库和头文件目录为:C:\Program Files (x86)\IVI Foundation
以64位为例:
lib:【用Visa32.lib和RsVisa32.lib都可以】
h:【包含visa.h即可】
dll:
3.QT的pro
QT += core gui greaterThan(QT_MAJOR_VERSION, 4): QT += widgets CONFIG += c++17 DEFINES += RSVISA_EXTENSION #如果需要查找设备需要把这个宏打开 # You can make your code fail to compile if it uses deprecated APIs. # In order to do so, uncomment the following line. #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 SOURCES += \ main.cpp \ MainWindow.cpp HEADERS += \ MainWindow.h FORMS += \ MainWindow.ui # Default rules for deployment. qnx: target.path = /tmp/$${TARGET}/bin else: unix:!android: target.path = /opt/$${TARGET}/bin !isEmpty(target.path): INSTALLS += target contains(QT_ARCH, i386){ message("32-bit") INCLUDEPATH += $$PWD/rsvisa/x32/include LIBS += -L$$PWD/rsvisa/x32/lib/ -lRsVisa32 }else{ message("64-bit") INCLUDEPATH += $$PWD/rsvisa/x64/include LIBS += -L$$PWD/rsvisa/x64/lib/ -lRsVisa32 }
注意:如果需要查找设备需要把这个宏:RSVISA_EXTENSION打开
4.MainWindow.h
#ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QMainWindow> #include "visa.h" QT_BEGIN_NAMESPACE namespace Ui { class MainWindow; } QT_END_NAMESPACE class MainWindow : public QMainWindow { Q_OBJECT public: MainWindow(QWidget *parent = nullptr); ~MainWindow(); public slots: void setDevices(QStringList items); void setStatus(const QString& msg); void setPortSource(int port); void setPortBoth(int port); void setPortAll(int port); void setPortNone(int port); private: //初始化 void init(); // 发送数据 void writeData(QString data); // 读取数据 void readData(QByteArray& data); private slots: void on_pushButton_find_clicked(); void on_pushButton_open_clicked(); private: Ui::MainWindow *ui; ViSession m_defRM = -1; ViSession m_vi = -1; }; #endif // MAINWINDOW_H
5.MainWindow.cpp
#include "MainWindow.h" #include "ui_MainWindow.h" #include <QDebug> #include <thread> MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) , ui(new Ui::MainWindow) { ui->setupUi(this); (void)init(); } MainWindow::~MainWindow() { delete ui; } void MainWindow::setDevices(QStringList items) { if(!items.isEmpty()) { ui->comboBox_devices->clear(); ui->comboBox_devices->addItems(items); } } void MainWindow::setStatus(const QString &msg) { ui->statusbar->showMessage(msg); } void MainWindow::setPortSource(int port) { //[1] 使端口可以与VNA源连接 QString cmd = QString(":PORT%1:FUNCtion %2").arg(port).arg("SOURce"); writeData(cmd); } void MainWindow::setPortBoth(int port) { //[1] 使端口测量路可以与VNA测量接收机连接 QString cmd = QString(":PORT%1:FUNCtion %2").arg(port).arg("MEASure"); writeData(cmd); //[2] 使端口参考路可以与VNA参考接收机连接 cmd = QString(":PORT%1:FUNCtion %2").arg(port).arg("REFerence"); writeData(cmd); } void MainWindow::setPortAll(int port) { //[1] 使端口源、测量路、参考路可以与VNA的源和接收机连接 QString cmd = QString(":PORT%1:FUNCtion %2").arg(port).arg("ALL"); writeData(cmd); } void MainWindow::setPortNone(int port) { //[1] 使端口测量路可以与VNA测量接收机连接 QString cmd = QString(":PORT%1:FUNCtion %2").arg(port).arg("NONE"); writeData(cmd); } void MainWindow::init() { //[1] visa设备管理器初始化 if(VI_SUCCESS != viOpenDefaultRM(&m_defRM)) { setStatus("open rm failed"); } else { setStatus("open rm success"); } //[2] 2x16物理端口按钮点击初始化 auto btnList1 = ui->groupBox->findChildren<QPushButton*>(); //group1 for (const auto btn : btnList1) { QObject::connect(btn, &QPushButton::clicked, this, [this, btn](){ setPortAll(btn->text().toInt()); }); } auto btnList2 = ui->groupBox_2->findChildren<QPushButton*>(); //group2 for (const auto btn : btnList2) { QObject::connect(btn, &QPushButton::clicked, this, [this, btn](){ setPortAll(btn->text().toInt()); }); } //[3] 4x8物理端口按钮点击初始化 auto btnList3 = ui->groupBox_3->findChildren<QPushButton*>(); //group1 for (const auto btn : btnList3) { QObject::connect(btn, &QPushButton::clicked, this, [this, btn](){ setPortAll(btn->text().toInt()); }); } auto btnList4 = ui->groupBox_4->findChildren<QPushButton*>(); //group2 for (const auto btn : btnList4) { QObject::connect(btn, &QPushButton::clicked, this, [this, btn](){ setPortAll(btn->text().toInt()); }); } auto btnList5 = ui->groupBox_5->findChildren<QPushButton*>(); //group3 for (const auto btn : btnList5) { QObject::connect(btn, &QPushButton::clicked, this, [this, btn](){ setPortAll(btn->text().toInt()); }); } auto btnList6 = ui->groupBox_6->findChildren<QPushButton*>(); //group4 for (const auto btn : btnList6) { QObject::connect(btn, &QPushButton::clicked, this, [this, btn](){ setPortAll(btn->text().toInt()); }); } } void MainWindow::writeData(QString data) { do { //[1] 资源管理器判断 if(m_defRM <= 0) { setStatus("m_defRM is null"); break; } //[2] 设备判断 if(m_vi <= 0) { setStatus("writeData m_vi is null"); break; } //[3] 确保以回车结束 if(!data.endsWith("\n")) { data = data + "\n"; } //[4] 写数据 if(VI_SUCCESS != viPrintf(m_vi, data.toStdString().data())) { setStatus("writeData failed"); break; } else { ui->textEdit->append("write:"+data); } }while(0); } void MainWindow::readData(QByteArray &data) { do { //[1] 资源管理器判断 if(m_defRM <= 0) { setStatus("m_defRM is null"); break; } //[2] 设备判断 if(m_vi <= 0) { setStatus("m_vi is null"); break; } //[3] 读数据 int bufLeng = 1024*4; unsigned char buf[1024*4]; long unsigned int retcount; if(VI_SUCCESS != viRead(m_vi, buf, bufLeng, &retcount)) { setStatus("readData failed"); break; } data = QByteArray::fromRawData((char*)buf, retcount); }while(0); } void MainWindow::on_pushButton_open_clicked() { do { if("打开"==ui->pushButton_open->text()) { setStatus("open devices"); QString deviceName = ui->comboBox_devices->currentText(); //[1] 资源管理器判断 if(m_defRM <= 0) { setStatus("m_defRM is null"); break; } //[2] 设备恢复 if(m_vi > 0) { viClose(m_vi); m_vi = -1; } //[3] 打开设备 int timeout = 20000; auto ret = viOpen(m_defRM, deviceName.toStdString().data(), 0, timeout, &m_vi); if(VI_SUCCESS != ret) { setStatus("viOpen failed"); break; } ui->pushButton_open->setText("已打开"); //[4] 设置属性 viSetAttribute(m_vi, VI_ATTR_TMO_VALUE, timeout);//设置读写超时 } else { setStatus("close devices"); auto ret = viClose(m_vi); if(VI_SUCCESS != ret) { setStatus("viClose failed"); break; } else { ui->pushButton_open->setText("打开"); setStatus("viClose success"); } } }while(0); } void MainWindow::on_pushButton_find_clicked() { setStatus("find devices"); auto findDeivesFun = [this](){ QStringList rsrcList; do { //[1] 资源管理器判断 if(m_defRM <= 0) { setStatus("m_defRM is null"); break; } //[2] 设置查找属性 ViAttrState searchAttributes = VI_RS_FIND_MODE_CONFIG | VI_RS_FIND_MODE_VXI11 | VI_RS_FIND_MODE_MDNS; auto ret = viSetAttribute(m_defRM, VI_RS_ATTR_TCPIP_FIND_RSRC_MODE, searchAttributes); if(VI_SUCCESS != ret) { setStatus("viSetAttribute failed"); break; } //[3] 查找设备 ViUInt32 retCnt; ViChar desc[256]; ret = viFindRsrc(m_defRM, "?*", &m_vi, &retCnt, desc); if(VI_SUCCESS != ret) { setStatus("viFindRsrc failed"); break; } rsrcList.push_back(desc); for (ViInt16 i = 0; i < static_cast<ViInt16>(retCnt)-1; ++i) { if(VI_SUCCESS == viFindNext(m_vi, desc)) { rsrcList.push_back(QString(desc)); } } }while(0); //[4] 如果查找到了VXI设备,则增加一个通过SOCKET控制它的方式 QStringList socketItems; for(auto item : rsrcList) { if(-1 != item.indexOf("inst0") && -1 != item.indexOf("INSTR")) { auto newItem = item.replace("inst0", "5025"); newItem = newItem.replace("INSTR", "SOCKET"); socketItems.append(newItem); } } rsrcList.append(socketItems); QMetaObject::invokeMethod(this, "setDevices", Qt::QueuedConnection, Q_ARG(QStringList, rsrcList)); }; std::thread t(findDeivesFun); t.detach(); }
长风破浪会有时,直挂云帆济沧海!
可通过下方链接找到博主
https://www.cnblogs.com/judes/p/10875138.html