【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通信的方法,就讲到这里了。
欢迎关注我的公众号,可留言“资料”获取相关资料和软件: