タイマー |
![]() |
内蔵のタイマーをカスケード接続して、正確に時間を計るプログラムの例です。screen 構造体のx-y座標に値を代入すると、エミュレータ上で正しく動作しないようなので、実機で動作テストしてください。もし、原因が解ったら教えてください。座標の保存のために配列を使用しなければ、エミュレータでも動作するようですが、マルチタスクOS上のエミュレータでは、正確な時間は計れません。 |
/****************************************************************/ /* Timer control */ /****************************************************************/ #include "gba.h" #include "FontC64-08.c" void init_screen(void); void location(int, int); void scroll(void); void print(const char*); void print_hex8(int); void print_hex16(int); |
FontC64-08.c は、キー入力と複数画面合成で使用したものと同じフォントデータ。 | // Background palette base address pointer 0x05000000 hword* bcolor = (hword*) BG_PALETTE; // Screen structures screen plane[ 1 ] = { { (hword*) VRAM_MAP(16), (hword*) VRAM_TILE(0), 0, 0}, }; int page = 0; // page number |
背景パレットのポインタ設定と、文字表示画面用のscreen型構造体を用意します。ここでは、背景を使用しないため、画面は1枚だけ必要なので、画面番号は page = 0 のみを使用します。 | int main() { // Initialize screen init_screen(); |
init_screen 関数で、フォントデータの設定と画面の初期設定を行います。 | // Initialize timers gba_reg(TIMER_CNT0) = 0x0000; gba_reg(TIMER_CNT1) = 0x0000; |
タイマー0とタイマー1のタイマー設定レジスタを16 bit の 0 に設定しています。これで、カウント初期値が、0になります。 | gba_reg(TIMER_CTL0) = TIMER_ENABLE + TIMER_PRE256; gba_reg(TIMER_CTL1) = TIMER_ENABLE + TIMER_CASCADE; |
タイマー0とタイマー1のタイマー制御レジスタの値を、タイマー動作開始にすると同時に、タイマー1のプリスケーラ(分周器)を、256 = 28 周期に設定しています。これで、16 bit フルカウントすると、216 + 8 = 224となります。GBAのシステムクロックの周波数は、224Hz に設定されているため、16bit フルカウントすると、丁度1秒に相当します。ハードウエアの概要のページで確認してください。タイマー0だけでは、1秒までしかカウントできないので、タイマー1をカスケードモードにして1秒単位でカウントアップさせます。カスケードモードでは、前の番号のタイマーがオーバフローする毎に、1カウントするモードです。この設定方法も、ハードウエアの概要のページで確認してください。 | // Print loop while (1) { location(8, 7); print("Timer 0 : "); location(18, 7); print_hex16(gba_reg(TIMER_CNT0)); location(8, 8); print("Timer 1 : "); location(18, 8); print_hex16(gba_reg(TIMER_CNT1)); } } |
location 関数で、文字を出力する座標を指定し、タイマー0とタイマー1のカウント値を16進数4桁で表示します。 | // Screen Initialization void init_screen(void) { int i, row, col, bit, val; // Initialize palettes bcolor[ 0 ] = RGB(0, 0, 0); // Black bcolor[ 1 ] = RGB(0, 31, 25); // Green // Setup tiles of font set for (i = 0; i < 96; i++) { for (row = 0; row < 8; row++) { for (col = 7; col >= 0; col--) { bit = (Font[ i ][ row ] & (1 << col)) ? 1 : 0; if (col % 2) val = bit; else plane[ 0 ].tile[((i + 32) * 32) + (row * 4) + \ ((7 - col)/2)] = val + (bit << 8); } } } |
フォントデータをタイルに読み込みます。この処理は、テキスト表示のページと同じです。 | //Setup background mode and LCD control register gba_reg(BG0_CTL) = LCD_SIZE00 | LCD_COLOR256 | LCD_BGTILE(0)| LCD_BGMAP(16); gba_reg(LCD_CTL) = LCD_BG0 | LCD_MODE0; } |
文字表示用に背景コントロールレジスタとLCDコントロールレジスタを設定します。これまでに、何度も出てきたので、説明を省略します。 | // Present position of tile character void location(int xx, int yy) { if (xx < 0) plane[ page ].x = 0; else if (xx >= 30) plane[ page ].x = 30 - 1; else plane[ page ].x = xx; if (yy < 0) plane[ page ].y = 0; else if (yy >= 20) plane[ page ].y = 20 - 1; else plane[ page ].y = yy; } |
文字出力座標(タイル単位)を指定する関数です。キー入力と複数画面合成のページと同じものですから、内容説明は省略します。 | // Scroll up void scroll(void) { int i, j; // Scroll for (i = 1; i < 20; i++) { for (j = 0; j < 30; j++) plane[ page ].map[ (i - 1) * 32 + j ] = \ plane[ page ].map[ i * 32 + j ]; } // End line for (j = 0; j < 30; j++) plane[ page ].map[ 19 * 32 + j ] = 0x20; // SP in bottom line } |
文字出力画面をスクロールさせる関数です。キー入力と複数画面合成のページと同じものですから、内容説明は省略します。 | // Print function void print(const char* str) { const char* pt = str; while (*pt) { if (*pt == '\n') { plane[ page ].x = 0; if (plane[ page ].y < (20 - 1)) plane[ page ].y++; else scroll(); pt++; continue; } plane[ page ].map[ plane[ page ].y * 32 + plane[ page ].x ] = *pt++; if (plane[ page ].x < (30 - 1)) plane[ page ].x++; else { plane[ page ].x = 0; if (plane[ page ].y < (20 - 1)) plane[ page ].y++; else scroll(); } } } |
文字列を表示する関数です。キー入力と複数画面合成のページと同じものですから、内容説明は省略します。 | // Print 1Byte HEX void print_hex8(int val) { char buf[ 3 ]; buf[ 0 ] = "0123456789ABCDEF"[ (val & 0xF0) >> 4 ]; buf[ 1 ] = "0123456789ABCDEF"[ val & 0x0F ]; buf[ 2 ] = 0; // Null print(buf); } |
16進2桁の数値を表示する関数です。キー入力と複数画面合成のページと同じものですから、内容説明は省略します。 | // Print 2Byte HEX void print_hex16(int val) { print_hex8((val & 0xFF00) >> 8); print_hex8(val & 0x00FF); } |
16進4桁の数値を表示する関数です。キー入力と複数画面合成のページと同じものですから、内容説明は省略します。 |
(c) Kanazawa Univ., 2004