LCDキャラクターディスプレイ / 4ビットモード

pp.396-398
今度は4ビットモードを試す。上位ニブル、下位ニブルの順に書き込む。
f:id:ti-nspire:20200611052000p:plain:h300 f:id:ti-nspire:20200611052028j:plain:h300

.EQU RS = PB0
.EQU EN = PB2

; スタックポインタの初期化マクロ
.MACRO INITSTACK
    LDI R20, HIGH(RAMEND)
    OUT SPH, R20
    LDI R20, LOW(RAMEND)
    OUT SPL, R20
.ENDMACRO

INITSTACK

; PD7:4をLCDのD7:4に接続して命令とデータとを書き込むことにする。
LDI R16, 0xF0
OUT DDRD, R16

; PB0からRS信号を、PB2からEN信号を出すことにする。
SBI DDRB, RS
SBI DDRB, EN

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, 'ハ'
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, 'w'
CALL DATA_W
LDI R16, 'o'
CALL DATA_W
LDI R16, 'r'
CALL DATA_W
LDI R16, 'l'
CALL DATA_W
LDI R16, 'd'
CALL DATA_W

HERE:
    RJMP HERE

NIBBLE_W:
    ANDI R27, 0xF0
    OUT PORTD, R27
    SBI PORTB, EN
    CALL SHORT_DELAY
    CBI PORTB, EN
    CALL DELAY_100us
    RET

NIBBLES_W:
    MOV R27, R16
    CALL NIBBLE_W
    MOV R27, R16
    SWAP R27
    CALL NIBBLE_W
    RET

; 命令を書き込むためのサブルーチン
COMMAND_W:
    CBI PORTB, RS
    CALL NIBBLES_W
    RET

; データを書き込むためのサブルーチン
DATA_W:
    SBI PORTB, RS
    CALL NIBBLES_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