【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】
利用usb接口访问底层下位机,这是一种很常见的方式。目前比较简单的做法有两种,一种是usb转串口,另外一种是利用libusb访问下位机设备。前面一种看着是usb,其实是串口;后面一种则主要针对mcu等设备。今天,我们借着学习qt的机会,练习下如何利用libusb库进行上位机、下位机的通讯。
1、创建一个widget的qt工程
创建的目的,主要还是构建一个qt版本,用于编译。
2、usb设备插入到pc
一旦usb设备插入到电脑当中,我们就可以在设备管理器中发现这个设备。目前为止,因为还没有驱动和这个设备关联,所以设备显示为不可用的状态。
3、给设备安装libusb驱动
安装驱动的方法比较简单。首先是安装zadig软件。等zadig软件安装好了之后,就可以利用zadig给usb设备安装libusb驱动。这一步非常重要,只有安装了驱动之后,后续我们开发qt上位机的时候,才能利用libusb库操作这个设备。同时,在安装的时候,注意记录一下vendor id号、product id号,编程的时候用得到。
4、安装libusb第三方库
安装的方法,其实就是利用nuget进行安装的。选中“引用”,右击“管理NuGet程序包”,输入libusb查找即可,选择第一个选项,单击下载,
5、设置include目录路径
当前情况下,工程是找不到libusb的include地址的,需要手动添加,即,
C:\Users\feixiaoxing\Desktop\QtWidgetsApplication\packages\libusb.1.0.21\src\include
6、设置链接lib库,注意顺便加上目录
如果缺少这个步骤,待会链接是不会通过的,
C:\Users\feixiaoxing\Desktop\QtWidgetsApplication\packages\libusb.1.0.21\lib\native\x86\libusb-1.0.lib
7、添加源代码
整个代码倒没有想象得那么复杂。首先初始化libusb,接着打开设备,读取数据,写入数据,关闭设备,关闭libusb。注意一下,这里的读取数据和写入数据,使用的函数都是libusb_bulk_transfer,只不过两者的endpoint不一样,前者是0x81,后者是0x01。
#include <QApplication>
#include <QDebug>
#include <libusb-1.0/libusb.h>
#define VENDOR_ID 0x1234 // vendor id
#define PRODUCT_ID 0xabcd // product id
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
// init libusb here
libusb_context *ctx = nullptr;
libusb_init(&ctx);
// open device
libusb_device_handle *devHandle = libusb_open_device_with_vid_pid(ctx, VENDOR_ID, PRODUCT_ID);
if (devHandle == nullptr) {
qDebug() << "Failed to open device.";
libusb_exit(ctx);
return app.exec();
}
// read data
unsigned char buffer[64];
int bytesRead = 0;
int readResult = libusb_bulk_transfer(devHandle, 0x81, buffer, sizeof(buffer), &bytesRead, 1000); // 0x81, read
if (readResult == 0) {
qDebug() << "Read data successful. Bytes read: " << bytesRead;
// add your operation here
}
else {
qDebug() << "Failed to read data. Error code: " << readResult;
}
// write data
const char *dataToWrite = "Hello, USB Device!";
int bytesWritten = 0;
int writeResult = libusb_bulk_transfer(devHandle, 0x01, (unsigned char *)dataToWrite, strlen(dataToWrite), &bytesWritten, 1000); // 0x01, write
if (writeResult == 0) {
qDebug() << "Write data successful. Bytes written: " << bytesWritten;
}
else {
qDebug() << "Failed to write data. Error code: " << writeResult;
}
// close device
libusb_close(devHandle);
// shutdown libusb
libusb_exit(ctx);
return app.exec();
}
8、调试和测试
调试的时候,需要提前把libusb的libusb-1.0.dll文件,拷贝到exe的目录下面。不然没有办法启动和调试exe。另外在调试过程中,可以结合mcu上面的串口打印一起调试,这样效果会更好一点,效率也会更高一点。