[USB编程] STM32做一个鼠标键盘复合设备求救(旧帖复开)

[复制链接]
 楼主| lh2008xp 发表于 2014-12-16 15:38 | 显示全部楼层 |阅读模式
STM32做一个鼠标键盘复合设备求救@computer00
https://bbs.21ic.com/forum.php?mod=viewthread&tid=631382&fromuid=745651
由于论坛中同样的问题没有最终解决,因此重开帖。
目的:通过修改报告描述符,利用报告ID的方法,实现单接口的HID USB键盘和鼠标复合设备;
方法:借鉴《圈圈教你学USB》;
问题描述:
①已识别为复合设备,并安装驱动成功;
②但是按按键时,鼠标和键盘数据PC无法识别;
③已通过串口读取到需要发送的数据,因此判定按键数据采集过程正常;怀疑USB设备问题;
使用BUS HOUND检测到设备重启6次后挂起!劳烦大家帮忙分析下,集思广益!

  1. const u8 Joystick_ReportDescriptor[JOYSTICK_SIZ_REPORT_DESC] =
  2.   {
  3. /*****************************keyboard ReportDescriptor**************/
  4. 0x05, 0x01, // USAGE_PAGE (Generic Desktop)
  5. 0x09, 0x06, // USAGE (Keyboard)
  6. 0xa1, 0x01, // COLLECTION (Application)
  7. 0x85, 0x01, //REPORT ID(1)
  8. 0x05, 0x07, //     USAGE_PAGE (Keyboard/Keypad)
  9. 0x19, 0xe0, //     USAGE_MINIMUM (Keyboard LeftControl)
  10. 0x29, 0xe7, //     USAGE_MAXIMUM (Keyboard Right GUI)
  11. 0x15, 0x00, //     LOGICAL_MINIMUM (0)
  12. /* 16 */
  13. 0x25, 0x01, //     LOGICAL_MAXIMUM (1)
  14. 0x95, 0x08, //     REPORT_COUNT (8)
  15. 0x75, 0x01, //     REPORT_SIZE (1)
  16. 0x81, 0x02, //     INPUT (Data,Var,Abs)
  17. 0x95, 0x01, //     REPORT_COUNT (1)
  18. 0x75, 0x08, //     REPORT_SIZE (8)
  19. 0x81, 0x03, //     INPUT (Cnst,Var,Abs)
  20. 0x95, 0x06, //   REPORT_COUNT (6)
  21. /* 32 */
  22. 0x75, 0x08, //   REPORT_SIZE (8)
  23. 0x15, 0x00, //   LOGICAL_MINIMUM(0)
  24. 0x25, 0xFF, //   LOGICAL_MAXIMUM (255)
  25. 0x05, 0x07, //   USAGE_PAGE(keboard/Keypad)
  26. 0x19, 0x00, //   USAGE_MINIMUM (Reserved (no event indicated))
  27. 0x29, 0x65, //   USAGE_MAXIMUM (Keyboard Application)
  28. 0x81, 0x00, //     INPUT (Data,Ary,Abs)
  29. 0x25, 0x01, //     LOGICAL_MAXIMUM (1)
  30. 0x95, 0x05, //   REPORT_COUNT (5)
  31. 0x75, 0x01, //   REPORT_SIZE (1)
  32.   /* 52 */
  33. 0x05, 0x08, //   USAGE_PAGE (LEDs)
  34. 0x19, 0x01, //   USAGE_MINIMUM (Num Lock)
  35. 0x29, 0x05, //   USAGE_MAXIMUM (Kana)
  36. 0x91, 0x02, //   OUTPUT (Data,Var,Abs)
  37. 0x95, 0x01, //   REPORT_COUNT (1)
  38. 0x75, 0x03, //   REPORT_SIZE (3) ÐÞ¸ÄÄÚÈÝ
  39. 0x91, 0x03, //   OUTPUT (Cnst,Var,Abs)
  40. 0xc0,        // END_COLLECTION
  41.   /* 67 */
  42. /*****************************Mouse ReportDescriptor**************/
  43. 0x05,0x01, //USAGE_PAGE(Generic Desktop)
  44. 0x09,0x02, //USAGE(MOUSE)
  45. 0xa1,0x01, //COLLECTION
  46. 0X85,0X02, //REPORT ID(2)
  47. 0x09,0x01,         /*Usage(Pointer)*/
  48. 0xa1,0x00,          /*Collection(Linked)*/
  49. 0x05,0x09,          /*Usage Page(Buttons)*/
  50. 0x19,0x01,          /*Usage Minimum(1)*/
  51.         /* 16 */
  52.         0x29,0x03,          /*Usage Maximum(3)*/
  53.         0x15,0x00,          /*Logical Minimum(0)*/
  54.         0x25,0x01,          /*Logical Maximum(1)*/
  55.         0x95,0x03,          /*Report Count(3)*/
  56.         0x75,0x01,          /*Report Size(1)*/
  57.         0x81,0x02,          /*Input(Variable)*/
  58.         0x95,0x01,          /*Report Count(1)*/
  59.         0x75,0x05,          /*Report Size(5)*/
  60.         /* 32 */
  61.         0x81,0x01,          /*Input(Constant,Array)*/
  62.         0x05,0x01,          /*Usage Page(Generic Desktop)*/
  63.         0x09,0x30,          /*Usage(X axis)*/
  64.         0x09,0x31,          /*Usage(Y axis)*/
  65.         0x09,0x38,          /*Usage(Wheel)*/
  66.         0x15,0x81,          /*Logical Minimum(-127)*/
  67.         0x25,0x7F,          /*Logical Maximum(127)*/       
  68.         0x75,0x08,          /*Report Size(8)*/
  69.         /* 48 */
  70.         0x95,0x03,          /*Report Count(3)*/
  71.         0x81,0x06,          /*Input(Variable, Relative)*/
  72.         0xC0,          /*End Collection*/
  73.         0xc0           //End Collection again
  74.         /* 54 */
  75.   }
  76.   ; /* Joystick_ReportDescriptor */
