あそ~ぶUSB サンプルソース解説・その3

USBキーボードを作る

2010/11/15

Assembly Desk

1. 概要

ここでは、あそ~ぶUSB のサンプルプログラムを解説していきます。

ここではUSBキーボードを作成します。

PCの[Caps lock][Num lock]の状態によってLEDが点灯します。

また、RA0にスイッチを接続すると、スイッチを[ENTER]として利用する事ができます。

なお、本サンプルソースはMicrochip社のMCHPFSUSBver2.7を元にして作成しています。

この文章は、開発環境が既にインストールされている事を前提としてかかれています。

まだ、開発環境を整えて居ない方はこちらを参考にして、まずは開発環境を整えて下さい。

http://a-desk.jp/modules/forum_pic/index.php?cat_id=4

まだ、ファームウェアのビルドの仕方についてはこちらを参考にして下さい。

http://a-desk.jp/modules/forum_pic/index.php?cat_id=3

2. ソースコード解説

2.1 ファイルの構成

”keyboard_sample”は次の様な、様々なファイルで構成されています。

これらのファイルには、USBの通信を行う為の様々な記述があります。

ここでは、手っ取り早くUSBキーボードのソフトを作れる様になるための、最低限の説明を行います。

“Keyboard.c”このファイルを開いてください。

とりあえず、このファイルの中の次の二つの関数を弄るだけで、大抵のキーボードの機能は実現出来ます。

2.2 void UserInit(void)関数

まずは、”Keyboard.c”の中のUserInit関数を見ていきます。

ここは、プログラムが動きだしてから最初に一回だけ実行されます。

色々な初期化ルーチンを書く事が出来ます。

また、USB関係の初期化はこの関数が実行された後にやってくれるので、よっぽど変な設定をしない限りは正常に動作してくれます。


/******************************************************************************

 * Function:        void UserInit(void)

 *****************************************************************************/

void UserInit(void)

{

        TRISA = 0x3;        //RA0/1を入力

        TRISB = 0;                //RBを出力

        LATB = 0;

lastINTransmission = 0;

lastOUTTransmission = 0;

}//end UserInit


ここでは、ポートの設定と変数の初期化を行っています。

TRISAはRA0と1にスイッチを接続出来るように入力に設定しています。

TRISBは全て出力に設定しています。

lastINTransmission及びlatOUTTransmissionは後で使うUSB通信の管理を行う為の変数です。

削除シないでください。

2.3 void Keyboard(void)関数

Keyboard関数では、キーボードとして、PCとどのようなデータを送受信するかを記述します。


void Keyboard(void)

{

if(!HIDTxHandleBusy(lastINTransmission))

{

                       hid_report_in[0] = 0;

                       hid_report_in[1] = 0;

                   hid_report_in[3] = 0;

                       hid_report_in[4] = 0;

                       hid_report_in[5] = 0;

                       hid_report_in[6] = 0;

                       hid_report_in[7] = 0;

if(!PORTAbits.RA0)

                                hid_report_in[2] = 0x28;        //[ENTER]

else

                                hid_report_in[2] = 0;

                        

                //Send the 8 byte packet over USB to the host.

                lastINTransmission = HIDTxPacket(HID_EP, (BYTE*)hid_report_in, 0x08);

}

   

if(!HIDRxHandleBusy(lastOUTTransmission))

{

                if(hid_report_out[0] & 0x02)        //[CAPS]lock時に点灯

                        LATBbits.LATB4 = 1;

                else

                        LATBbits.LATB4 = 0;

                if(hid_report_out[0] & 0x01)        //[NUM]lock時に点灯

                        LATBbits.LATB5 = 1;

                else

                        LATBbits.LATB5 = 0;

                

                lastOUTTransmission = HIDRxPacket(HID_EP,(BYTE*)&hid_report_out,1);

        }

return;                

}//end keyboard()


2.3.1 あそ~ぶからPCへのデータ

if(!HIDTxHandleBusy(lastINTransmission))このif文の中には、あそ~ぶからPCに送信するデータを入れます。

hid_report[0]~[7]にデータを入れて、lastINTransmission = HIDTxPacket(HID_EP, (BYTE*)hid_report_in, 0x08);の部分で送信しています。

ここで、hid_report[0]~[7]に入れるデータは次の様に決まっています。(これはUSBキーボードの仕様です)

hid_report[0]

Modifier(後述)

hid_report[1]

Reserved(常に0)

hid_report[2]~[7]

Keycode

ModifierはShiftキーやCtrlキーが押されているかどうかの情報を表していて、ビット毎に次のような意味になっています。

ビット0

左Ctrl

ビット1

左Shift

ビット2

左Alt

ビット3

左Windowsキー

ビット4

右Ctrl

ビット5

右Shift

ビット6

右Alt

ビット7

右Windowsキー

また、キーコードはUSBのキーコードで、仮想キーコードとは別物です。

「USB キーコード」等の検索ワードで検索すると調べる事が出来ます。

また、USB.orgの「Universal Serial Bus HID Usage Tables」と言う資料にも載っています。

2.3.2 PCからあそ~ぶへのデータ

if(!HIDRxHandleBusy(lastOUTTransmission))このif文の中ではPCからあそ~ぶに送られたデータに対する処理を記述します。

hid_report_out[0]の中身は以下の状態が入ってきます。

ビット0

Num Lock

ビット1

Caps Lock

ビット2

Scroll Lock

ビット3

Compose

ビット4

Kana

このソフトでは、ビット0(Num Lock)とビット1(Caps Lock)の中身を判定して、LEDの点灯を行っています。

3. スイッチの繋ぎ方

図の様に、スイッチの片側をピンと繋ぎ、1kΩ~10kΩほどの抵抗で、電源と繋ぎます。

もう片側はGNDに繋ぎます。