【USB开发 】用pcDuino的otg做鼠标键盘-Arduino中文社区 - Powered by Discuz!

Arduino中文社区

 找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 6129|回复: 0

【USB开发 】用pcDuino的otg做鼠标键盘

[复制链接]
发表于 2013-12-4 14:24 | 显示全部楼层 |阅读模式
有人说现代社会,计算机锁住了人类的双手,为什么呢?因为基本上一个人一天上班8小时手是不断的在键盘鼠标上面工作的。我们能不能让电脑更智 能一些,例如电脑放弃人类的双手 ,更智能的工作,这里pcDuino跟你提过一个建议。让兼容arduino的各种传感器去采集信号,让pcDuino帮你实现鼠标键盘的各种工作。
      
04140747_RsUZ.jpg
       一,修改内核
                                                                                           vim vim linux-sunxi/drivers/usb/gadget/hid.c #在里面添加几个结构体和几行代码
               static LIST_HEAD(hidg_func_list);
               /* hid descriptor for a keyboard */
               static struct hidg_func_descriptor pcduino_keyboard_date = {
                   .subclass       = 0, /* No subclass */
                   .protocol       = 1, /* Keyboard */
                   .report_length      = 8,
                   .report_desc_length = 63,
                   .report_desc        = {
                       0×05, 0×01, /* USAGE_PAGE (Generic Desktop)           */
                       0×09, 0×06, /* USAGE (Keyboard)                       */
                       0xa1, 0×01, /* COLLECTION (Application)               */
                       0×05, 0×07, /*   USAGE_PAGE (Keyboard)                */
                       0×19, 0xe0, /*   USAGE_MINIMUM (Keyboard LeftControl) */
                       0×29, 0xe7, /*   USAGE_MAXIMUM (Keyboard Right GUI)   */
                       0×15, 0×00, /*   LOGICAL_MINIMUM (0)                  */
                       0×25, 0×01, /*   LOGICAL_MAXIMUM (1)                  */
                       0×75, 0×01, /*   REPORT_SIZE (1)                      */
                       0×95, 0×08, /*   REPORT_COUNT (8)                     */
                       0×81, 0×02, /*   INPUT (Data,Var,Abs)                 */
                       0×95, 0×01, /*   REPORT_COUNT (1)                     */
                       0×75, 0×08, /*   REPORT_SIZE (8)                      */
                       0×81, 0×03, /*   INPUT (Cnst,Var,Abs)                 */
                       0×95, 0×05, /*   REPORT_COUNT (5)                     */
                       0×75, 0×01, /*   REPORT_SIZE (1)                      */
                       0×05, 0×08, /*   USAGE_PAGE (LEDs)                    */
                       0×19, 0×01, /*   USAGE_MINIMUM (Num Lock)             */
                       0×29, 0×05, /*   USAGE_MAXIMUM (Kana)                 */
                       0×91, 0×02, /*   OUTPUT (Data,Var,Abs)                */
                       0×95, 0×01, /*   REPORT_COUNT (1)                     */
                       0×75, 0×03, /*   REPORT_SIZE (3)                      */
                       0×91, 0×03, /*   OUTPUT (Cnst,Var,Abs)                */
                       0×95, 0×06, /*   REPORT_COUNT (6)                     */
                       0×75, 0×08, /*   REPORT_SIZE (8)                      */
                       0×15, 0×00, /*   LOGICAL_MINIMUM (0)                  */
                       0×25, 0×65, /*   LOGICAL_MAXIMUM (101)                */
                       0×05, 0×07, /*   USAGE_PAGE (Keyboard)                */
                       0×19, 0×00, /*   USAGE_MINIMUM (Reserved)             */
                       0×29, 0×65, /*   USAGE_MAXIMUM (Keyboard Application) */
                       0×81, 0×00, /*   INPUT (Data,Ary,Abs)                 */
                       0xc0        /* END_COLLECTION                         */
                   }
               };
               static struct platform_device pcduino_hid_keyboard = {
                   .name           = “hidg”,
                   .id         = 0,
                   .num_resources      = 0,
                   .resource       = 0,
                   .dev.platform_data  = &pcduino_keyboard_date,
               };
               /* hid descriptor for a mouse */
               static struct hidg_func_descriptor pcduino_mouse_data = {
                .subclass = 0, //No SubClass
                .protocol = 2, //Mouse
                .report_length = 4,
                .report_desc_length = 52,
                .report_desc = {
                0×05, 0×01,  //Usage Page(Generic Desktop Controls)
                0×09, 0×02,  //Usage (Mouse)
                0xa1, 0×01,  //Collction (Application)
                0×09, 0×01,  //Usage (pointer)
                0xa1, 0×00,  //Collction (Physical)
                0×05, 0×09,  //Usage Page (Button)
                0×19, 0×01,  //Usage Minimum(1)
                0×29, 0×05,  //Usage Maximum(5)
                0×15, 0×00,  //Logical Minimum(1)
                0×25, 0×01,  //Logical Maximum(1)
                0×95, 0×05,  //Report Count(5)
                0×75, 0×01,  //Report Size(1)
                0×81, 0×02,  //Input(Data,Variable,Absolute,BitField)
                0×95, 0×01,  //Report Count(1)
                0×75, 0×03,  //Report Size(3)
                0×81, 0×01,  //Input(Constant,Array,Absolute,BitField)
                0×05, 0×01,  //Usage Page(Generic Desktop Controls)
                0×09, 0×30,  //Usage(x)
                0×09, 0×31,  //Usage(y)
                0×09, 0×38,  //Usage(Wheel)
                0×15, 0×81,  //Logical Minimum(-127)
                0×25, 0x7F,  //Logical Maximum(127)
                0×75, 0×08,  //Report Size(8)
                0×95, 0×03,  //Report Count(3)
                0×81, 0×06,  //Input(Data,Variable,Relative,BitField)
                0xc0,  //End Collection
                0xc0  //End Collection
                }
               };
              
               static struct platform_device pcduino_hid_mouse = {
                .name = “hidg”,
                .id = 1,
                .num_resources = 0,
                .resource = 0,
                .dev.platform_data = &pcduino_mouse_data,
               };
               static int __init hidg_init(void)
               {
                   int status;
              
                   status = platform_device_register(&pcduino_hid_keyboard);
                   if (status < 0) {
                       printk(“hid keyboard  reg failed\n”);
                       platform_device_unregister(&pcduino_hid_keyboard);
                       return status;
                   }
                   status = platform_device_register(&pcduino_hid_mouse);
                   if (status < 0) {
                       printk(“hid mouse reg  failed\n”);
                       platform_device_unregister(&pcduino_hid_mouse);
                       return status;
                   }
              
              
                   status = platform_driver_probe(&hidg_plat_driver,
                               hidg_plat_driver_probe);
                   if (status < 0)
                       return status;
              
                   status = usb_composite_probe(&hidg_driver, hid_bind);
                   if (status < 0)
                       platform_driver_unregister(&hidg_plat_driver);
              
                   return status;
               }
               module_init(hidg_init);
              
               static void __exit hidg_cleanup(void)
               {
                   platform_driver_unregister(&hidg_plat_driver);
                   platform_device_unregister(&pcduino_hid_keyboard);
                   platform_device_unregister(&pcduino_hid_mouse);
                   usb_composite_unregister(&hidg_driver);
               }
               结构体是需要添加的,后面两个函数里面要加上结构注册。这里说明一下,根据usb协议,每一个设备都要有描述符,两个结构体就是hid 鼠标键盘的描述符。下面配置内核。
                              Device Drivers  —>
                         
  • USB support  —>
                                       <M>   USB Gadget Support  —>
                                                          <M>     SoftWinner SUN4I USB Peripheral Controller                              
                                       < >     Dummy HCD (DEVELOPMENT)                        
                                             USB Gadget Drivers                                
                                       < >     Gadget Zero (DEVELOPMENT)                       
                                       < >     Audio Gadget (EXPERIMENTAL)                     
                                       <M>     Ethernet Gadget (with CDC Ethernet support)     
                                      
  •        RNDIS support                                 
                                       [ ]       Ethernet Emulation Model (EEM) support        
                                       < >     Network Control Model (NCM) support            
                                       < >     Gadget Filesystem (EXPERIMENTAL)               
                                       < >     Function Filesystem (EXPERIMENTAL)              
                                       < >     File-backed Storage Gadget (DEPRECATED)         
                                       < >     Mass Storage Gadget                             
                                       <M>     Serial Gadget (with CDC ACM and CDC OBEX support)
                                       <M>     MIDI Gadget (EXPERIMENTAL)                     
                                       <M>     Printer Gadget                                 
                                       < >     CDC Composite Device (Ethernet and ACM)         
                                       < >     CDC Composite Device (ACM and mass storage)      
                                       < >     Multifunction Composite Gadget (EXPERIMENTAL)   
                                       <M>     HID Gadget                                      
                                       < >     EHCI Debug Device Gadget                        
                                       < >     USB Webcam Gadget
                  
                
                
               
             
             
            
          
          
            二,加载内核                               关于怎么使用编译生成的内核,已经写过好多文章了。这里大致提一下。
                        sudo mount  /dev/nanda  /mnt
               tar xvf pcduino_a10_hwpack_20131129.tar.xz
               cp  kernel/*  /mnt  -f
               cp  rootfs/lib/modules/3.4.29+  /lib/modules/
               vim /etc/modules #添加下面内容
               sw_usb_udc
               g_hid
             
            
          
          
           三,测试驱动
                                   这里测试用到的是linux-sunxi/Documentation/usb里面的测试程序。
                         1 /* hid_gadget_test */
                 2
                 3 #include <pthread.h>
                 4 #include <string.h>
                 5 #include <stdio.h>
                 6 #include <ctype.h>
                 7 #include <fcntl.h>
                 8 #include <errno.h>
                 9 #include <stdio.h>
                10 #include <stdlib.h>
                11 #include <unistd.h>
                12
                13 #define BUF_LEN 512
                14
                15 struct options {
                16     const char    *opt;
                17     unsigned char val;
                18 };
                19
                20 static struct options kmod[] = {
                21     {.opt = “–left-ctrl”,      .val = 0×01},
                22     {.opt = “–right-ctrl”,     .val = 0×10},
                23     {.opt = “–left-shift”,     .val = 0×02},
                24     {.opt = “–right-shift”,    .val = 0×20},
                25     {.opt = “–left-alt”,       .val = 0×04},
                26     {.opt = “–right-alt”,      .val = 0×40},
                27     {.opt = “–left-meta”,      .val = 0×08},
                28     {.opt = “–right-meta”,     .val = 0×80},
                29     {.opt = NULL}
                30 };
                31
                32 static struct options kval[] = {
                33     {.opt = “–return”, .val = 0×28},
                34     {.opt = “–esc”,    .val = 0×29},
                35     {.opt = “–bckspc”, .val = 0x2a},
                36     {.opt = “–tab”,    .val = 0x2b},
                37     {.opt = “–spacebar”,   .val = 0x2c},
                38     {.opt = “–caps-lock”,  .val = 0×39},
                39     {.opt = “–f1″,     .val = 0x3a},
                40     {.opt = “–f2″,     .val = 0x3b},
                41     {.opt = “–f3″,     .val = 0x3c},
                42     {.opt = “–f4″,     .val = 0x3d},
                43     {.opt = “–f5″,     .val = 0x3e},
                44     {.opt = “–f6″,     .val = 0x3f},
                45     {.opt = “–f7″,     .val = 0×40},
                46     {.opt = “–f8″,     .val = 0×41},
                47     {.opt = “–f9″,     .val = 0×42},
                48     {.opt = “–f10″,    .val = 0×43},
                49     {.opt = “–f11″,    .val = 0×44},
                50     {.opt = “–f12″,    .val = 0×45},
                51     {.opt = “–insert”, .val = 0×49},
                52     {.opt = “–home”,   .val = 0x4a},
                53     {.opt = “–pageup”, .val = 0x4b},
                54     {.opt = “–del”,    .val = 0x4c},
                55     {.opt = “–end”,    .val = 0x4d},
                56     {.opt = “–pagedown”,   .val = 0x4e},
                57     {.opt = “–right”,  .val = 0x4f},
                58     {.opt = “–left”,   .val = 0×50},
                59     {.opt = “–down”,   .val = 0×51},
                60     {.opt = “–kp-enter”,   .val = 0×58},
                61     {.opt = “–up”,     .val = 0×52},
                62     {.opt = “–num-lock”,   .val = 0×53},
                63     {.opt = NULL}
                64 };
                65
                66 int keyboard_fill_report(char report[8], char buf[BUF_LEN], int *hold)
                67 {
                68     char *tok = strtok(buf, ” “);
                69     int key = 0;
                70     int i = 0;
                71
                72     for (; tok != NULL; tok = strtok(NULL, ” “)) {
                73
                74         if (strcmp(tok, “–quit”) == 0)
                75             return -1;
                76
                77         if (strcmp(tok, “–hold”) == 0) {
                78             *hold = 1;
                79             continue;
                80         }
                81
                82         if (key < 6) {
                83             for (i = 0; kval.opt != NULL; i++)
                84                 if (strcmp(tok, kval.opt) == 0) {
                85                     report[2 + key++] = kval.val;
                86                     break;
                87                 }
                88             if (kval.opt != NULL)
                89                 continue;
                90         }
                91
                92         if (key < 6)
                93             if (islower(tok[0])) {
                94                 report[2 + key++] = (tok[0] – (‘a’ – 0×04));
                95                 continue;
                96             }
                97
                98         for (i = 0; kmod.opt != NULL; i++)
                99             if (strcmp(tok, kmod.opt) == 0) {
               100                 report[0] = report[0] | kmod.val;
               101                 break;
               102             }
               103         if (kmod.opt != NULL)
               104             continue;
               105
               106         if (key < 6)
               107             fprintf(stderr, “unknown option: %s\n”, tok);
               108     }
               109     return 8;
               110 }
               111
               112 static struct options mmod[] = {
               113     {.opt = “–b1″, .val = 0×01},
               114     {.opt = “–b2″, .val = 0×02},
               115     {.opt = “–b3″, .val = 0×04},
               116     {.opt = NULL}
               117 };
               118
               119 int mouse_fill_report(char report[8], char buf[BUF_LEN], int *hold)
               120 {
               121     char *tok = strtok(buf, ” “);
               122     int mvt = 0;
               123     int i = 0;
               124     for (; tok != NULL; tok = strtok(NULL, ” “)) {
               125
               126         if (strcmp(tok, “–quit”) == 0)
               127             return -1;
               128
               129         if (strcmp(tok, “–hold”) == 0) {
               130             *hold = 1;
               131             continue;
               132         }
               133
               134         for (i = 0; mmod.opt != NULL; i++)
               135             if (strcmp(tok, mmod.opt) == 0) {
               136                 report[0] = report[0] | mmod.val;
               137                 break;
               138             }
               139         if (mmod.opt != NULL)
               140             continue;
               141
               142         if (!(tok[0] == ‘-’ && tok[1] == ‘-’) && mvt < 2) {
               143             errno = 0;
               144             report[1 + mvt++] = (char)strtol(tok, NULL, 0);
               145             if (errno != 0) {
               146                 fprintf(stderr, “Bad value:’%s’\n”, tok);
               147                 report[1 + mvt--] = 0;
               148             }
               149             continue;
               150         }
               151
               152         fprintf(stderr, “unknown option: %s\n”, tok);
               153     }
               154     return 3;
               155 }
               156
               157 static struct options jmod[] = {
               158     {.opt = “–b1″,     .val = 0×10},
               159     {.opt = “–b2″,     .val = 0×20},
               160     {.opt = “–b3″,     .val = 0×40},
               161     {.opt = “–b4″,     .val = 0×80},
               162     {.opt = “–hat1″,   .val = 0×00},
               163     {.opt = “–hat2″,   .val = 0×01},
               164     {.opt = “–hat3″,   .val = 0×02},
               165     {.opt = “–hat4″,   .val = 0×03},
               166     {.opt = “–hatneutral”, .val = 0×04},
               167     {.opt = NULL}
               168 };
               169
               170 int joystick_fill_report(char report[8], char buf[BUF_LEN], int *hold)
               171 {
               172     char *tok = strtok(buf, ” “);
               173     int mvt = 0;
               174     int i = 0;
               175
               176     *hold = 1;
               177
               178     /* set default hat position: neutral */
               179     report[3] = 0×04;
               180
               181     for (; tok != NULL; tok = strtok(NULL, ” “)) {
               182
               183         if (strcmp(tok, “–quit”) == 0)
               184             return -1;
               185
               186         for (i = 0; jmod.opt != NULL; i++)
               187             if (strcmp(tok, jmod.opt) == 0) {
               188                 report[3] = (report[3] & 0xF0) | jmod.val;
               189                 break;
               190             }
               191         if (jmod.opt != NULL)
               192             continue;
               193
               194         if (!(tok[0] == ‘-’ && tok[1] == ‘-’) && mvt < 3) {
               195             errno = 0;
               196             report[mvt++] = (char)strtol(tok, NULL, 0);
               197             if (errno != 0) {
               198                 fprintf(stderr, “Bad value:’%s’\n”, tok);
               199                 report[mvt--] = 0;
               200             }
               201             continue;
               202         }
               203
               204         fprintf(stderr, “unknown option: %s\n”, tok);
               205     }
               206     return 4;
               207 }
               208
               209 void print_options(char c)
               210 {
               211     int i = 0;
               212
               213     if (c == ‘k’) {
               214         printf(“    keyboard options:\n”
               215                “        –hold\n”);
               216         for (i = 0; kmod.opt != NULL; i++)
               217             printf(“\t\t%s\n”, kmod.opt);
               218         printf(“\n  keyboard values:\n”
               219                “        [a-z] or\n”);
               220         for (i = 0; kval.opt != NULL; i++)
               221             printf(“\t\t%-8s%s”, kval.opt, i % 2 ? “\n” : “”);
               222         printf(“\n”);
               223     } else if (c == ‘m’) {
               224         printf(“    mouse options:\n”
               225                “        –hold\n”);
               226         for (i = 0; mmod.opt != NULL; i++)
               227             printf(“\t\t%s\n”, mmod.opt);
               228         printf(“\n  mouse values:\n”
               229                ”        Two signed numbers\n”
               230                “–quit to close\n”);
               231     } else {
               232         printf(“    joystick options:\n”);
               233         for (i = 0; jmod.opt != NULL; i++)
               234             printf(“\t\t%s\n”, jmod.opt);
               235         printf(“\n  joystick values:\n”
               236                “        three signed numbers\n”
               237                “–quit to close\n”);
               238     }
               239 }
               240
               241 int main(int argc, const char *argv[])
               242 {
               243     const char *filename = NULL;
               244     int fd = 0;
               245     char buf[BUF_LEN];
               246     int cmd_len;
               247     char report[8];
               248     int to_send = 8;
               249     int hold = 0;
               250     fd_set rfds;
               251     int retval, i;
               252
               253     if (argc < 3) {
               254         fprintf(stderr, “Usage: %s devname mouse|keyboard|joystick\n”,
               255             argv[0]);
               256         return 1;
               257     }
               258
               259     if (argv[2][0] != ‘k’ && argv[2][0] != ‘m’ && argv[2][0] != ‘j’)
               260       return 2;
               261
               262     filename = argv[1];
               263
               264     if ((fd = open(filename, O_RDWR, 0666)) == -1) {
               265         perror(filename);
               266         return 3;
               267     }
               268
               269     print_options(argv[2][0]);
               270
               271     while (42) {
               272
               273         FD_ZERO(&rfds);
               274         FD_SET(STDIN_FILENO, &rfds);
               275         FD_SET(fd, &rfds);
               276
               277         retval = select(fd + 1, &rfds, NULL, NULL, NULL);
               278         if (retval == -1 && errno == EINTR)
               279             continue;
               280         if (retval < 0) {
               281             perror(“select()”);
               282             return 4;
               283         }
               284
               285         if (FD_ISSET(fd, &rfds)) {
               286             cmd_len = read(fd, buf, BUF_LEN – 1);
               287             printf(“recv report:”);
               288             for (i = 0; i < cmd_len; i++)
               289                 printf(” %02x”, buf);
               290             printf(“\n”);
               291         }
               292
               293         if (FD_ISSET(STDIN_FILENO, &rfds)) {
               294             memset(report, 0×0, sizeof(report));
               295             cmd_len = read(STDIN_FILENO, buf, BUF_LEN – 1);
               296
               297             if (cmd_len == 0)
               298                 break;
               299
               300             buf[cmd_len - 1] = ‘\0′;
               301             hold = 0;
               302
               303             memset(report, 0×0, sizeof(report));
               304             if (argv[2][0] == ‘k’)
               305                 to_send = keyboard_fill_report(report, buf, &hold);
               306             else if (argv[2][0] == ‘m’)
               307                 to_send = mouse_fill_report(report, buf, &hold);
               308             else
               309                 to_send = joystick_fill_report(report, buf, &hold);
               310
               311             if (to_send == -1)
               312                 break;
               313
               314             if (write(fd, report, to_send) != to_send) {
               315                 perror(filename);
               316                 return 5;
               317             }
               318             if (!hold) {
               319                 memset(report, 0×0, sizeof(report));
               320                 if (write(fd, report, to_send) != to_send) {
               321                     perror(filename);
               322                     return 6;
               323                 }
               324             }
               325         }
               326     }
               327
               328     close(fd);
               329     return 0;
               330 }
               编译:gcc  gadget_hid.c
               运行:
               root@ubuntu:/home/ubuntu# ./a.out /dev/hidg0  k   # 键盘
               keyboard options:
               –hold
               –left-ctrl
               –right-ctrl
               –left-shift
               –right-shift
               –left-alt
               –right-alt
               –left-meta
               –right-meta
               keyboard values:
               [a-z] or
               –return             –esc
               –bckspc             –tab
               –spacebar                 –caps-lock
               –f1                –f2
               –f3                –f4
               –f5                –f6
               –f7                –f8
               –f9                –f10
               –f11               –f12
               –insert              –home
               –pageup           –del
               –end              –pagedown
               –right               –left
               –down            –kp-enter
               –up               –num-lock
               根据提示输入: a  b  c  d  e  f
               你电脑上可以看到已经有显示了。
               root@ubuntu:/home/ubuntu# ./a.out /dev/hidg1 m  #鼠标
               mouse options:
               –hold
               –b1
               –b2
               –b3
               mouse values:
               Two signed numbers
               –quit to close
               说明一下
               –b1  10  10
               执行这个的时候,相当于鼠标左键。
               –b2  1
               执行这个的时候,相等于鼠标右键
               –b3  -10  100
               这个相当于移动鼠标。
             
            
          
          
          四,用joystick做鼠标                               这里代码太多了,今天写了一天,我就不贴,你可以到
              https://github.com/Pillar1989/arduino
              我git上面下载,直接运行output/test/usb
              joystick接的是pcDuino的A4和A5,由于里面有个delay(500)。所有移动的时候桌面有些卡顿。具体的演示,就看你自己的了。
            
          
          
          五,补充USB协议                               下面是自己整理的鼠标键盘的通信格式,如果你有兴趣可以研究一下。
              鼠标发送给PC的数据每次4个字节
              BYTE1 BYTE2 BYTE3 BYTE4
              定义分别是:
              BYTE1 –
              |–bit7:   1   表示   Y   坐标的变化量超出-256   ~   255的范围,0表示没有溢出
              |–bit6:   1   表示   X   坐标的变化量超出-256   ~   255的范围,0表示没有溢出
              |–bit5:   Y   坐标变化的符号位,1表示负数,即鼠标向下移动
              |–bit4:   X   坐标变化的符号位,1表示负数,即鼠标向左移动
              |–bit3:     恒为1
              |–bit2:     1表示中键按下
              |–bit1:     1表示右键按下
              |–bit0:     1表示左键按下
              BYTE2 — X坐标变化量,与byte的bit4组成9位符号数,负数表示向左移,正数表右移。用补码表示变化量
              BYTE3 — Y坐标变化量,与byte的bit5组成9位符号数,负数表示向下移,正数表上移。用补码表示变化量
              BYTE4 — 滚轮变化。
              由于手上没有USB鼠标,对BYTE1的4-7位没有测试,对于BYTE2 BYTE3做个测试,BYTE1的4-7全为0的时候,BYTE2 BYTE3的正负表示鼠标移动方向
              键盘发送给PC的数据每次8个字节
              BYTE1 BYTE2 BYTE3 BYTE4 BYTE5 BYTE6 BYTE7 BYTE8
              定义分别是:
              BYTE1 –
              |–bit0:   Left Control是否按下,按下为1
              |–bit1:   Left Shift  是否按下,按下为1
              |–bit2:   Left Alt    是否按下,按下为1
              |–bit3:   Left GUI    是否按下,按下为1
              |–bit4:   Right Control是否按下,按下为1
              |–bit5:   Right Shift 是否按下,按下为1
              |–bit6:   Right Alt   是否按下,按下为1
              |–bit7:   Right GUI   是否按下,按下为1
              BYTE2 — 暂不清楚,有的地方说是保留位
              BYTE3–BYTE8 — 这六个为普通按键
              键盘经过测试。
              例如:键盘发送一帧数据   02 00 0×04 0×05 00 00 00 00
              表示同时按下了Left Shift + ‘a’+‘b’三个键
              附件里面是usb协议中文版,喜欢折腾的可以看看。USB1.1协议中文版
            
          
          
          帖子出自http://cnlearn.linksprite.com/?p=1531     
  • 您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    小黑屋|Archiver|手机版|Arduino中文社区

    GMT+8, 2024-11-30 23:45 , Processed in 0.112525 second(s), 18 queries .

    Powered by Discuz! X3.4

    Copyright © 2001-2021, Tencent Cloud.

    快速回复 返回顶部 返回列表