今度はLPC810でテストした”Blinky”を読む。
“Blinky”は次の3つのソースファイルで構成されている。
1. cr_startup_lpc8xx.c
2. crp.c
3. main.c
まずはmain
関数のあるmain.c
から。
/**************************************************************************** * $Id:: blinky.c 3634 2012-10-31 00:09:55Z usb00423 $ * Project: NXP LPC8xx Blinky example * * Description: * This file contains LED blink code example which include timer, * GPIO initialization, and clock monitoring. * **************************************************************************** 略 ****************************************************************************/ #ifdef __USE_CMSIS #include "LPC8xx.h" #endif #include "lpc8xx_clkconfig.h" #include "lpc8xx_gpio.h" #include "lpc8xx_mrt.h" extern uint32_t mrt_counter; /* Main Program */ int main (void) { uint32_t regVal; SystemCoreClockUpdate(); /* Config CLKOUT, mostly used for debugging. */ regVal = LPC_SWM->PINASSIGN8 & ~( 0xFF << 16 ); LPC_SWM->PINASSIGN8 = regVal | ( 12 << 16 ); /* P0.12 is CLKOUT, ASSIGN(23:16). */ CLKOUT_Setup( CLKOUTCLK_SRC_MAIN_CLK ); #if 0 regVal = LPC_SWM->PINASSIGN0 & ~( (0xFF << 0) | (0xFF << 8) ); LPC_SWM->PINASSIGN0 = regVal | ( (2 << 0) | (3 << 8) ); /* P0.2 is UART0 TX, ASSIGN(7:0); P0.3 is UART0 RX. ASSIGN(15:8). */ #endif /* Enable AHB clock to the GPIO domain. */ LPC_SYSCON->SYSAHBCLKCTRL |= (1<<6); /* Set port p0.0 to output */ GPIOSetDir( 0, 0, 1 ); /* Set port p0.16 to output */ GPIOSetDir( 0, 16, 1 ); /* Set port p0.17 to output */ GPIOSetDir( 0, 17, 1 ); init_mrt(0x8000); while (1) /* Loop forever */ { /* I/O configuration and LED setting pending. */ if ( (mrt_counter > 0) && (mrt_counter <= 200) ) { GPIOSetBitValue( 0, 0, 0 ); } if ( (mrt_counter > 200) && (mrt_counter <= 400) ) { GPIOSetBitValue( 0, 0, 1 ); } if ( (mrt_counter > 400) && (mrt_counter <= 600) ) { GPIOSetBitValue( 0, 16, 0 ); } if ( (mrt_counter > 600) && (mrt_counter <= 800) ) { GPIOSetBitValue( 0, 16, 1 ); } if ( (mrt_counter > 800) && (mrt_counter <= 1000) ) { GPIOSetBitValue( 0, 17, 0 ); } if ( (mrt_counter > 1000) && (mrt_counter <= 1200) ) { GPIOSetBitValue( 0, 17, 1 ); } else if ( mrt_counter > 1200 ) { mrt_counter = 0; } } }
main
関数の頭からざーっと見ていくと、クロックの設定をして、LPC_SWM->PINASSIGN8
関連のところはクロックをP0.12ピンに出力する?
LPC_SYSCON->SYSAHBCLKCTRL |= (1<<6);
ここは飛ばして。
GPIOSetDir( 0, 0, 1 );
ここでGPIOの入出力を設定。ここではGPIO P0.0ピンを"出力"に設定。
init_mrt(0x8000);
ここも飛ばして。
while (1)
でループ。
ループ内でmrt_counter
の値によってGPIOSetBitValue( 0, 0, 0 );
とか、GPIOSetBitValue( 0, 0, 1 );
でGPIO P0.0(P0.16, P0.17も)をLOにしたりHIGHにしている。
mrt_counter
は1200より大きくなると0にクリアする。
では、さっき飛ばしたinit_mrt(0x8000);
の定義を見てみると、lpc800_driver_lib
プロジェクトの"lpc8xx_mrt.c"で定義されている。
void init_mrt(uint32_t TimerInterval)
となっていて、処理内容としてはタイマーを設定していて、インターバルは引数で指定している。
で、同ソースファイルのちょっと上にvoid MRT_IRQHandler(void)
が定義されていて、その中で mrt_counter
がカウントアップされている。
次はLPC_SYSCON->SYSAHBCLKCTRL |= (1<<6);
この行。
SYSAHBCLKCTRL
は意味がわからないので、ユーザーズマニュアルを見るとp.36のTable 30にあって、6ビットを1にしているので、GPIOポートレジスタおよびGPIOピン1割り込みレジスタのクロックを有効にしているということ(?)。
と、ここまで読んできてSYSAHBCLKCTRL
でググってたら詳しく解説しているサイトを見つけました。
このサンプルでは元々LPC812用でしたが、私のソースコードはLPC810用にGPIO p0.7をp0.0に書き換えています。
この行LPC_SYSCON->SYSAHBCLKCTRL |= (1<<6);
の意味は、GPIOにクロックを供給することでGPIOが有効になるということのようです。
で、その上のLPC_SWM->PINASSIGN8
関連のところは予想通りp0.12ピンにクロックを出力しているようです。
ただし、この機能はデバッグのためのようで、GPIOにクロックを出力する必要性は無いようです。
先のサイトではUARTのページのおまけの項でボード上のLEDが点灯するからくりのところで解説しています。
まぁ、大体の雰囲気はつかめたから"Blinky"はこれで終わり。
次は自分で新しいプロジェクト(I2CでMPU-6050を使う)を作りたい。