自製 USB HID鍵盤

Oct 9, 2007 2 分鐘 914 字 #USB

上一次跟大家稍加說明了人性化界面之後,今天要稍微深入一點實作一個小電路和小程式了。

上一次文章連結


電腦系統的複雜度是遠超乎人腦可以掌控的範圍,所以工程師和專家們通常都制定了一套很嚴謹規範讓大家分層負責。這樣每個人只需要搞清礎自己負責的事就好了,就不會讓腦袋爆炸了。

套用一個生活化的例子就是:會計主任只要看看發票加總的金額是發出去的錢是不是一樣就好了,不用去管那到底是真發票還是假發票。整理發票是他下面的人在搞的。

為了怕大腦爆炸我們也先不用管到電子信號是怎樣傳遞,今天就先實做一個會自動按上下左右四個方向鍵的電路和程式就好了。

首先我們去Objective Development網站下載公開的範例程式EasyLogger

如果沒有裝過WINAVR的話,還要去sourceforge.net下載

WinAVR開發工具包

由於篇幅的關係,我們就先假設大家都抓下來也裝好了。

再來就是改寫EasyLogger裡面的main.c 。下面是改寫後的片斷。

/* USB report descriptor */
PROGMEM char usbHidReportDescriptor[USB_CFG_HID_REPORT_DESCRIPTOR_LENGTH] = { 
0x05, 0x01,      // USAGE_PAGE (Generic Desktop)
0x09, 0x06,      // USAGE (Keyboard)
0xa1, 0x01,      // COLLECTION (Application)
0x05, 0x07,      //   USAGE_PAGE (Keyboard)
0x19, 0xe0,      //   USAGE_MINIMUM (Keyboard 
//                  LeftControl)
0x29, 0xe7,      //   USAGE_MAXIMUM (Keyboard 
//                  Right GUI)
0x15, 0x00,      //   LOGICAL_MINIMUM (0)
0x25, 0x01,      //   LOGICAL_MAXIMUM (1)
0x75, 0x01,      //   REPORT_SIZE (1)
0x95, 0x08,      //   REPORT_COUNT (8)
0x81, 0x02,      //   INPUT (Data,Var,Abs)
0x95, 0x01,      //   REPORT_COUNT (1)
0x75, 0x08,      //   REPORT_SIZE (8)
0x25, 0x65,      //   LOGICAL_MAXIMUM (101)
0x19, 0x00,      //   USAGE_MINIMUM (Reserved 
//   (no event indicated))
0x29, 0x65,      //   USAGE_MAXIMUM 
//   (Keyboard Application)
0x81, 0x00,      //   INPUT (Data,Ary,Abs)
0xc0             // END_COLLECTION
};

#define KEY_UP  82
#define KEY_DOWN 81
#define KEY_LEFT 80
#define KEY_RIGHT 79


/* -----------------------------*/


static void timerPoll(void)

{
static uchar timerCnt;
static uchar i;

if(TIFR & (1 << TOV1)){
TIFR = (1 << TOV1); /* clear overflow */
if(++timerCnt >= 63){ /* ~ 1 second interval */
timerCnt = 0;
if (!FlagKey) {
FlagKey = 1;
if (++i > 3)
i=0;
switch (i) {
case 0:
reportBuffer[0] = 0;    
reportBuffer[1] = KEY_RIGHT;
break;
case 1:
reportBuffer[0] = 0;    
reportBuffer[1] = KEY_DOWN;
break;
case 2:
reportBuffer[0] = 0;
reportBuffer[1] = KEY_LEFT;
break;
case 3:
reportBuffer[0] = 0;
reportBuffer[1] = KEY_UP;
break;
}
}   
}
}
}


//
//
//

程式其實很簡單,就是像上次說的:先向作業系統提交一份表格。上面我們所提交的表格是說以後只要鍵盤有狀態改變我就會送2個byte上來.第一個byte是功能鍵(如Ctrl)的狀態,第二個byte是按鍵碼.

再來就是大約每隔一秒就依序上傳上,右,下,左四個方向鍵被按的資訊了.

整個程式看起來很簡單,但卻是個極佳的例子來說明魔盤為何在網路上被批評。今天先寫到這裡賣個關子同時讓大家吸收一下。

我們可以在USB.ORG這文件的第53頁找到各按鍵的代碼

USB HID Usage Tables

USB using ATTiny45

最基本這樣的電路圖簡夠簡單了吧 ?如果要做商業用途的話請自行閱讀Objective Development的授權說明。

`