【STM32+cubemx】0018 HAL库开发:自定义usb HID设备实现

前面几节我们使用Cubemx生成了usb的两个使用例子(虚拟串口、HID鼠标),本节我们进一步学习,如何用生成自定义的HID设备。本节的例子在开发板上运行以后,可以通过usb HID接口实现和计算机更为自由的通信。

本节的例子使用的开发环境是cubemx 6.1.0,pack版本是1.8.0。

1)生成USB HID工程

仍然使用串口工程,如下图添加USB的配置:

可以看到,勾选usb device的功能后,右侧的芯片引脚已经设置好了,DP和DM两根线就是usb通信的差分线。

再配置USB的软件中间件,选择usb device,Custom Interface Device Class,这个选项生成的就是自定义的HID设备。

然后需要修改三个参数:

CUSTOM_HID_FS_BINTERVAL,这个设置的是HID设备的通信时间间隔,单位为ms,最快可以为1ms间隔;

USBD_CUSTOM_HID_REPORT_DESC_SIZE,设置的是报告描述符的长度,设为34(后面会提到为什么是这个值);

USBD_CUSTOMHID_OUTREPORT_BUF_SIZE,比较好理解,设置的是发送缓冲区的大小,HID一次最多可以发送64个字节,我们设置为最大值。

在另一个选项卡中,我们可以看到下面几个参数:VID、PID,以及设备标识,这里我们都不修改。

修改时钟设置,把usb时钟设置为48M:

其他的配置都不用改,就可以生成工程代码了。

2)代码编写

打开生成的keil工程,可以看到已经生成了usb相关的源文件。

我们一步步添加需要的代码。

首先添加报告描述符,如下图,在usbd_custom_hid_if.c文件中,CUSTOM_HID_ReportDesc_FS定义数组内部添加:

描述符定义了usb传输数据的格式。

这里的数组长度USBD_CUSTOM_HID_REPORT_DESC_SIZE就是在cubemx中定义的34,与描述符数组的长度必须一样。

然后,在usbd_customhid.c文件中,找到USBD_CUSTOM_HID_CfgHSDesc数组,修改里面的参数:

标记的四个参数,分别是:接收的长度、延时,发送的长度、延时;这里我们可以跳转到它们的宏定义处修改;长度都修改为0x40;延时可以默认,也可以修改到1,也就是1ms周期,可以加快通信的最快速率。

接着,修改接收函数,如下图,在usbd_custom_hid_if.c文件中,添加语句如下:

这个函数在usb接收到数据时会自动调用,这里我们在函数中,把接收到的数据用strncpy这个函数拷贝到usb_rx_data数组中,然后设置usb_rx_flag标志位。

到主函数中循环查询标志位,查询到则可以处理usb_rx_data中接收到的数据。

需要发送数据时,直接调用HAL库生成的发送函数即可,函数原型如下:

到这里,最主要的就添加完了,可以到主函数中编写测试代码:

主函数中主要添加的是:初始时将USB端口复位,以及主循环中的接收和发送数据。

USB_IO_rest();这个函数主要是用在初始时把usb接口引脚拉低一下,让计算机知道有新设备插入(以前的文章讲过,也可以参考源代码,很容易理解);

主循环中检测接收标志位,如果收到数据,则把数据更新到usb_tx_data中,每隔1s检测一下;每隔1s把usb_tx_data中的数据发送出去。

3)代码测试

将上述keil工程编译、下载、运行,开发板的usb口连接到计算机,可以看到计算机中识别出了一个HID设备,VID和PID与我们设置的一致:

我们使用Bus bond这个软件,来实现usb接口和开发板通信。

打开Bus bond,在Devices页面找到我们的hid设备,注意VID和PID与我们设置的一致:

选中该设备,然后切换到capture页面,点击run,检测收发数据,可以看到开发板每1s向计算机发送一包数据,长度为64字节:

说明发送功能给是正常的。

接着,我们测试接收功能,在Devices页面,选中我们自定义的HID设备后,点击右下方的Send Commands,打开发送窗口,如下设置:

选中usb选项卡,然后选中interrupt Out,在data length处填入64,即需要发送64个字节;修改下方的数据为想要发送的数据,这里为便于观察,设置成全0x11;然后点击发送。

观察captrue窗口,可以看到,监测到接收和发送的数据,其中out为计算机发送,in为计算机接收:

可以看到,发送去的数据,处理之后正确返回了,说明HID双向通信成功了。

4)注意事项

a) 使用HID方式通信,最大的方便之处是不用安装驱动程序,HID设备本质是和鼠标键盘一类的设备,无论windows、linux、或是andriod,都能识别;

b) USB的HID通信最快速率是64Btye/1ms,也就是最快64KB每秒,如果需要使用更快的速率通信,得使用USB的其他模式。

c) 本节的例子使用的开发环境是cubemx 6.1.0,pack版本是1.8.0,换成这个版本主要是因为在这个例子的调试过程中,老版本的环境(cubemx 5.1.0,pack1.7.0)生成的代码里有bug,不太便于学习。

比如,生成的代码在编译时会报错,原因是usbd_conf.c文件中,分频内存的函数内部的mem没有定义,在文件开头添加如下代码可以解决:

(这里在更老的版本和新版本的库中都有定义,中间版本的却没有,ST公司的操作真是迷惑)。

另外,老版本的环境生成的代码,在发送数据时,会莫名其妙把发送的数据长度填充到要发送的数据中,找了好久无法解决的一个bug。

好了,本节usb自定义HID通信的方法,就讲到这里了。

欢迎关注我的公众号,可留言“资料”获取相关资料和软件:

posted @ 2021-12-11 00:40  xiaobaibai_2021  阅读(1915)  评论(0编辑  收藏  举报