LCDキャラクターディスプレイ / 4ビットモード / 1ポートだけ使う
pp.399-401
4ビットモードなら結局全部で6本つなげばいいだけなので1ポートでまかなえる。上位ニブルにデータを、下位ニブルに制御信号を割り振ることにする。制御信号(RS、EN)をいじるときはデータ(D7:4)には触らず、and vice versa。
.EQU RS = PD0 .EQU EN = PD2 ; スタックポインタの初期化マクロ .MACRO INITSTACK LDI R16, HIGH(RAMEND) OUT SPH, R16 LDI R16, LOW(RAMEND) OUT SPL, R16 .ENDMACRO INITSTACK ; PD7:4をLCDのD7:4に接続して命令とデータとを書き込むことにする。 ; PD0からRS信号を、PD2からEN信号を出すことにする。 LDI R16, 0xF0 | (1 << RS) | (1 << EN) OUT DDRD, R16 LDI R16, 0b00110011 CALL COMMAND_W CALL DELAY_2ms LDI R16, 0b00110010 CALL COMMAND_W CALL DELAY_2ms LDI R16, 0b00101000 CALL COMMAND_W CALL DELAY_2ms LDI R16, 0b1111 CALL COMMAND_W LDI R16, 0b0001 CALL COMMAND_W CALL DELAY_2ms LDI R16, 0b0110 CALL COMMAND_W LDI R16, 0xA2 ;「 CALL DATA_W LDI R16, 'ハ' CALL DATA_W LDI R16, 'ロ' CALL DATA_W LDI R16, 'ー' CALL DATA_W LDI R16, '、' CALL DATA_W LDI R16, 'ワ' CALL DATA_W LDI R16, 'ー' CALL DATA_W LDI R16, 'ル' CALL DATA_W LDI R16, 'ト' CALL DATA_W LDI R16, '゙' CALL DATA_W LDI R16, 0xA3 ; 」 CALL DATA_W LDI R16, (1 << 7) | 0xC0 ; 2行目1文字目に移動して、 CALL COMMAND_W LDI R16, '"' CALL DATA_W LDI R16, 'コ' CALL DATA_W LDI R16, '゙' CALL DATA_W LDI R16, 'チ' CALL DATA_W LDI R16, 'ヒ' CALL DATA_W LDI R16, '゚' CALL DATA_W LDI R16, 'タ' CALL DATA_W LDI R16, 'リ' CALL DATA_W LDI R16, '1' CALL DATA_W LDI R16, '0' CALL DATA_W LDI R16, '0' CALL DATA_W LDI R16, 0xFB ; 万 CALL DATA_W LDI R16, 0xFC ; 円 CALL DATA_W LDI R16, '"' CALL DATA_W MAIN: RJMP MAIN ; 上位ニブルを書き込むためのサブルーチン HI_NIBBLE_W: ANDI R27, 0xF0 IN R26, PORTD ; ポートDの下位ニブル(制御線)に触りたくないので一旦全部取り込んで、 ANDI R26, 0x0F OR R26, R27 ; 下位ニブルは変えないまま、 OUT PORTD, R26 ; またポートDに書き込んで、 SBI PORTD, EN CALL SHORT_DELAY CBI PORTD, EN ; そのままLCDへ書き込む。 CALL DELAY_100us RET ; 1バイトを書き込むためのサブルーチン BYTE_W: MOV R27, R16 CALL HI_NIBBLE_W MOV R27, R16 SWAP R27 CALL HI_NIBBLE_W RET ; 命令を書き込むためのサブルーチン COMMAND_W: CBI PORTD, RS CALL BYTE_W RET ; データを書き込むためのサブルーチン DATA_W: SBI PORTD, RS CALL BYTE_W RET SHORT_DELAY: RET ; 4 DELAY_100us: PUSH R17 ; 2 LDI R17 , 200 ; 1 DR0: RCALL SHORT_DELAY ; 3 DEC R17 ; 1W BRNE DR0 ; falseで1, trueで2 POP R17 ; 2 RET ; 4 DELAY_2ms: PUSH R17 ; 2 LDI R17, 20 ; 1 LDR0: RCALL DELAY_100us ; 3 DEC R17 ; 1 BRNE LDR0 ; falseで1, trueで2 POP R17 ; 2 RET ; 4