【STM32+cubemx】0017 HAL库开发:usb HID鼠标设备实现

Cubemx可以生成多种usb设备的初始化代码,本节我们就使用它来生成一个usb HID鼠标的工程,在开发板上运行以后,可以模拟usb鼠标的功能。

1)生成USB HID工程

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

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

再配置USB的软件中间件,选择usb device,Human Interface Device Class,这个选项生成的就是usb鼠标工程。

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

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

2)代码编写

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

我们先来了解一下相关的代码,先打开usbd_hid.c这个源文件,找到其中定义的USBD_HID_CfgDesc数组,这里定义了hid设备的一些参数:

第161行定义了这是一个鼠标,第183行定义了数据发送的间隔为10ms。

间隔这个参数,也可以调用USBD_HID_GetPollingInterval这个函数获取,这个函数也在usbd_hid.c文件中定义。

(其他具体参数的定义比较复杂,可以学习一下usb的描述符后再解读)

接下来,我们需要了解的是USBD_HID_SendReport这个函数,也在usbd_hid.c中定义,它就是usb发送的函数,看以看到它内部调用了USB的发送函数,所以调用它就能把数据通过usb口发到上位机:

然后,我摸还需要知道鼠标传输数据的协议。鼠标发送的数据格式,一共四个字节:

第一个字节表示按键,bit0对应左键、bit1对应右键、bit3对应中键;0表示未按,1表示按下;

第二个字节表示x轴(即鼠标左右移动,0表示不动,正值表示往右移,负值表示往左移,范围-127~127,绝对值对应了移动量大小);

第三个字节表示y轴(即鼠标上下移动,0表示不动,正值表示往下移,负值表示往上移,范围-127~127,绝对值对应了移动量大小);

第四个字节表示鼠标滚轮(正值为往上滚动,负值为往下滚动,-127~127,绝对值对应了移动量大小)。

了解了以上这些必要的知识,我们就可以改写代码了,在主函数中添加,如下图所示:

先获取设备发送数据的间隔,保存,用作后面的延时使用;

再初始化X、Y方向的移动距离,要发送的数据保存在HID_Buffer数组中,然后就可以把数据发送出去了。

这一段代码实现的是,使鼠标按“左上<-->右下”的方式往复运动,运行距离为2。

编译、下载后,断电,再将开发板usb口连接到计算机上,就可以看到计算机识别出了一个新的鼠标设备,并且鼠标会自动来回运动。

注意观察一下设备的VID和PID,和cubemx的设置是一样的。

3)注意事项

a)usb hid设备的初始化

由于一般计算机都能识别HID设备,所以不用安装特殊的驱动程序也能够运行起来。但是需要注意的是,如果不断电重新插拔设备,可能会识别不到HID设备。

这是由于HID设备在初始插接到计算机上时,会同计算机进行几次交互,让计算机知道自己是个鼠标设备(或者键盘设备等等)、以及约定其他一些事项,之后才是向计算机发送数据。Cubemx生成的工程文件中,在初始化usb时,已经有这部分交互的代码了;所以我们在主循环中只需要发送鼠标的运动、点击等数据即可。

如果不断电,程序重新开始运行,计算机可能不会理会这些交互数据,会认为这是已有的usb设备在发送一般的通信数据,所以不能初始化成功。解决办法是在程序初始运行时,将usb的通信线拉低一下,让计算机认为有新设备插入,再去执行usb的初始化,这样就能顺利执行交互,让计算机识别出这是个鼠标设备。

增加的代码如下图,在初始化之前,把usb的IO口拉低一下( 使用USB_IO_rest()函数 ):

该函数具体实现如下:

添加这段代码后,只要程序重新执行,计算机就会认为有新的usb设备插入,会开始交互通信去识别设备的种类。

b)关于通信的时间间隔

主函数中,如图示的两行:

先获取usb设备的通信间隔,然后在主循环中,每延时这个间隔后,发送一次数据。

这个间隔是必须的,因为设备初始定义时包含了这个参数,会在和计算机的交互中确定设备的通信时间间隔;实际使用时,延时大于这个时间是可以的,但是小于这个时间会导致计算机端丢失数据。

好了,本节usb模拟HID鼠标的方法,就讲到这里了。

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

posted @ 2021-11-30 23:42  xiaobaibai_2021  阅读(741)  评论(0编辑  收藏  举报