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();
}
相关推荐
瓦力wow5 分钟前
python 绘制3D平面图
开发语言·python·3d·matplotlib
Yu_Mao_Cat1 小时前
数独求解器3.0 增加latex格式读取
开发语言·python·算法
天若有情6732 小时前
探秘 C++ 计数器类:从基础实现到高级应用
java·开发语言·c++
进击的愤怒2 小时前
GIM发布新版本了 (附rust CLI制作brew bottle流程)
开发语言·后端·rust
x-cmd2 小时前
x-cmd install | cargo-selector:优雅管理 Rust 项目二进制与示例,开发体验升级
开发语言·后端·rust·cargo·示例
春生野草2 小时前
如何用JAVA手写一个Tomcat
java·开发语言·tomcat
范纹杉想快点毕业3 小时前
Google C++ Style Guide 谷歌 C++编码风格指南,深入理解华为与谷歌的编程规范——C和C++实践指南
c语言·数据结构·c++·qt·算法
幸运黒锦鲤3 小时前
Qt5、C++11 获取wifi列表与wifi连接
开发语言·qt
满怀10153 小时前
【Python中的Socket套接字详解】网络通信的核心基石
开发语言·网络·python·网络编程·socket
学习使我变快乐3 小时前
C++:关联容器set容器,multiset容器
开发语言·c++·算法