?? usbcore.lst
字號:
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 + -