之前都是在Linux下使用cyusb的usb设备,通过libcyusb.cpp来进行usb设备的读写,libcyusb.cpp底层也是通过libusb来操作设备的,因此,在Linux下,不需要usb相关的驱动就能实现读写的目的了,我们使用的都是bulk方式,亲测好用。
而这几天,公司某个运行在PC上的UI界面工具需要通过USB与板载的FPGA通信,本以为在qt里导入官方的库直接调用,结果是我想得太美好,我当时不知道CY官方提供的库是通过msvc编译器编译的,导致在qt中使用MinGW编译器总是编译不通过(调用接口时)。
网上有几篇教程是在qt里调用CyAPI.lib实现接口调用的,不过好像他们是在qt里调用了msvc编译器,可是qt默认不带这个编译器,得自己安装vs各种环境,我觉得太麻烦,想着还是搞一个msvc编译的库吧。
后来在某个网站上找到了这个库,亲测好用,高兴极了!
MinGW编译的CyAPI.lib的链接为:
https://download.csdn.net/download/baidu_15814023/12673567
下面说下关于在windows下qt中使用CyAPI.lib方法:
1、电脑上安装CYUSB官方驱动,只有这样才能识别USB设备;
2、参照官方 fwdownload_fx2或者fwdownload_fx3目录下的接口,在使用设备前,自动加载固件;
3、调用CCyUSBDevice类的Open接口打开设备,找到IN和OUT端点,我使用的是bulk方式:
//找到输入、输出端点
int eptCount = p_usb_dev->EndPointCount();
int i = 1;
for (i = 1; i < eptCount; i++)
{
bool bIn = ((p_usb_dev->EndPoints[i]->Address & 0x80) == 0x80);
bool bBulk = (p_usb_dev->EndPoints[i]->Attributes == 2);
if (bBulk && bIn)
BulkInEndPt = (CCyBulkEndPoint *)p_usb_dev->EndPoints[i];
if (bBulk && !bIn)
BulkOutEndPt = (CCyBulkEndPoint *)p_usb_dev->EndPoints[i];
}
//设置通讯超时时间,毫秒
BulkInEndPt->TimeOut = 500;
BulkOutEndPt->TimeOut = 500;
其中,BulkInEndPt和BulkOutEndPt是全局变量,类型为CCyBulkEndPoint *,这样,后面就可以直接通过 BulkInEndPt 和 BulkOutEndPt分别接收、发送数据了:
//接收 length字节数据到 p_recv中,成功返回true,超时或者失败返回false
BulkInEndPt->XferData(p_recv, length);
//从p_send中发送length字节数据,成功返回true,超时或者失败返回false
BulkOutEndPt->XferData(p_send, length);
有的示例代码使用的是 BeginDataXfer、WaitForXfer、FinishDataXfer接口,不过官方手册说了,bulk方式下可以直接使用 XferData接口,注意,该接口是阻塞式(可带超时):
当然,如果你的业务需求就是异步操作,那么还是老老实实用BeginDataXfer、WaitForXfer、FinishDataXfer这几个接口吧。
另外,有人可能遇到了这么一个问题,就是通过上位机往USB发送数据时,数据能够直接被发送出去,但是当另一端发送数据给上位机时,上位机并不能及时收到该数据(小于512字节时),这个是因为CY的默认固件限制,所以,建议在发送数据时,以每512字节为一帧进行交互,当然,你也可以修改固件,取校这个限制。