关于STM32的USB设备库DIY机械键盘

前言
为什么想写这个呢,首先一方面是因为自己喜欢DIY一些小玩意,另一方面关于USB-HID的东西断断续续的学习了不少东西,想总结整理一下 。其次就是网络上关于STM32制作USB-HID的案例很多,我这里尽量说一些不一样的,以便大家参考,内容主要还是关于机械键盘方面的 。
本来早就应该写的,自己懒,然后又喜欢拖延,最近想着利用下班的时间将它陆续整理完善吧 。
DIY机械键盘相比于客制化机械键盘更为彻底,也没有客制化出来的机械键盘好用,我追寻的只是DIY给我带来的乐趣与成就感 。
如果只是想要一把好用的键盘,建议还是买一把量产键盘 。客制化烧钱,有这个钱,能卖高至少一个等级的量产键盘 。
前后做了三种键盘,GH60,,还有标准的87配列 。有的送人了,有的还在自己手上 。其中GH60和的PCB是自己设计的,代码也是自己敲的,很丑陋,代码习惯不好,就不放出来献丑了,后面主要还是告诉各位实现原理与方法 。
一 STM32的设备库与USB协议
STM32的设备库中有很多的例程,比如DFU,MSC,HID等等,或者直接使用生成的工程也可以一样使用,如何移植,如何让自己的PCBA在电脑上成功的识别为一个HID设备,我这里就不过多赘述了,网上有大量的例子可以参考 。因为库中的例子都是依托STM32的评估板来做的,所以修改起来会比较麻烦,倒不如后一种方法省事 。
重点说一句,就是HID设备的特别之处就在于HID描述符和报告描述符,你这个设备发送给电脑的数据有啥用,需要电脑给你什么数据,都是通过报告描述符来实现的 。而这两个描述符中的各个数据有什么作用,在HID Usage Table这个文档中都有说明,而且,写的很详细 。但是,但是,但是是英文文档,又臭又长,看了下一段,忘了上一段 。所以不想去看的也可以直接复制下面的描述符直接用 。
1.1 设备描述符
const uint8_t CustomHID_DeviceDescriptor[CUSTOMHID_SIZ_DEVICE_DESC] ={0x12,/*bLength:18Bytes */USB_DEVICE_DESCRIPTOR_TYPE, /*bDescriptorType*/0x00,/*bcdUSB */0x02,0x00,/*bDeviceClass*/0x00,/*bDeviceSubClass*/0x00,/*bDeviceProtocol*/0x40,/*bMaxPacketSize:64Bytes*/0x83,/*idVendor (0x0483)*/0x04,0x12,/*idProduct = 0x5750*/0x34,0x00,/*bcdDevice rel. 2.00*/0x02,1,/*Index of string descriptor describingmanufacturer */2,/*Index of string descriptor describingproduct*/3,/*Index of string descriptor describing thedevice serial number */0x01/*bNumConfigurations*/}
关于设备描述符,我只说一个点,即和这两个数据 。这两个数值是不能随便定义的,但是你随便定义也没有关系 。我在调试的过程中发现这样的一个问题,如果我更改了譬如配置描述符的内容,但是没有更改上面这两个数据,电脑就显示上一次的设备,而不是你更改了的设备 。只有在更改了这两个数据以后,PC才会重新识别这个设备 。这个情况在Win7上是如此 。Win10没有出现过 。
1.2 配置描述符
0x09, /* bLength: Configuration Descriptor size */USB_CONFIGURATION_DESCRIPTOR_TYPE, /* bDescriptorType: Configuration */CUSTOMHID_SIZ_CONFIG_DESC,/* wTotalLength: Bytes returned */0x00,0x01,/* bNumInterfaces: 1 interface */0x01,/* bConfigurationValue: Configuration value */0x00,/* iConfiguration: Index of string descriptor describingthe configuration*/0x80,/* bmAttributes: Self powered */0x64,/* MaxPower 200 mA: this current is used for detecting Vbus */
关于配置描述符,说的是你这个设备有多少个接口 。还有最后一个0xC8这个数据表示你这个设备需要从总线上获取多少电流,这个视你设备功耗决定 。0xC8 * 2 = 400mA,最大能获取500mA的电流 。