cortex-m3の勉強のために買った「ARMマイコンパーフェクト学習基板の使い方」をlbedを使うとどのくらい簡単に なるかを試してみます。
実験に使用するのは、以下の3つです。
lbedにはまだ汎用入力クラスがありませんので、この機に作ってみます。
まずは、mbedのDigitalInのAPIを以下のURLで調べます。
DigitalOut.cppをコピーして作りました。
クラス定義のDigitalIn.cppは、ほとんどDigitalOut.cppと同じです。
#include "platform.h" #include "PinNames.h" #include "DigitalIn.h" DigitalIn::DigitalIn() : _pin(-1) , _gpio(0) , _mask(0) { } DigitalIn::DigitalIn(PinName pin, const char* name) : _pin(-1) , _gpio(0) , _mask(0) { setup(pin, name); } void DigitalIn::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); switch(_pin - P2_0) { case 0: _io = &LPC_IOCON->PIO2_0; *_io = 0xd0; break; case 1: _io = &LPC_IOCON->PIO2_1; *_io = 0xd0; break; case 2: _io = &LPC_IOCON->PIO2_2; *_io = 0xd0; break; case 3: _io = &LPC_IOCON->PIO2_3; *_io = 0xd0; break; case 4: _io = &LPC_IOCON->PIO2_4; *_io = 0xd0; break; case 5: _io = &LPC_IOCON->PIO2_5; *_io = 0xd0; break; } } else if (_pin >= P3_0 && _pin <= P3_31) { _gpio = LPC_GPIO3; _mask = 1 << (_pin - P3_0); } if (_gpio) { _gpio->DIR &= ~_mask; } } void DigitalIn::mode(PinMode mode) { switch (mode) { case PullUp: *_io = 0xd0; // MODE = 10 break; case PullDown: *_io = 0xc8; // MODE = 01 マニュアルだと0xc8になりそうなのだが、パーフェクト基板本では0x48とある break; case PullNone: // MODE = 00 *_io = 0xc0; break; case OpenDrain: // TODO 未実装 break; default: *_io = 0xd0; } } int DigitalIn::read() { return _gpio && (_gpio->DATA & _mask) ? 1 : 0; }
何かたくさんの定義をしたように思えるかも知れませんが、これによってDigitalOut.cppはとても簡単になります。
#include "platform.h" #include "PinNames.h" #include "DigitalOut.h" #include "DigitalIn.h" DigitalOut::DigitalOut() { } DigitalOut::DigitalOut(PinName pin, const char* name) { setup(pin, name); } void DigitalOut::setup(PinName pin, const char* name) { DigitalIn::setup(pin, name); if (_gpio) { _gpio->DIR |= _mask; } }
ジャンパP4の3と4、31と32にジャンパーをセットし、タッチエリアに触れるとLEDが点灯するテストプログラムを作ります。
タッチセンサーPCF8883の出力オープン・ドレインHigth *1 なので、LPC1343の入力ピンは、プルダウンモードにセットする必要があります。 *2
テストプログラムTestSwitch.cppは、以下の様になります。
#include <cr_section_macros.h> #include <NXP/crp.h> // Variable to store CRP value in. Will be placed automatically // by the linker when "Enable Code Read Protect" selected. // See crp.h header for more information __CRP extern const unsigned int CRP_WORD = CRP_NO_CRP ; #include "lbed.h" int main(void) { wait_init(); DigitalOut myled(LED2); DigitalIn sw(P2_4); sw.mode(PullDown); while(1) { myled = sw; } }