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


包缓冲区中有一个叫缓冲区描述表的东西,这个东西的位置也位于包缓冲区中 。它的意义就在于告诉USB设备,哪个端点的数据放置与缓冲区的哪个位置 。而不管我们定义的端点是否为双向端点,即不管我们是否同时使用一个端点来收发数据,它的缓冲区描述表都在那里,都要占据8个字节 。而且这个缓冲区描述表的位置就位于包缓冲区的开始的位置 。也就是说,如果我使用了三个端点,那么的值最小也得是3*8 = 0x18 。至于你定义在0x30这个位置,只是说对于包缓冲区的 空间利用不充分,因为缓冲区描述表后面的部分是都可以用来作为数据缓冲区的,但如果定义的小了,则会造成通信异常 。
5、这里修改好以后,在.c文件中,需要定义如下几个函数 。并在相应头文件中声明 。
uint8_t *CustomHID_GetHIDDescriptor(uint16_t Length){return Standard_GetDescriptorData(Length, &CustomHID_Hid_Descriptor);}uint8_t *Meida_GetHIDDescriptor(uint16_t Length){return Standard_GetDescriptorData(Length, &Media_Hid_Descriptor);}uint8_t *CustomHID_GetReportDescriptor(uint16_t Length){return Standard_GetDescriptorData(Length, &CustomHID_Report_Descriptor);}uint8_t *Media_GetReportDescriptor(uint16_t Length){return Standard_GetDescriptorData(Length, &Media_Report_Descriptor);}
6、最后 。看第一条注释语句,这里为什么是这样,有知道的朋友,欢迎指点迷津 。曾经头皮挠破了,不曾想是这里的原因 。
RESULT CustomHID_Data_Setup(uint8_t RequestNo){uint8_t *(*CopyRoutine)(uint16_t);/* 复合设备一定要将此语句注释掉,否则只识别第一个设备 *///if (pInformation->USBwIndex != 0)//return USB_UNSUPPORT;CopyRoutine = NULL;if ((RequestNo == GET_DESCRIPTOR)&& (Type_Recipient == (STANDARD_REQUEST | INTERFACE_RECIPIENT))&& (pInformation->USBwIndex0 < 3)){if (pInformation->USBwValue1 == REPORT_DESCRIPTOR){if (pInformation->USBwIndex0 == 0){CopyRoutine = CustomHID_GetReportDescriptor;}else if (pInformation->USBwIndex0 == 1){CopyRoutine = Media_GetReportDescriptor;}}else if (pInformation->USBwValue1 == HID_DESCRIPTOR_TYPE){if (pInformation->USBwIndex0 == 0){CopyRoutine = CustomHID_GetHIDDescriptor;}else if (pInformation->USBwIndex0 == 1){CopyRoutine = Meida_GetHIDDescriptor;}}} /* End of GET_DESCRIPTOR */
7、好了,到这里,一个带多媒体按键的键盘组合设备差不多是完成了,除了还需要对其端点的回调函数定义 。插上电脑,应该可以正确的识别为一个设备了 。
三 六键无冲与全键无冲 3.1 关于按键冲突
为什么会有按键冲突?请看下面这张图 。
以上图为例,2×2的键盘矩阵,一般键盘的扫描方式,都是按列扫描,A,B,C,D都是连接在单片机的IO上,A,B设置为输入,然后C,D设置为输出,先让C输出1,D输出0,分别读取A,B引脚的电平,如果此时S3按下,应该是A读到0,B读到1 。然后再让D输出1,C输出0,分别读取A,B电平,应该是A读到0,B也读到0 。这样就可以获得S1-S4的按键状态了 。
还有一种按键扫描方式,不过很少用,先让A,B输入,C,D输出,让C,D同时输出1,读取A,B电平,保存为temp1,然后再让A,B为输出,C,D为输入,A,B同时输出1,读取C,D电平,保存为temp2,然后根据temp1和temp2的组合值来判断是哪个按键按下 。
按键冲突的出现:当按键S1,S2,S3同时按下时,无论采用上述的哪种扫描方法,对于单片机来说,判断结果都是S1,,S2,S3,S4这四个按键都被按下了 。
按键冲突的解决办法:
1:通过改变按键的布局,比如,W,E,S,D这四个按键在某一个游戏操作时容易被同时按下,这就需要在原理图设计时不能把这四个按键放置为上图的形势 。