本文章的usb的库来自github的上面的开源库:libusb。这个需要在使用的操作系统的环境中手动编译。
如果你是在window使用,可以下载已经编译好的库:连接在这里。
这里QT-Creator 创建工程,就不介绍了。首先需要创建一个qt工程。
然后根据电脑的需要复制前面下载的库。
笔者这里复制:libusb-MinGW-x64文件夹到工程下面。可以看到三个文件夹,分别是bin、include和lib,其中bin中放着动态链接库,lib中放的是静态链接库,include中放的是头文件
然后在pro里面添加库和头文件。(这里为了方便操作,重新对之前库文件进行重新命名,改成:libusb.a)
win32: LIBS += -L$$PWD/new_test/libusb_MinGW_x64/lib/ -llibusb
INCLUDEPATH += $$PWD/new_test/libusb_MinGW_x64/include
DEPENDPATH += $$PWD/new_test/libusb_MinGW_x64/include
#ifndef DIALOGTEST1_H
#define DIALOGTEST1_H
#include
#include "libusb.h"
#define Vendor_Id 0x1AB1
#define Product_Id 0x0643
namespace Ui {
class Dialogtest;
}
class Dialogtest : public QDialog
{
Q_OBJECT
public:
explicit Dialogtest(QWidget *parent = nullptr);
~Dialogtest();
void ScanDev(void); // 扫描设备
private slots:
void on_ScanBtn_clicked();
private:
Ui::Dialogtest *ui;
libusb_device **devs; // usb获取所有设备
libusb_device *product_dev; // 扫描指定id的设备句柄
uint32_t product_num; // 产品扫描到usb的编号
};
#endif // DIALOGTEST1_H
#include "dialogtest1.h"
#include "ui_dialogtest1.h"
#include "libusb.h"
#include
#include
Dialogtest::Dialogtest(QWidget *parent) :
QDialog(parent),
ui(new Ui::Dialogtest)
{
ui->setupUi(this);
int r = libusb_init(nullptr); // 初始化usb,
int cnt=0;
if(r < 0) // 无usb设备
{
// 取消警告
QMessageBox::warning(this,tr("警告"),tr("搜索不到usb"),QMessageBox::Abort);
// 调整显示内容
this->close();
}
else
{
// 获取连接设备
cnt = libusb_get_device_list(NULL,&devs);
if(cnt < 0) // 没有连接任何设备
{
// 取消警告
QMessageBox::warning(this,tr("警告"),tr("没有连接设备"),QMessageBox::Abort);
// 调整显示内容
this->close();
}
else
{
product_dev=nullptr;
product_num=0;
ScanDev(); // 扫描设备
}
}
}
Dialogtest::~Dialogtest()
{
libusb_free_device_list(devs,true);
libusb_exit(NULL);
delete ui;
}
void Dialogtest::ScanDev()
{
libusb_device *dev;
int i = 0;
// int j = 0;
// uint8_t path[8];
while((dev = devs[i++]) != NULL) // 检查每个usb的句柄
{
struct libusb_device_descriptor desc;
int r = libusb_get_device_descriptor(dev,&desc);
if(r < 0)
{
qDebug() << "failed to get device descriptor.";
break;
}
qDebug("%04x:%04x (bus %d, device %d)",desc.idVendor,desc.idProduct,
libusb_get_bus_number(dev),libusb_get_device_address(dev));
if(desc.idVendor==Vendor_Id && desc.idProduct==Product_Id) //对比,找到合适的供应商和设备
{
product_dev=dev; //保存设备编号
product_num=i;
break;
}
}
if(product_dev==nullptr) //没有合适的设备;
{
QMessageBox::warning(this,tr("警告"),tr("没有连接设备"),QMessageBox::Abort);
ui->labelCom->setText("没有连接");
libusb_free_device_list(devs,true);
}
else
{
ui->labelCom->setText("连接正常");
}
}
void Dialogtest::on_ScanBtn_clicked()
{
libusb_get_device_list(NULL,&devs); // 重新扫描
product_dev=nullptr;
product_num=0;
ScanDev(); // 扫描设备
ubs操作很容易,只要按照步骤,就可以很容易成功加载成功。 使用对应usbapi就可以按照example里面的顺序,依次应用对应的函数。
NI-VISA(Virtual Instrument Software Architec-ture,以下简称为“VISA”)是美国国家仪器NI(NationalInstrument)公司开发的一种用来与各种仪器总线进行通信的高级应用编程接口。VISA总线I/O软件是一个综合软件包,不受平台、总线和环境的限制,可用来对USB、GPIB、串口、VXI、PXI和以太网系统进行配置、编程和调试。VISA是虚拟仪器系统I/ O接口软件。基于自底向上结构模型的VISA创造了一个统一形式的I/ O控制函数集。一方面,对初学者或是简单任务的设计者来说,VISA提供了简单易用的控制函数集,在应用形式上相当简单;另一方面,对复杂系统的组建者来说,VISA提供了非常强大的仪器控制功能与资源管理。
很多仪器仪表公司的上位机的仪器通讯采用VISA库。譬如普源精电科技股份有限公司的DG800 系列函数/任意波形发生器。它支持USB通讯,通过VISA库建立连接。
远程可以控制仪器。
附件中是window应用的VISA库,需要可以直接下载。
win32: LIBS += -L$$PWD/log4qt/bin/ -llog4qt \
-L$$PWD/new_test/libusb_MinGW_x64/lib/ -llibusb \
-L$$PWD/new_test/visa/Lib_x64/msc -lvisa64
INCLUDEPATH += $$PWD/log4qt \
$$PWD/new_test/libusb_MinGW_x64/include \
$$PWD/new_test/visa/Include
DEPENDPATH += $$PWD/log4qt \
$$PWD/new_test/libusb_MinGW_x64/include \
$$PWD/new_test/visa/Include
仪器信息写入,上位机发送信息给仪器。
bool InstrWrite(QString strAddr, QString strContent,QWidget *pDialog)
{
ViSession defaultRM,instr;
ViStatus status;
ViUInt32 retCount;
std::string SendBuf ;
std::string SendAddr ;
bool bWriteOK = false;
// QString str;
//Change the address's data style from CString to char*
SendAddr=strAddr.toStdString();
//Change the command's data style from CString to char*
SendBuf=strContent.toStdString();
//open the VISA instrument
status = viOpenDefaultRM(&defaultRM);
if (status < VI_SUCCESS)
{
QMessageBox::warning(pDialog,QObject::tr("警告"),QObject::tr("No VISA instrument was opened !"),QMessageBox::Abort);
return false;
}
viOpen(defaultRM,(char *)SendAddr.c_str(), VI_NULL, VI_NULL, &instr);
//write command to the instrument
viWrite(instr, (unsigned char *)SendBuf.c_str(), SendBuf.size(), &retCount);
//close the instrument
viClose(instr);
viClose(defaultRM);
return bWriteOK;
}
仪器信息读取。读取仪器发送的消息。
bool InstrRead(QString strAddr, QString *pstrResult,QWidget *pDialog)
{
ViSession defaultRM,instr;
ViStatus status;
ViUInt32 retCount;
std::string SendAddr ;
unsigned char RecBuf[MAX_REC_SIZE];
bool bReadOK = false;
//Change the address's data style from CString to char*
SendAddr = strAddr.toStdString();
memset(RecBuf,0,MAX_REC_SIZE);
//open the VISA instrument
status = viOpenDefaultRM(&defaultRM);
if (status < VI_SUCCESS)
{
// Error Initializing VISA...exiting
QMessageBox::warning(pDialog,QObject::tr("警告"),QObject::tr("No VISA instrument was opened !"),QMessageBox::Abort);
return false;
}
//open the instrument
viOpen(defaultRM,(char *)SendAddr.c_str(), VI_NULL, VI_NULL, &instr);
//read from the instrument
viRead(instr, RecBuf, MAX_REC_SIZE, &retCount);
//close the instrument
viClose(instr);
viClose(defaultRM);
*pstrResult=pstrResult->QString::fromLocal8Bit((char *)RecBuf); // 把char 型转化成为
return bReadOK;
}
控制输出正弦波
case 0: res=pVisaDev->OnSend(this,":SOUR1:FUNC SIN"); if(res==false) break;
case 1: res=pVisaDev->OnSend(this,":SOUR1:FREQ 2000"); if(res==false) break;
case 2: res=pVisaDev->OnSend(this,":SOUR1:VOLT 2"); if(res==false) break;
case 3: res=pVisaDev->OnSend(this,":SOUR1:VOLT:OFFS 0"); if(res==false) break;
case 4: res=pVisaDev->OnSend(this,":SOUR1:PHAS 0"); if(res==false) break;
case 5: res=pVisaDev->OnSend(this,":OUTP1 ON"); if(res==false) break;