QT调用HIDAPI进行 USB-HID设备通信
目录
一、引用hidapi库
二、创建 设备句柄
三、初始化
四、函数说明
(1)hid_open 打开
(2)hid_set_nonblocking 设置阻塞模式
(3)hid_read 读取
(4)hid_write写入
(5)其他函数
五、总结
一、引用hidapi库
QT中引用库的方式分为隐式调用和显式调用,也就是动态库和静态库。下面是在工程中添加的数据
#在工程中添加库路径LIBS += -L$$PWD/DLL/ -lhidapiHEADERS += hidapi.h
二、创建 设备句柄
创建句柄就是方便对设备进行访问,类似描述符。
private: hid_device *handle ;
三、初始化
初始化步骤比较简单,调用hidapi库的初始化函数就行了,不调用也可以,反正在hid_open函数也会调用。
其中值得注意的是hid_read需要调用才能读取数据,没用触发事件,在QT中一般习惯了信号和槽,但很可惜没用触发事件,我这里使用的方法是开一个线程,循环的读取hid_read函数,来判断是否有数据到达。
//1.初始化hid_init(); //2.打开设备
handle = hid_open( 0x303a, 0x4012,NULL); static unsigned char sendDATA[64] ;// 3.发送数据int res = hid_write(handle, sendDATA, sizeof(sendDATA));
// 4.读取数据int res = hid_read(handle, sendDATA, sizeof(sendDATA));
四、函数说明
(1)hid_open 打开
打开的方式有两种,一种是hid_open以vid,pid的方式打开,还有一种的以路径的方式打开,具体看下面吧。
hid_device * hid_open(unsigned short vendor_id,unsigned short product_id, const wchar_t *serial_number);
/*
@参数1:VID
@参数2:PID
@参数3:设备序列号 (一般NULL即可,默认选第一个)
@返回值返回一个对象指针,NULL是打开失败
*/ //另一个打开方式 通过路径打开hid_device * hid_open_path(const char *path);这里要比hid_open多一个查找(1)hid_device_info *devs = hid_enumerate(0x303a, 0x4012);(2) hid_device * hid_handle = open_path(devs);
(2)hid_set_nonblocking 设置阻塞模式
设置阻塞模式,其实就是设置读取的时候,是否阻塞,设置成非阻塞的话,没用数据会执行后面的程序。
是否阻塞这个是我其中遇到调试一个问题,讲完函数在最后说一下注意事项。
int hid_set_nonblocking(hid_device *dev, int nonblock);
/*
@参数1:对象句柄
@参数2:阻塞模式-非阻塞模式- 1 to enable nonblocking- 0 to disable nonblocking.
@ 0 成功
@-1 失败
*/
(3)hid_read 读取
读取的注意事项就是申请的大小可以跟USBhid设置设置成一样或者大一些
int hid_read(hid_device *dev, unsigned char *data, size_t length);
/*
@参数1:对象句柄
@参数2:存放读取的数据地址
@参数3:长度
@返回值 读取长度 -1读取失败
*/
(4)hid_write写入
函数说明如下:
int hid_write(hid_device *dev, const unsigned char *data, size_t length);
/*
@参数1:对象句柄
@参数2:写入的数据地址
@参数3:写入长度
@返回值 写入长度 -1读取失败
*/
程序使用的发送例子如下, frm是CAN数据,自行按自定义格式就行。
注意发送的第一个字节需要跟 USB-hid设备的报告ID一致,例如我这次的hid设备就是0x03,后面的就是自定义数据了。
static unsigned char USB_BUF[64] = { 0 };memset(USB_BUF,0,sizeof(USB_BUF));int count = 0;unsigned int ID = frm->ID;USB_BUF[count++] = 0x03;USB_BUF[count++] = 0x0;USB_BUF[count++] = 0xff;for(int i = 0 ; i < 4 ; i++){USB_BUF[count++] = ( ID >> ((3-i)*8) )&0xFF;}USB_BUF[count++] = frm->RemoteFlag;USB_BUF[count++] = frm->ExternFlag;USB_BUF[count++] = frm->DataLen;if(frm->DataLen < 9)for(int i = 0 ;i < frm->DataLen ;i++)USB_BUF[(count++)] = frm->Data[i];int res;// res = hid_send_feature_report(Usb_handle,USB_BUF,sizeof(USB_BUF));res = hid_write(Usb_handle,USB_BUF,sizeof(USB_BUF));
(5)其他函数
剩下的函数用到再查吧 ,总的来说,利用库实现HID在QT中不难
主要是配合esp32和STM32的HID实现免驱通信,有时间搞一下ST的例子
struct hid_device_info * hid_enumerate(unsigned short vendor_id, unsigned short product_id);
//简单概括就是 传入需要查找的VID和PID 返回一个 对象结构体
//当VID 和PID 都是 0 的时候,则搜索全部的HID设备 ,具体的可以通过对象的next访问到下一个对象
//下面是具体的介绍
/** @brief Enumerate the HID Devices.This function returns a linked list of all the HID devicesattached to the system which match vendor_id and product_id.If @p vendor_id is set to 0 then any vendor matches.If @p product_id is set to 0 then any product matches.If @p vendor_id and @p product_id are both set to 0, thenall HID devices will be returned.@ingroup API@param vendor_id The Vendor ID (VID) of the types of deviceto open.@param product_id The Product ID (PID) of the types ofdevice to open.@returnsThis function returns a pointer to a linked list of typestruct #hid_device_info, containing information about the HID devicesattached to the system, or NULL in the case of failure. Freethis linked list by calling hid_free_enumeration().*/
//简单概括一下就是发送特征报告的
int hid_send_feature_report(hid_device *dev,const unsigned char *data,size_t length);
//简单概括一下就是获取特征报告的
int hid_get_feature_report(hid_device *dev,unsigned char *data,size_t length);
//获取序列号字符串
int hid_get_serial_number_string(hid_device *dev, wchar_t *string,size_t maxlen);
五、总结
调试过程中主要是下位机的问题,想更方便看到效果, 可以买一个HID模块,本次调试中用到ch9326模块和Bus Hound进行调试。
遇到的问题:
1.刚开始调试的时候,没用考虑阻塞的问题,打开程序的时候设置的非阻塞,当手动关闭的时候再打开的时候没用设置非阻塞,导致hid_read函数阻塞导致整个ui阻塞了
2.由于新接触hid的免驱设备,在调试的时候最好还是先确保一方设备没问题,再调试,刚开始跟同事调试的时候发现,死活连接不上,原来是esp32 usb-hid描述符配置有问题导致,后面买了个新设备调试,发现可以连接上,并能发送。
由于这是第一篇文章,如果这篇文章给你一点帮助,可以先关注一下,后续持续更新QT系列和STM32系列,UI的话后面再搞一个lvgl专栏
以下是hidapi库 链接,提取码:tang
hidapi链接
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
