⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 usbcore.lst

📁 此源代码为双接口法USB键盘鼠标开发源代码
💻 LST
📖 第 1 页 / 共 5 页
字号:
 243           
 244           //这是一个全局条目。定义位域长度为3bit。
 245           0x75, 0x03, //   REPORT_SIZE (3)
 246           
 247           //这是一个主条目,定义输出常量,前面用了5bit,所以这里需要
 248           //3个bit来凑成一字节。
 249           0x91, 0x03, //   OUTPUT (Cnst,Var,Abs)
 250           
 251           //下面这个主条目用来关闭前面的集合。bSize为0,所以后面没数据。
 252           0xc0,        // END_COLLECTION
 253          //以下注释不包括第一字节报告ID。
 254          //通过上面的报告描述符的定义,我们知道返回的输入报告具有8字节。
 255          //第一字节的8个bit用来表示特殊键是否按下(例如Shift、Alt等键)。
 256          //第二字节为保留值,值为常量0。第三到第八字节是一个普通键键值的
 257          //数组,当没有键按下时,全部6个字节值都为0。当只有一个普通键按下时,
 258          //这六个字节中的第一字节值即为该按键的键值(具体的键值请看HID的
 259          //用途表文档),当有多个普通键同时按下时,则同时返回这些键的键值。
 260          //如果按下的键太多,则这六个字节都为0xFF(不能返回0x00,这样会让
 261          //操作系统认为所有键都已经释放)。至于键值在数组中的先后顺序是
 262          //无所谓的,操作系统会负责检查是否有新键按下。我们应该在中断端点1
 263          //中按照上面的格式返回实际的键盘数据。另外,报告中还定义了一个字节
 264          //的输出报告,是用来控制LED情况的。只使用了低7位,高1位是保留值0。
 265          //当某位的值为1时,则表示对应的LED要点亮。操作系统会负责同步各个
 266          //键盘之间的LED,例如你有两块键盘,一块的数字键盘灯亮时,另一块
 267          //也会跟着亮。键盘本身不需要判断各种LED应该何时亮,它只是等待主机
 268          //发送报告给它,然后根据报告值来点亮相应的LED。我们在端点1输出中断
 269          //中读出这1字节的输出报告,然后对它取反(因为学习板上的LED是低电平时
 270          //亮),直接发送到LED上。这样main函数中按键点亮LED的代码就不需要了。
 271          };
 272          ///////////////////////////键盘报告描述符完毕////////////////////////////
 273          
 274          //USB鼠标报告描述符的定义
 275          code uint8 MouseReportDescriptor[]=
 276          {
 277           //这是一个全局(bType为1)条目,选择用途页为普通桌面Generic Desktop Page(0x01)
 278           0x05, 0x01, // USAGE_PAGE (Generic Desktop)
 279           
 280           //这是一个局部(bType为2)条目,说明接下来的应用集合用途用于鼠标
 281           0x09, 0x02, // USAGE (Mouse)
 282           
 283           //这是一个主条目(bType为0)条目,开集合,后面跟的数据0x01表示
 284           //该集合是一个应用集合。它的性质在前面由用途页和用途定义为
 285           //普通桌面用的鼠标。
 286           0xa1, 0x01, // COLLECTION (Application)
 287           
 288           //报告ID,这里定义鼠标报告的ID为1
 289           //为了减少程序修改量,这里依然保留报告ID。
 290           //事实上,该报告只有一个,所以可以不用报告ID。
 291           0x85, 0x01, //Report ID (1)
 292           
 293           //这是一个局部条目。说明用途为指针集合
 294           0x09, 0x01, //   USAGE (Pointer)
 295           
 296           //这是一个主条目,开集合,后面跟的数据0x00表示该集合是一个
 297           //物理集合,用途由前面的局部条目定义为指针集合。
 298           0xa1, 0x00, //   COLLECTION (Physical)
 299           
 300           //这是一个全局条目,选择用途页为按键(Button Page(0x09))
 301           0x05, 0x09, //     USAGE_PAGE (Button)
 302           
 303           //这是一个局部条目,说明用途的最小值为1。实际上是鼠标左键。
C51 COMPILER V7.06   USBCORE                                                               11/16/2008 15:59:36 PAGE 6   

 304           0x19, 0x01, //     USAGE_MINIMUM (Button 1)
 305           
 306           //这是一个局部条目,说明用途的最大值为3。实际上是鼠标中键。
 307           0x29, 0x03, //     USAGE_MAXIMUM (Button 3)
 308           
 309           //这是一个全局条目,说明返回的数据的逻辑值(就是我们返回的数据域的值啦)
 310           //最小为0。因为我们这里用Bit来表示一个数据域,因此最小为0,最大为1。
 311           0x15, 0x00, //     LOGICAL_MINIMUM (0)
 312           
 313           //这是一个全局条目,说明逻辑值最大为1。
 314           0x25, 0x01, //     LOGICAL_MAXIMUM (1)
 315           
 316           //这是一个全局条目,说明数据域的数量为三个。
 317           0x95, 0x03, //     REPORT_COUNT (3)
 318           
 319           //这是一个全局条目,说明每个数据域的长度为1个bit。
 320           0x75, 0x01, //     REPORT_SIZE (1)
 321           
 322           //这是一个主条目,说明有3个长度为1bit的数据域(数量和长度
 323           //由前面的两个全局条目所定义)用来做为输入,
 324           //属性为:Data,Var,Abs。Data表示这些数据可以变动,Var表示
 325           //这些数据域是独立的,每个域表示一个意思。Abs表示绝对值。
 326           //这样定义的结果就是,第一个数据域bit0表示按键1(左键)是否按下,
 327           //第二个数据域bit1表示按键2(右键)是否按下,第三个数据域bit2表示
 328           //按键3(中键)是否按下。
 329           0x81, 0x02, //     INPUT (Data,Var,Abs)
 330           
 331           //这是一个全局条目,说明数据域数量为1个
 332           0x95, 0x01, //     REPORT_COUNT (1)
 333           
 334           //这是一个全局条目,说明每个数据域的长度为5bit。
 335           0x75, 0x05, //     REPORT_SIZE (5)
 336           
 337           //这是一个主条目,输入用,由前面两个全局条目可知,长度为5bit,
 338           //数量为1个。它的属性为常量(即返回的数据一直是0)。
 339           //这个只是为了凑齐一个字节(前面用了3个bit)而填充的一些数据
 340           //而已,所以它是没有实际用途的。
 341           0x81, 0x03, //     INPUT (Cnst,Var,Abs)
 342           
 343           //这是一个全局条目,选择用途页为普通桌面Generic Desktop Page(0x01)
 344           0x05, 0x01, //     USAGE_PAGE (Generic Desktop)
 345           
 346           //这是一个局部条目,说明用途为X轴
 347           0x09, 0x30, //     USAGE (X)
 348           
 349           //这是一个局部条目,说明用途为Y轴
 350           0x09, 0x31, //     USAGE (Y)
 351           
 352           //这是一个局部条目,说明用途为滚轮
 353           0x09, 0x38, //     USAGE (Wheel)
 354           
 355           //下面两个为全局条目,说明返回的逻辑最小和最大值。
 356           //因为鼠标指针移动时,通常是用相对值来表示的,
 357           //相对值的意思就是,当指针移动时,只发送移动量。
 358           //往右移动时,X值为正;往下移动时,Y值为正。
 359           //对于滚轮,当滚轮往上滚时,值为正。
 360           0x15, 0x81, //     LOGICAL_MINIMUM (-127)
 361           0x25, 0x7f, //     LOGICAL_MAXIMUM (127)
 362           
 363           //这是一个全局条目,说明数据域的长度为8bit。
 364           0x75, 0x08, //     REPORT_SIZE (8)
 365           
C51 COMPILER V7.06   USBCORE                                                               11/16/2008 15:59:36 PAGE 7   

 366           //这是一个全局条目,说明数据域的个数为3个。
 367           0x95, 0x03, //     REPORT_COUNT (3)
 368           
 369           //这是一个主条目。它说明这三个8bit的数据域是输入用的,
 370           //属性为:Data,Var,Rel。Data说明数据是可以变的,Var说明
 371           //这些数据域是独立的,即第一个8bit表示X轴,第二个8bit表示
 372           //Y轴,第三个8bit表示滚轮。Rel表示这些值是相对值。
 373           0x81, 0x06, //     INPUT (Data,Var,Rel)
 374           
 375           //下面这两个主条目用来关闭前面的集合用。
 376           //我们开了两个集合,所以要关两次。bSize为0,所以后面没数据。
 377           0xc0,       //   END_COLLECTION
 378           0xc0        // END_COLLECTION
 379          ////以下注释不包括第一字节报告ID。
 380          //通过上面的报告描述符的定义,我们知道返回的输入报告具有4字节。
 381          //第一字节的低3位用来表示按键是否按下的,高5位为常数0,无用。
 382          //第二字节表示X轴改的变量,第三字节表示Y轴的改变量,第四字节表示
 383          //滚轮的改变量。我们在中断端点1中应该要按照上面的格式返回实际的
 384          //鼠标数据。
 385          };
 386          ///////////////////////////报告描述符完毕////////////////////////////
 387          
 388          //USB配置描述符集合的定义
 389          //配置描述符总长度为9+9+9+7+7+9+9+7字节
 390          code uint8 ConfigurationDescriptor[9+9+9+7+7+9+9+7]=
 391          {
 392           /***************配置描述符***********************/
 393           //bLength字段。配置描述符的长度为9字节。
 394           0x09,
 395           
 396           //bDescriptorType字段。配置描述符编号为0x02。
 397           0x02,
 398           
 399           //wTotalLength字段。配置描述符集合的总长度,
 400           //包括配置描述符本身、接口描述符、类描述符、端点描述符等。
 401           sizeof(ConfigurationDescriptor)&0xFF, //低字节
 402           (sizeof(ConfigurationDescriptor)>>8)&0xFF, //高字节
 403           
 404           //bNumInterfaces字段。该配置包含的接口数,有两个接口。
 405           0x02,
 406           
 407           //bConfiguration字段。该配置的值为1。
 408           0x01,
 409           
 410           //iConfigurationz字段,该配置的字符串索引。这里没有,为0。
 411           0x00,
 412           
 413           //bmAttributes字段,该设备的属性。由于我们的板子是总线供电的,
 414           //并且我们不想实现远程唤醒的功能,所以该字段的值为0x80。
 415           0x80,
 416           
 417           //bMaxPower字段,该设备需要的最大电流量。由于我们的板子
 418           //需要的电流不到100mA,因此我们这里设置为100mA。由于每单位
 419           //电流为2mA,所以这里设置为50(0x32)。
 420           0x32,
 421           
 422           /*******************第一个接口描述符*********************/
 423           //bLength字段。接口描述符的长度为9字节。
 424           0x09,
 425           
 426           //bDescriptorType字段。接口描述符的编号为0x04。
 427           0x04,
C51 COMPILER V7.06   USBCORE                                                               11/16/2008 15:59:36 PAGE 8   

 428           
 429           //bInterfaceNumber字段。该接口的编号,第一个接口,编号为0。
 430           0x00,
 431           
 432           //bAlternateSetting字段。该接口的备用编号,为0。
 433           0x00,
 434           
 435           //bNumEndpoints字段。非0端点的数目。由于USB键盘需要二个
 436           //中断端点(一个输入一个输出),因此该值为2。
 437           0x02,
 438           
 439           //bInterfaceClass字段。该接口所使用的类。USB键盘是HID类,
 440           //HID类的编码为0x03。
 441           0x03,
 442           
 443           //bInterfaceSubClass字段。该接口所使用的子类。在HID1.1协议中,
 444           //只规定了一种子类:支持BIOS引导启动的子类。
 445           //USB键盘、鼠标属于该子类,子类代码为0x01。
 446           0x01,
 447           
 448           //bInterfaceProtocol字段。如果子类为支持引导启动的子类,
 449           //则协议可选择鼠标和键盘。键盘代码为0x01,鼠标代码为0x02。
 450           0x01,
 451           
 452           //iConfiguration字段。该接口的字符串索引值。这里没有,为0。
 453           0x00,
 454           
 455           /******************HID描述符************************/
 456           //bLength字段。本HID描述符下只有一个下级描述符。所以长度为9字节。
 457           0x09,
 458           
 459           //bDescriptorType字段。HID描述符的编号为0x21。
 460           0x21,
 461           
 462           //bcdHID字段。本协议使用的HID1.1协议。注意低字节在先。
 463           0x10,
 464           0x01,
 465           
 466           //bCountyCode字段。设备适用的国家代码,这里选择为美国,代码0x21。
 467           0x21,
 468           
 469           //bNumDescriptors字段。下级描述符的数目。我们只有一个报告描述符。
 470           0x01,
 471           
 472           //bDescritporType字段。下级描述符的类型,为报告描述符,编号为0x22。
 473           0x22,
 474           
 475           //bDescriptorLength字段。
 476           //下级描述符的长度。下级描述符为键盘报告描述符。
 477           sizeof(KeyboardReportDescriptor)&0xFF,
 478           (sizeof(KeyboardReportDescriptor)>>8)&0xFF,
 479           
 480           /**********************输入端点描述符***********************/
 481           //bLength字段。端点描述符长度为7字节。
 482           0x07,
 483           
 484           //bDescriptorType字段。端点描述符编号为0x05。
 485           0x05,
 486           
 487           //bEndpointAddress字段。端点的地址。我们使用D12的输入端点1。
 488           //D7位表示数据方向,输入端点D7为1。所以输入端点1的地址为0x81。
 489           0x81,
C51 COMPILER V7.06   USBCORE                                                               11/16/2008 15:59:36 PAGE 9   

 490           
 491           //bmAttributes字段。D1~D0为端点传输类型选择。
 492           //该端点为中断端点。中断端点的编号为3。其它位保留为0。
 493           0x03,

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -