2007年10月9日 星期二

自製 USB HID鍵盤

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



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







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



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



首先我們去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的授權說明。



今天的完整程式可以在這裡



9 則留言:

chiahu 提到...

大大你好請問一下你用的ic是多少的 ?
那如何寫滑鼠一直連點右鍵在加鍵盤的空白鍵可以請大大幫忙一下嗎?
那usb的頭電子材料店有在賣嗎?

請大大幫小弟一下

武功卓越 提到...

1.我用的是ATMEL 的tiny45.

2.一個裝置被系統判讀為鍵盤和滑鼠叫做複合裝置.我已經拖稿拖了半年都還沒動手來寫.

3.電子材料行有賣.

weihung 提到...

我在電子材料行都找不到AVR的IC,請問大大你有沒有管道可以買阿,最近找到不少tiny45的應用,可是苦無IC不知道該怎麼上手。

還有就是我找到的資料中有一些需要接16M的震盪器,為什麼你的應用不需要?接下來就是要懂軟體怎麼跟tiny45溝通,做出我要的IIC interface了。

希望大大給我IC相關的資訊,感謝

武功卓越 提到...

IC我都是到IC王
digikey這二個網站去買.

tiny45或tiny2313其實內部就有一個校正過的RC振盪器, (其實一買來就是這種內部振盪的模式).若是頻率剛好適用就不用再外掛振盪器了.

tiny45的USI界面可以設定成master或slave的IIC, 但一開始使用有點複雜. 好在網路上的資源很多.

PCTC 提到...

請問卓越大大
如果我想做到像坊間那種
以PC程式存定義程式進USB裝置
讓他自行控制鍵盤滑鼠跟JOY的功能
要如果製作呢?
這樣應該可以少掉原本燒錄的手續吧

匿名 提到...

請問一下
您有複合式USB鍵盤與滑鼠的範例嗎
可以提供給我參考嗎
謝謝

匿名 提到...

請問這個須要燒路器..燒進ic嗎....謝謝!

阿呆 提到...

您好:
最近想拿AVR來玩USB,Google搜尋到您的網站。
看了您的電路,我有個疑問,在參考Objective Development的V-USB時,它電路的Vcc都有接2根二極體再接到AVR上,我後來查了之後發現,原因似乎是因為D+、D-的信號是3.3V,所以用2根二極體做壓降(AVR309則是用降壓IC)。
您的電路似乎沒看到做降壓,是有用甚麼其他方法,或者D+、D-其實5V也能動呢?

棒棒 提到...

主要關鍵就在R1,R2,R3 這三個電阻的值都比USB規範的要大 ,所以接到主機板上後信號的電壓自然就被分壓得比較小了。不過就是偷懶的作法, 不見得每片主機板都會分成一樣的電壓. 保險一點還是讓AVR的I/O輸出3.3V的信號較好.

張貼留言