描述符的代码大家应该很熟悉,是书中的源码!
  1. void Joystick_Send(u8 buf0,u8 buf1,u8 buf2,u8 buf3,u8 buf4,u8 buf5,u8 buf6,u8 buf7,u8 buf8)
  2. {
  3.    u8 Keyboard_Buffer[9] = {0, 0, 0, 0,0,0,0,0,0};
  4.    
  5.   /* prepare buffer to send */
  6.   Keyboard_Buffer[0]=buf0;
  7.   Keyboard_Buffer[1]=buf1;
  8.   Keyboard_Buffer[2]=buf2;
  9.   Keyboard_Buffer[3]=buf3;
  10.   Keyboard_Buffer[4]=buf4;
  11.   Keyboard_Buffer[5]=buf5;
  12.   Keyboard_Buffer[6]=buf6;
  13.   Keyboard_Buffer[7]=buf7;
  14.   Keyboard_Buffer[8]=buf8;

  15.   /*copy mouse position info in ENDP1 Tx Packet Memory Area*/
  16.   UserToPMABufferCopy(Keyboard_Buffer, GetEPTxAddr(ENDP1), 8);
  17.   /* enable endpoint for transmission */
  18.   SetEPTxValid(ENDP1);
  19. }
USB数据传输键盘数据程序段如上,由于含ID为因此数据结构为1+8;
主函数中的程序端如下;
  1. #include "led.h"
  2. #include "delay.h"
  3. #include "key.h"
  4. #include "sys.h"
  5. #include "usart.h"         
  6. #include "string.h"
  7. #include "usb_lib.h"
  8. #include "hw_config.h"
  9. #include "usb_pwr.h"
  10. #include "I2C.h"
  11. #include "mpu6050.h"
  12. #include "24l01.h"
  13.                 
  14. u32 usb_abs(u32 x1,u32 x2)
  15. {
  16.         if(x1>x2)return x1-x2;
  17.         else return x2-x1;
  18. }
  19.   
  20. void usb_port_set(u8 enable)
  21. {         
  22.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);       
  23.         if(enable)_SetCNTR(_GetCNTR()&(~(1<<1)));
  24.         else
  25.         {          
  26.                 _SetCNTR(_GetCNTR()|(1<<1));
  27.                 GPIOA->CRH&=0XFFF00FFF;
  28.                 GPIOA->CRH|=0X00033000;
  29.                 PAout(12)=0;                      
  30.         }
  31. }         

  32. int main(void)
  33. {       
  34.                 u8 Keyboard_Buffer[8] ={0,0,0,0,0,0,0,0};
  35.           u8 key;
  36.                 short X,Y,X1,Y1;
  37.                
  38.                 u8 keysta;                  
  39.                 delay_init();                     //ÑÓʱº¯Êý³õʼ»¯          
  40.                 NVIC_Configuration();          //ÉèÖÃNVICÖжϷÖ×é2:2λÇÀÕ¼ÓÅÏȼ¶£¬2λÏìÓ¦ÓÅÏȼ¶
  41.                 uart_init(9600);                 //´®¿Ú³õʼ»¯Îª9600
  42.                 printf("´®¿Ú³õʼ»¯Íê±Ï\r\n");
  43.           KEY_Init();                                  //°´¼ü³õʼ»¯
  44.                 printf("°´¼ü³õʼ»¯Íê±Ï\r\n");
  45.                 usb_port_set(0);         //USBÏȶϿª
  46.                 delay_ms(300);
  47.                 usb_port_set(1);        //USBÔÙ´ÎÁ¬½Ó
  48.                 USB_Interrupts_Config();   
  49.                 Set_USBClock();   
  50.                 USB_Init();         
  51.                 printf("USB¶¼³õʼ»¯Íê±ÏÁË£¬É§Ä꣬¿ªÊ¼½ÓÊÕ°É£¡£¡£¡\r\n");               
  52.         while(1)
  53.         {                
  54.                  key=KEY_Scan(1);//Ö§³ÖÁ¬°´          
  55.                  if(key==WKUP_PRES) Keyboard_Buffer[3]=0x15; //r
  56.                  if(key==KEY1_PRES) Keyboard_Buffer[3]=0x16; //s
  57.                  if(key==KEY0_PRES) Keyboard_Buffer[3]=0x17; //t
  58. //         printf(" %8d%8d\r\n",Keyboard_Buffer[0],Keyboard_Buffer[1]);       
  59.                  Joystick_Send(0x01,Keyboard_Buffer[0],0,Keyboard_Buffer[3],0,0,0,0,0);
  60.      Keyboard_Buffer[3]=0x00;               
  61.         }
  62. }
  63.        
