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


二 多媒体按键的实现方法 2.1 关于复合设备和组合设备
我倒不是去纠结两个概念的含义,只是想说目前比较主流的实现多媒体按键的方法就上面两种 。其实多个接口一个设备的这种设备按照定义应该称之为组合设备 。我下面讲的方法也是通过组合设备,即一个设备下多个接口描述符来实现的 。
就是说一个配置描述符下可以挂多个接口描述符,每个接口做自己的事情,多媒体按键就是通过另外一个接口来实现的 。
2.2 多媒体按键的实现方法
如果一个HID设备中需要实现标准键盘,鼠标,多媒体按键功能,第一种方法就是通过三个接口来实现 。第二种方法就是只使用两个接口,第二个接口通过报告ID这么一个字段,来向PC机报告我这一包数据是鼠标的数据还是多媒体按键数据 。还有第三种方法,就是前面说的复合设备,即把多个设备作为一个hub,这样也可以实现(这个方法我没有证实过) 。
/* system control */0x05, 0x01,// USAGE_PAGE (Generic Desktop)0x09, 0x80,// USAGE (System Control)0xa1, 0x01,// COLLECTION (Application)0x85, 0x02,//REPORT_ID (2)0x15, 0x01,//LOGICAL_MINIMUM (0x1)0x26, 0xb7, 0x00,//LOGICAL_MAXIMUM (0xb7)0x19, 0x01,//USAGE_MINIMUM (0x1)0x29, 0xb7,//USAGE_MAXIMUM (0xb7)0x75, 0x10,//REPORT_SIZE (16)0x95, 0x01,//REPORT_COUNT (1)0x81, 0x00,//INPUT (Data,Array,Abs)0xc0,// END_COLLECTION/* 24 *//* consumer */0x05, 0x0c,// USAGE_PAGE (Consumer Devices)0x09, 0x01,// USAGE (Consumer Control)0xa1, 0x01,// COLLECTION (Application)0x85, 0x03,//REPORT_ID (3)0x15, 0x01,//LOGICAL_MINIMUM (0x1)0x26, 0x9c, 0x02,//LOGICAL_MAXIMUM (0x29c)0x19, 0x01,//USAGE_MINIMUM (0x1)0x2a, 0x9c, 0x02,//USAGE_MAXIMUM (0x29c)0x75, 0x10,//REPORT_SIZE (16)0x95, 0x01,//REPORT_COUNT (1)0x81, 0x00,//INPUT (Data,Array,Abs)0xc0,// END_COLLECTION/* 25 */

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

文章插图
上面的代码中,仅展示了一个例子,使用 ID来完成数据和 数据的区分 。比如报告ID为2的字段表示这一帧的数据是 数据,如果报告ID为3,则表示这次的数据是数据 。
额外提一句,如果使用的报告ID,那么发送给PC机的数据就需要附上报告ID这个字节,且这个ID必须在所有数据的最前面 。
2.3 如何在键盘的工程上添加这个功能
1、首先在.c文件中得定义这个多媒体的报告描述符,也有在里面包含鼠标的数据的,这个随意,只要复合HID标准即可 。然后在对应的.h文件中也要声明这个变量 。
2、修改前面说的配置描述符,这个字段更改为2,表示有两个接口 。
3、在第一个接口描述符后面,添加第二个接口的描述符,这个字段改为1,这是序号为1(起始序号为0)的接口描述符,然后依次添加这个接口的HID描述符和端点描述符 。
4、在.h中添加相应的端点资源 。用到哪个端点,就添加哪个端点 。
#define BTABLE_ADDRESS(0x00)/* EP0*//* rx/tx buffer base address */#define ENDP0_RXADDR(0x30)#define ENDP0_TXADDR(0x70)/* EP1*//* tx buffer base address */#define ENDP1_TXADDR(0xB0)/* EP2*//* Rx buffer base address */#define ENDP2_RXADDR(0xF0)/* EP3*//* Tx buffer base address */#define ENDP3_TXADDR(0x130)
比如说,我这里用到了三个端点,除了端点0 (控制端点)以外,端点1用来发送键盘数据,端点2用来接收键盘上灯的数据,端点3用来发送多媒体数据 。
重点来了!!!
这里每一个宏定义后的值并不是可以随便定义的,如果翻看一下STM32的参考手册USB章节,发现USB模块中有512字节的缓冲区,这个缓缓区和CAN是共用的 。但重点不在这里,如果我把端点0的定义为0x10,那么这样USB设备接收的数据或者发送的数据就会出错 。为什么呢?看下图 。