第13週プログラム 
;LCD表示器 SC1602BS*B
;*********************************************
        LIST        P=PIC16F84    ;
        INCLUDE     "P16f84.inc"  ;標準ヘッダ定義ファイル
        __CONFIG    _HS_OSC & _PWRTE_ON & _WDT_OFF
;*********************************

TIMCNT  EQU     0CH             ;タイマ用カウンタ
TIM5CNT EQU     0DH
TIM1CNT EQU     0EH
LCDDT   EQU     0FH             ;LCD表示データ格納
LCDINST EQU     010H            ;LCDインストラクション格納

        ORG     0               ;Reset Start
;***********************
;  メインルーチン
;***********************

MAIN                            ;Initialize        
;ポート初期化
        BSF     STATUS,RP0      ;バンク1へ切替
        CLRF    TRISA           ;ポートAを出力モードに設定
        CLRF    TRISB           ;ポートBを出力モードに設定
        BCF     STATUS,RP0      ;バンク0に戻す     
        MOVLW   B'00000000'     ;初期出力
        MOVWF   PORTA
        MOVLW   B'00000000'     ;初期出力
        MOVWF   PORTB

;LCD初期化
        CALL    TIM5            ;まず15msec以上待ち(TIM5は約5msec)
        CALL    TIM5
        CALL    TIM5
        CALL    TIM5 
        MOVLW   030H
        MOVWF   PORTB
        BCF     PORTA,1         ;R/WをWに
        BCF     PORTA,2         ;RSをインストラクションに
        BSF     PORTA,0         ;E
        BCF     PORTA,0

        CALL    TIM5            ;4.1msec以上待ち
        MOVLW   030H
        MOVWF   PORTB
        BCF     PORTA,1         ;R/WをWに
        BCF     PORTA,2         ;RSをインストラクションに
        BSF     PORTA,0         ;E
        BCF     PORTA,0

        CALL    TIM04           ;100μsec以上待ち(TIM04は約0.4msec)
        MOVLW   030H
        MOVWF   PORTB
        BCF     PORTA,1         ;R/WをWに
        BCF     PORTA,2         ;RSをインストラクションに
        BSF     PORTA,0         ;E
        BCF     PORTA,0

        CALL    TIM04
        MOVLW   038H            ;Function Set 8ビット 2行 5×7ドット
        CALL    LCDCMD
        MOVLW   01H             ;表示クリア
        CALL    LCDCMD        
        MOVLW   06H             ;エントリーモード                
        CALL    LCDCMD
        MOVLW   0CH             ;表示ON
        CALL    LCDCMD
        
;文字書き込み(いくらなんでもちょっと能なしすぎるプログラムですけど(^^; )
;Yamatonmbo   Kimura
;Kimura   と Yamatombo を交互に表示
CHW
        CALL    LCDCLR          ;表示クリア
        CALL    TOMBO
        CALL    LCD2L           ;2行目へ
        CALL    KIMURA
        CALL    TIM1S
        CALL    LCDCLR
        CALL    KIMURA
        CALL    LCD2L
        CALL    TOMBO           
        CALL    TIM1S
        GOTO    CHW


;***********************
;サブルーチン
;***********************
TOMBO                           ;表示Yamatombo
        MOVLW   'Y'
        CALL    LCDDTW
        MOVLW   'a'
        CALL    LCDDTW
        MOVLW   'm'
        CALL    LCDDTW
        MOVLW   'a'
        CALL    LCDDTW
        MOVLW   't'
        CALL    LCDDTW
        MOVLW   'o'
        CALL    LCDDTW
        MOVLW   'm'
        CALL    LCDDTW
        MOVLW   'b'
        CALL    LCDDTW
        MOVLW   'o'
        CALL    LCDDTW
        RETURN
KIMURA
        MOVLW   'K'            ;表示Kimura
        CALL    LCDDTW
        MOVLW   'i'
        CALL    LCDDTW
        MOVLW   'm'
        CALL    LCDDTW
        MOVLW   'u'
        CALL    LCDDTW
        MOVLW   'r'
        CALL    LCDDTW
        MOVLW   'a'
        CALL    LCDDTW
        RETURN
        

;LCDデータ書き込み
LCDDTW                          
                                ;Wに書き込まれたデータ(1文字)を表示
        MOVWF   PORTB
        BCF     PORTA,1         ;R/WをW
        BSF     PORTA,2         ;RSをデータに
        BSF     PORTA,0         ;E
        BCF     PORTA,0
        CALL    LCDBUSY         ;BUSYチェック
        RETURN

;LCDインストラクション書き込み
LCDCMD                          
                                ;Wレジスタに書き込まれたコマンドをLCDへ
        MOVWF   PORTB
        BCF     PORTA,1         ;R/WをW
        BCF     PORTA,2         ;RSをインストラクションに
        BSF     PORTA,0         ;E
        BCF     PORTA,0
        CALL    LCDBUSY         ;BUSYチェック
        RETURN

;LCD表示クリア
LCDCLR                          
        MOVLW   01H
        CALL    LCDCMD
        RETURN

;2行目へ移動
;◎データシートによると1行目と2行目はアドレスが連続していないで
;2行目の第1文字目は40(H)番地らしい
;(b'1*******'が表示アドレス書き込み  *******を1000000として2行目先頭指令)
LCD2L                           
        MOVLW   0C0H
        CALL    LCDCMD
        RETURN

;LCD BUSYチェック
LCDBUSY                         
                                ;◎やっかいなことにいちいちPORTBを入力に変える
        BSF     STATUS,RP0      ;バンク1へ切替
        MOVLW   0FFH            ;ポートBを入力モードに設定
        MOVWF   TRISB
        BCF     STATUS,RP0      ;バンク0に戻す

        BCF     PORTA,2         ;RSをインストラクションに
        BSF     PORTA,1         ;R/WをR
        BSF     PORTA,0         ;E
        BCF     PORTA,0
        MOVF    PORTB,W
        MOVWF   LCDINST
        BTFSC   LCDINST,7       ;BUSYフラグチェック
        GOTO    LCDBUSY

        BCF     PORTA,1         ;R/WをWに戻しておく
        BSF     STATUS,RP0      ;バンク1へ切替
        CLRF    TRISB           ;ポートBを出力モードに設定
        BCF     STATUS,RP0      ;バンク0に戻す
        RETURN

;タイマ        
TIM04                           ;約0.4mSECタイマ
        MOVLW   0FFH
        MOVWF   TIMCNT
TIMLP   NOP
        DECFSZ  TIMCNT,F
        GOTO    TIMLP
        RETURN
TIM5                            ;約5msecタイマ
        MOVLW   0DH
        MOVWF   TIM5CNT
TIM5LP  CALL    TIM04
        DECFSZ  TIM5CNT,F
        GOTO    TIM5LP
        RETURN
TIM1S                          ;約1secタイマ
        MOVLW   0C8H
        MOVWF   TIM1CNT
TIM1SLP CALL    TIM5
        DECFSZ  TIM1CNT,F
        GOTO    TIM1SLP
        RETURN
        
        END