为实现方便性,主函数暂时只考虑发送键盘数据;


本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

×
 楼主| lh2008xp 发表于 2015-2-13 17:36 | 显示全部楼层
自己的问题自己解决!~目前已基于STM32F103原子开发板实现了键盘和鼠标复合设备,
wk_up键 输入字母r;
KEY1键  鼠标上移;
KEY2键  鼠标下移;
修改主要内容为:
在usb_prop.c程序中SetEPTxCount(ENDP1, 8)修改为在usb_prop.c程序中SetEPTxCount(ENDP1, 8)和SetEPTxCount(ENDP1, 9)
附上工程代码!~

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

×
 楼主| lh2008xp 发表于 2014-12-17 09:13 | 显示全部楼层
@computer00
将键盘程序修改成复合设备除了你的书中修改报告描述符,是不是还要修改设备描述符吗?
diyusb 发表于 2014-12-18 20:42 | 显示全部楼层
严格来说,是需要修改配置描述符、接口描述符
 楼主| lh2008xp 发表于 2014-12-20 15:45 | 显示全部楼层
diyusb 发表于 2014-12-18 20:42
严格来说,是需要修改配置描述符、接口描述符

主要需要修改这两种描述符中的什么参数?数据长度?
computer00 发表于 2014-12-22 20:54 | 显示全部楼层
不需要,只需要修改报告描述符即可实现。
从抓到的信息来看,可能是因为你没有实现set idle这个请求,需要实现一下。
参考书中的例子来应该是OK的。
 楼主| lh2008xp 发表于 2015-2-9 11:08 | 显示全部楼层
computer00 发表于 2014-12-22 20:54
不需要,只需要修改报告描述符即可实现。
从抓到的信息来看,可能是因为你没有实现set idle这个请求,需要 ...

[img][/img]
上面的图中含有set idle,怎么看出来没有实现这个请求?还有实现这个请求与上面程序相关?
344534979 发表于 2016-7-3 23:20 | 显示全部楼层
楼主太强大了,请问怎么发送鼠标左中右键啊?这个数据的格式在哪里有?
307191841 发表于 2020-2-26 16:29 | 显示全部楼层
lh2008xp 发表于 2015-2-13 17:36
自己的问题自己解决!~目前已基于STM32F103原子开发板实现了键盘和鼠标复合设备,
wk_up键 输入字母r;
KEY ...

这个好使,keil版本不同有时候会报错,看下面链接,删掉里面的STM3210X_HD
https://www.cnblogs.com/shirishiqi/p/5484973.html
307191841 发表于 2020-2-26 16:37 | 显示全部楼层
lh2008xp 发表于 2015-2-13 17:36
自己的问题自己解决!~目前已基于STM32F103原子开发板实现了键盘和鼠标复合设备,
wk_up键 输入字母r;
KEY ...

这个代码好使,要做全功能键盘的,可以看下附件的HID键码

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

×
exxew 发表于 2024-1-10 15:29 | 显示全部楼层
踩一脚,留个脚印。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

1

主题

29

帖子

1

粉丝
快速回复 在线客服 返回列表 返回顶部