/* LCD test */ #include #define PBDDR ((_UB *)0x00ffffd4) #define LCD_GPIO ((_UB *)0x00ffffd6) // PBDR #define LCD_DB(x) ((x) & 0x0f) // DB4-7 <- PB0-3 #define LCD_RS (1 << 4) // RS <- PB4 #define LCD_E (1 << 7) // E <- PB7 #define LCD_E_DELAY 1 // usec #define LCD_CMD_DELAY 50 // usec /* μsec単位の待ち */ LOCAL void WaitUsec(UW usec) { #define CPUkHz (CPU_CLOCK / 1000) #define WaitFactor (20 * 1000) usec = (CPUkHz * usec + WaitFactor - 1) / WaitFactor; /* * ステート数は、内蔵ROM上で実行した場合の値。 * 外部バスに接続したRAM等では、より多くのステート数となる。 * * ※H8/3052Fのバスステートコントローラの設定値を * デフォルトのままとし、AKI-H8-LANボードのSRAM上に * コードを配置した場合、内蔵ROM上に配置した場合と * 比べて6倍程度の実行時間となる。 */ Asm( "0: mov.l %0, %0 \n" // 2 " beq 1f \n" // 4 " nop \n" // 2 " nop \n" // 2 " nop \n" // 2 " nop \n" // 2 " dec.l #1, %0 \n" // 2 " bra 0b \n" // 4 (total 20clk) "1: \n" :: "r"(usec)); return; } /* 4bit単位のデータ送信 */ LOCAL void lcd_writenibble(UB data) { *LCD_GPIO = data | LCD_E; WaitUsec(LCD_E_DELAY); *LCD_GPIO = data & ~LCD_E; WaitUsec(LCD_E_DELAY); return; } /* LCDコマンド書き込み */ LOCAL void lcd_writecmd(UB data) { lcd_writenibble(LCD_DB(data >> 4)); lcd_writenibble(LCD_DB(data >> 0)); WaitUsec(LCD_CMD_DELAY); /* * 一部のコマンド(Clear Display, Cursor At Home)は、 * さらに待つ必要がある */ return; } /* LCDデータ書き込み */ LOCAL void lcd_writedat(UB data) { lcd_writenibble(LCD_DB(data >> 4) | LCD_RS); lcd_writenibble(LCD_DB(data >> 0) | LCD_RS); WaitUsec(LCD_CMD_DELAY); return; } /* LCD初期化 */ EXPORT void lcd_reset(void) { *LCD_GPIO = 0x00; WaitUsec(LCD_E_DELAY); lcd_writenibble(0x03); // Function Set WaitUsec(5000); lcd_writenibble(0x03); // Function Set WaitUsec(125); lcd_writenibble(0x03); // Function Set WaitUsec(LCD_CMD_DELAY); lcd_writenibble(0x02); // Function Set: 4bit WaitUsec(LCD_CMD_DELAY); lcd_writecmd(0x28); // Function Set: 4bit, 2lines, 5x7dots lcd_writecmd(0x08); // Display On/Off Control: all off lcd_writecmd(0x01); // Clear Display WaitUsec(2000); // *** ここは追加の待ちが必要 lcd_writecmd(0x06); // Entry Mode Set: increment, no shift lcd_writecmd(0x0c); // Display On/Off Control: display on return; } /* 文字表示位置の設定 */ EXPORT void lcd_setpos(UINT position) { /* * positionと表示位置との関係は、以下の通りとする。 * 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f * 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f */ if (position & 0x10) position |= 0x40; position &= 0x4f; lcd_writecmd(0x80 | position); return; } /* LCDへの文字列表示 */ EXPORT void lcd_putstring(UINT position, const UB *string) { while (position < 0x20 && *string) { lcd_setpos(position++); lcd_writedat(*string++); } return; } EXPORT INT usermain(void) { W i; LOCAL const UB message[] = // 0000000000000000111111111111111122222222222233333333333333333333 // 0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef "The quick brown fox jumped over a lazy dog. "; *PBDDR = LCD_E | LCD_RS | LCD_DB(0x0f); lcd_reset(); while (1) { for (i = 0; i < sizeof(message) - 0x20; i++) { lcd_putstring(0, &message[i]); *LCD_GPIO = 0x00; tk_dly_tsk(250); *LCD_GPIO = 0x0f; tk_dly_tsk(250); } } // never return }