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();
}