2010/11/13からのアクセス回数 7291 はじめに †CQ出版から発売された「ARMマイコンパーフェクト学習基板の使い方」は、様々な インタフェースを実験するための部品とCortex-M3を搭載したARM用学習基板で 著者も私の好きな桑野雅彦氏です。 しかし、Micro BASICを使った説明では、処理の流れが分かりにくく、ビット処理も 読みづらいものとなっています。 microBuilder.euが公開している CodeBase はLPC1343のオープンソースのライブラリです。 ここでは、ARMマイコンパーフェクト学習基板の例題をCodeBaseを使って書き直し、 Cライブラリを使った開発方法を紹介します。 MacOSでCの例題を動かす †私はMacOSで開発しているので、ARMマイコンパーフェクト学習基板のCの例題を MacOSで動かしてみることにしました。 最初に そんすけぶろぐ を参考に以下のようにしました。 GCCは、MacPortのarm-elf-gcc*1を使いました。 変更点は、
makefileの変更 †8行以下に ARM_GCC := arm-elf-gcc ARM_SIZE := arm-elf-size ARM_OBJCOPY := arm-elf-objcopy CMSIS_LIB_DIR := ../../CMSISv1p30_LPC13xx/Debug CMSIS_INC_DIR := ../../CMSISv1p30_LPC13xx/inc を追加し、gcc, sizeの部分を以下のようにしまいした。 # GCCの部分 $(ARM_GCC) -nostdlib -L$(CMSIS_LIB_DIR) -Xlinker --gc-sections -Xlinker -Map=USBPWM.map \ -mcpu=cortex-m3 -mthumb -T "usbpwm_Debug.ld" -o "USBPWM.axf" $(OBJS) $(USER_OBJS) $(LIBS) # SIZEの部分 -$(ARM_SIZE) USBPWM.axf; $(ARM_OBJCOPY) -O binary USBPWM.axf USBPWM.bin 他は、そんすけぶろぐの処理と同じです。 binの処理 †makeで作成されたバイナリファイルは、そのままでは動作しないため、CodeBaseに含まれるlpcrc を使ってチェックサムをバイナリファイルにセットします。 また、パーフェクト学習基板基板への書き込みの際、Finderを使ってコピーすると隠れたゴミファイルが 作成されるため、ターミナルを使って以下のように行いました。 $ make $ lpcrc USBPWM.bin # ここで、基板のスイッチを2,3pinをショートし、Macに挿入します。 $ cp USBPWM.bin "/Volume/CRP DISABLD/" $ sudo umount "/Volume/CRP DISABLD/" この後、基板のスイッチを1,2pinをショートし、Macに挿入し直すと、LEDが点滅します。 これで、MacOS上で学習基板のプログラムが作成できることが確認できました。 CodeBaseのインストール †次にCodeBaseをインストールします。 CodeBaseのダウンロード †CodeBaseは以下のサイトからダウンロードします。 ダウンロードしたLPC1343_CodeBase_v0.50.zipを解凍し、適当なディレクトリに置きます (私は、~/local/arm/以下にセットしました)。 設定 †設定する部分は、MakefileのCROSS_COMPILEの部分だけです。 MacPortのクロスコンパイラ用に # CROSS_COMPILE = arm-none-eabi- CROSS_COMPILE = arm-elf- として、コンパイルしたところ、 /opt/local/lib/gcc/arm-elf/4.3.2/../../../../arm-elf/bin/ld: ERROR: /opt/local/lib/gcc/arm-elf/4.3.2/../../../../arm-elf/lib/thumb/libc.a(lib_a-ctype_.o) uses hardware FP, whereas firmware.elf uses software FP のエラーがでました。MacPortの作ったlib.aがハードのFloating Pointを使っているのに、firmware.elfがソフト ウェアのFloating Pointを使っているようです。MacPort arm-gccのVariantを見てもそれらしい設定がないので、 今回は、FYI氏ブログで使っている devkitARMのMac OS X版をダウンロードしました。 MakefileのCROSS_COMPILEの部分を以下のように変更し、 #CROSS_COMPILE = arm-none-eabi- CROSS_COMPILE = arm-eabi- 今度は、正常にコンパイルができfirmware.binが作成されました。 GPIO出力 †基板にLEDをセットし、LEDを点滅させる例題をCodeBaseで書いてみます。 基板のLEDは、GPIO0の7ビット目に接続されているので、LED点滅プログラムは次のようになります。 #include "core/cpu/cpu.h" #include "core/gpio/gpio.h" #include "core/systick/systick.h" int main (void) { // Initialise the cpu cpuInit(); // Initialise the systick timer with one tick every 10 millaseconds systickInit(10); gpioInit(); // Set GPIO0.7 to output gpioSetDir(0, 7, gpioDirection_Output); // Disable the internal pullup/down resistor on P0.7 gpioSetPullup(&IOCON_PIO0_7, gpioPullupMode_Inactive); while (1) { // Set GPIO0.7 high gpioSetValue(0, 7, 1); systickDelay(50); // Set GPIO0.7 low gpioSetValue(0, 7, 0); systickDelay(50); } } 基本的に、cpuInit関数を呼んだ後は、使用する周辺装置の初期化関数を読み出します。 ここでは、
を読んでいます。 次に、GPIOのレジスタの設定をします。
GPIOの値の設定は、gpioSetValue関数で行います。
となります。 GPIO入力 †次にGPIOの入力のテストを基板付属のタッチセンサーを使って行います。 この基板を入手するまでタッチセンサー専用ICがあるとは知らなくて、便利なものが出てきなぁと思いました。 タッチセンサーを使用するには、 P4ピンソケットの
のジャンパをセットします。使用するGPIOは、GPIO2の4bit目で、本の説明通りプルダウンに設定します。 先のLEDの例と合わせて、タッチしたときにLEDが点灯するようにプログラムを作成しました。 #include "core/cpu/cpu.h" #include "core/gpio/gpio.h" int main (void) { // Initialise the cpu cpuInit(); gpioInit(); // Set GPIO0.7 to output gpioSetDir(0, 7, gpioDirection_Output); // Disable the internal pullup/down resistor on P0.7 gpioSetPullup(&IOCON_PIO0_7, gpioPullupMode_Inactive); // Set GPIO2.4 to input gpioSetDir(2, 4, gpioDirection_Input); // Enable the pull-down resistor on GPIO2.4 gpioSetPullup (&IOCON_PIO2_4, gpioPullupMode_PullDown); while (1) { // Read the current state of GPIO2.4 (1 = high, 0 = low) if (gpioGetValue(2, 4) != 0) { // Set GPIO0.7 high gpioSetValue(0, 7, 1); } else { // Set GPIO0.7 low gpioSetValue(0, 7, 0); } } } どうでしょう、とても簡単にGPIOを使うことができると思いませんか。 CodeBaseはオープンソースなので、各関数のソースを読むことで処理内容を確認することができます。 USB接続時にシリアルデバイスにする方法 †LPC1343には、USBコントローラが付属しており、USBシリアルとすることができます。 CodeBaseのUSB CDCを使ってPCとシリアル通信する例題を作ってみます。 ソースは以下の通りです。 #include "core/cpu/cpu.h" #include "core/uart/uart.h" #include "core/usbcdc/usb.h" #include "core/usbcdc/usbcore.h" #include "core/usbcdc/usbhw.h" #include "core/usbcdc/cdcuser.h" /* Systick Timer Settings */ // The number of milliseconds between each tick of the systick timer #define CFG_SYSTICK_DELAY_IN_MS (1) /* UART Settings */ #define CFG_UART_BAUDRATE (57600) // Default UART speed // RX FIFO buffer size (the maximum number of received chars to store) #define CFG_UART_BUFSIZE (80) // loop until any key input. void waitUntilAnyKeyInput() { int numAvailByte = 0; do { CDC_OutBufAvailChar (&numAvailByte); } while(numAvailByte == 0); } int main (void) { // Initialise the cpu cpuInit(); // Initialise UART with the default baud rate (set in projectconfig.h) uartInit(CFG_UART_BAUDRATE); // Initialise USB CDC CDC_Init(); // Initialise VCOM USB_Init(); // USB Initialization USB_Connect(TRUE); // USB Connect while (!USB_Configuration); // wait until USB is configured waitUntilAnyKeyInput(); printf("Hello world"); while (1) ; } USBに接続するとすぐにプログラムを実行してしまうため、Mac側のターミナルから任意の文字を入力した タイミングでHello worldと出力することにしました。 文字列入力を待つ関数は、waitUntilAnyKeyInputです。 動作確認 †基板を接続すると、「新しいネットワークインタフェースが検出されました。」のメッセージがでます。 キャンセルとし、ここでは設定はしません。 ターミナルで以下のようにデバイスを確認します。 $ ls /dev/cu.* /dev/cu.Bluetooth-Modem /dev/cu.Bluetooth-PDA-Sync /dev/cu.usbmodem241321 と出力され、/dev/cu.usbmodem241321が新しいシリアルデバイスです。 起動方法が簡単なので、シリアル通信にはscreenコマンドを使用します。 $ screen /dev/cu.usbmodem241321 Hello world screenコマンドを実行し、リターンキーを押すと「Hello world」と表示されます。 screenコマンドを終了するには、Ctrl-a Ctrl-kとし[Y/N]を確認してくるので、yを入力すれば終了します。 このUSBシリアル通信は、デバッグやPCからの制御でとても便利です。 コメント [ †皆様のご意見、ご希望をお待ちしております。
Tweet |