2013/07/14からのアクセス回数 6134 実験ワークベンチ †プログラムを作成する場合には、いろいろな実験に必要な部品を装備した 実験ワークベンチを用意すると便利です。 今回は、トラ技の2012/11号で付録についてきたMyARM基板とLPC-Link *1 を使用します。 写真では、LPC11U14のデバッガ部分を切り離して使用していますが、表面の結線部分をカッターで切断するだけでも大丈夫です。 *2 子供たちでも組み込みの実験をするには、安価でソースレベルのデバッグが可能な環境が不可欠です。 そのため、1台2000円のLPC11U14ボードをワークベンチにするのではなく、 DIPタイプで1個110円のLPC1114FN28 は、外部クリスタルなしでも動作するので、子供たちの電子工作にうってつけです。 プログラミング環境 †無償のプログラムミング環境LPCXpressoを以下のページからユーザ登録し、LPCXpressoをダウンロードしてください。 Windowsを使用の方は、シリアル通信用のチップPL2303のドライバーをダウンロードしてください。 プロジェクトのインポート †プロジェクトを新規に作成すると細かな設定ミスで動作しないことがありますので、 ここでは、LBEDのトップページにあるLBED.ZIPを解凍して、ローカルのディレクトリー *3 に入れたところから説明します。*4 私の使っているLPCXpressoのバージョンは、4.2.2です。 最初に、LPCXpressoを起動して、以下の手順でプロジェクトをインポートしてください。
LEDチカチカをコンパイルする †LBED_MAIN/srcにあるTestOLED.cppをnot_usedに移動し、代わりにTestLED.cppをsrcに移動します。 LBED_MAINを選択し、右クリックしてBuild Projectを選択します。 Console画面に make --no-print-directory post-build Performing post-build steps arm-none-eabi-size "LBED_MAIN.axf"; # arm-none-eabi-objcopy -O binary "LBED_MAIN.axf" "LBED_MAIN.bin" ; checksum -p LPC1114FN_102 -d "LBED_MAIN.bin"; text data bss dec hexfilename 1600 4 28 1632 660LBED_MAIN.axf と表示されたらビルド成功です。 LEDチカチカを動かす †MyARM基板への電源は、LPC-Linkから供給します。 JP3をショートします。 LPC-LinkとMyARMの接続は、以下のようにします。
LPC-LinkをUSBに接続し、MyARMのLED3が点灯すれば接続完了です。 これで、LBED_MAINを選択し、トップのツールバーの虫のようなアイコンをクリックします。 自動的にプログラムがMyARMに書き込まれ、以下のようなデバッガが画面が表示されます。 緑の▲をクリックするとプログラムが動き出し、LED2が1秒間隔で点滅します。 ライブラリの構成 †LBEDのクラスライブラリは、以下の4つのプロジェクトから構成されています。
ベースとなるDigitalOut, BusOut, PinNamesは、「そらみみの声」の IDEを使わずにLPCXpresso LPC1768のプログラムを開発する を参考にさせて頂きました。 ピンの設定 †MyARMは、できるだけピンの配置をmbedと合わせるように作られています。 ピンの番号付けは、mbedにならって左端から反時計回りに1番から40番まで番号付けしました。 p5からp30までは、LBED_LPC11xx/inc/PinNames.hで実際のビン番号にマップされています。 wait関数 †mbedのwait_ms, wait_usとwaitの初期化関数wait_init関数をCで実装しました。 ただし、wait_usは8MHzの4クロックでループを回ると仮定して、ビジーウェイトで実装しました。 wait_usは、周辺機器の初期化に使用されるケースが多く、MPUが変わったときには変更が必要です。 wait_api.h void wait_ms(int ms); void wait_us(int us); void wait_init(void); DigitalOut †DigitalOutのsetupをGPIOとして使えるピンをチェックし、_gpioにポートのアドレス、_ioにIOのアドレスを セットし、最後に_gpiio->DIRで出力用にセットしています。 setup void DigitalOut::setup(PinName pin, const char* name) { _pin = pin; _gpio = 0; _mask = 0; _io = 0; if (_pin >= P0_0 && _pin <= P0_31) { _gpio = LPC_GPIO0; _mask = 1 << (_pin - P0_0); switch(_pin - P0_0) { case 1: _io = &LPC_IOCON->PIO0_1; *_io = 0xd0; break; case 2: _io = &LPC_IOCON->PIO0_2; *_io = 0xd0; break; case 3: _io = &LPC_IOCON->PIO0_3; *_io = 0xd0; break; case 4: _io = &LPC_IOCON->PIO0_4; *_io = 0xd0; break; case 5: _io = &LPC_IOCON->PIO0_5; *_io = 0xd0; break; case 6: _io = &LPC_IOCON->PIO0_6; *_io = 0xd0; break; case 7: _io = &LPC_IOCON->PIO0_7; *_io = 0xd0; break; case 8: _io = &LPC_IOCON->PIO0_8; *_io = 0xd0; break; case 9: _io = &LPC_IOCON->PIO0_9; *_io = 0xd0; break; case 10: _io = &LPC_IOCON->SWCLK_PIO0_10; *_io = 0xd0; break; case 11: _io = &LPC_IOCON->R_PIO0_11; *_io = 0xd0; break; } } else if (_pin >= P1_0 && _pin <= P1_31) { _gpio = LPC_GPIO1; _mask = 1 << (_pin - P1_0); switch(_pin - P1_0) { case 0: _io = &LPC_IOCON->R_PIO1_0; *_io = 0xd0; break; case 1: _io = &LPC_IOCON->R_PIO1_1; *_io = 0xd0; break; case 2: _io = &LPC_IOCON->R_PIO1_2; *_io = 0xd0; break; case 3: _io = &LPC_IOCON->SWDIO_PIO1_3; *_io = 0xd0; break; case 4: _io = &LPC_IOCON->PIO1_4; *_io = 0xd0; break; case 5: _io = &LPC_IOCON->PIO1_5; *_io = 0xd0; break; case 6: _io = &LPC_IOCON->PIO1_6; *_io = 0xd0; break; case 7: _io = &LPC_IOCON->PIO1_7; *_io = 0xd0; break; case 8: _io = &LPC_IOCON->PIO1_8; *_io = 0xd0; break; case 9: _io = &LPC_IOCON->PIO1_9; *_io = 0xd0; break; } } else if (_pin >= P2_0 && _pin <= P2_31) { _gpio = LPC_GPIO2; _mask = 1 << (_pin - P2_0); } else if (_pin >= P3_0 && _pin <= P3_31) { _gpio = LPC_GPIO3; _mask = 1 << (_pin - P3_0); } if (_gpio) { _gpio->DIR |= _mask; } } DigitalOut.hには、read, write, =, intを定義しています。 void write(int value) { if (_gpio) { if (value) { _gpio->DATA |= _mask; } else { _gpio->DATA &= ~ _mask; } } } int read() { return _gpio && (_gpio->DATA & _mask) ? 1 : 0; } DigitalOut& operator = (int value) { write(value); return *this; } DigitalOut& operator = (DigitalOut& rhs) { write(rhs.read()); return *this; } operator int() { return read(); } たったこれだけ? †最初のLEDチカチカに関連するプログラムは、本当にこれだけです。 注意 †Ram領域が足りないとのリンクエラーが発生したので、調べたところ以下のサイトに説明がありました。 http://todotani.cocolog-nifty.com/blog/2011/10/lpcxpresso-idec.html この対処のために、pure_virtual.cpp extern "C" void __cxa_pure_virtual() { while (1); } を定義しました。 コメント †皆様のご意見、ご希望をお待ちしております。 Tweet |