山本ワールド
LCDモジュール(SC2004/SC1602) 4bitモードライブラリー
概要
主に{SC1602 SC2004(秋月電子通称のページに移動します)}向けのLCD液晶表示用のライブラリである。
          液晶モジュールと接続するポートはマクロで変更可能である。
          busyフラグはチェックせずソフトウェアディレイで対応しているためクロック周波数が変更された場合はディレイの調整が必要
          使用する場合はlcd2.incをインクルードしlcd2.asmをプロジェクトに追加してください
          lcd_initをコールする前に以下のポートを出力にしてください。(GNDを除く)
; 接続方法 ; PIC18F14K50 SC2004/SC1602 ; RC7 ----> DB7 ; RC6 ----> DB6 ; RC5 ----> DB5 ; RC4 ----> DB4 ; RC3 ----> E ; RC2 ----> RS ; GND R/W
プログラムの説明
ソースファイル
以下のファイルで構成されているlcd2.asm ・・・ LCD表示用ライブラリ Version 1.20 lcd2.inc ・・・ LCD表示用インクルードファイル Version 1.20lcd2.incのマクロSC1602及びSC2004のいずれかを有効にすると対応する液晶を使用することができる。
サブルーチン
以下のサブルーチンをサポート
lcd_ddramxy
液晶への表示位置をx,yで指定
          x(0~19)は文字の横位置、y(0~3)は行位置を表す。 WREGの5~6bit目にy、4~0bit目にxを指定して本サブルーチンをコールする
          マクロLCD_LOCATE_XYを使うと簡単に表示位置の作成が行えるが
          マクロ作成を前提とすれば次のlcd_ddramとマクロLCD_LOCATEの方がプログラム容量が少なくなる。プログラムで動的に行アドレスを指定する必要がある場合に使用すべきである
          使用例
;       液晶の1文字目、2行目へ移動(左上は0,0なので注意)
        LCD_LOCATE_XY 1,2
        call lcd_ddram_xy
          lcd_ddram
液晶への表示位置を液晶の表示用RAMのアドレスをWREGに格納し本サブルーチンをコールする
          アドレスの指定方法
          0行目 00h+文字横位置
          1行目 40h+文字横位置
          2行目 14h+文字横位置
          3行目 54h+文字横位置
          上記のように4行液晶を使用する場合行方向のアドレスがリニアでないため、マクロLCD_LOCATEを作成した。
          使用例
;       液晶の1文字目、2行目へ移動(左上は0,0なので注意)
        LCD_LOCATE 1,2
        call lcd_ddram
          lcd_init
液晶モジュールの初期化
lcd_disp
液晶に表示可能な文字数分(SC1602の場合16文字*2行=32byte、SC2004の場合20文字*4行目のメモリ(FSR1で指定)から液晶に文字列を転送し表示する
ソースコード
lcd2.inc
; LCDモジュール(SC1602/SC2004) 4bitモードライブラリー  Version 1.20
; File:        lcd2.inc
; Target:      PIC18F14K50 48Mhz
; アセンブラ:   Microchip MPASM(v5.51)
; 書き込み:     PICKit 3
; リリース:     2013/10/9 21:00
;   液晶タイプを指定
;        #define SC1602 1  ;  16文字*2行液晶
        #define SC2004 1   ;  20文字*4行液晶
        IFNDEF   LCD2_ASM
        EXTERN  lcd_init,lcd_disp ;    液晶初期化,液晶表示
        EXTERN  lcd_ddram,lcd_ddramxy
        EXTERN  lcd_puts
        EXTERN  wait50,wait10
        ENDIF
;   x文字目でy行にカーソルを移動させるアドレスをWREGに設定する
;   サブルーチンlcd_ddramxy用
LCD_LOCATE_XY  MACRO   x,y
        movlw   y*d'32'+x
        ENDM
;   x文字目でy行にカーソルを移動させるアドレスをWREGに設定する
;   サブルーチンlcd_ddram用
LCD_LOCATE MACRO x,y
        IF (y)==0
            movlw   (x)
        ENDIF
        IF (y)==1
            movlw   040h+(x)
        ENDIF
        IF (y)==2
            movlw   014h+(x)
        ENDIF
        IF (y)==3
            movlw   054h+(x)
        ENDIF
        ENDM
;   液晶の文字数と行数を指定
        #ifdef  SC1602
            #define LCD_CMAX d'16'
            #define LCD_RMAX  2
        #endif
        #ifdef  SC2004
            #define LCD_CMAX d'20'
            #define LCD_RMAX  4
        #endif
lcd2.asm
; 液晶モジュールSC2004(20文字*4行)表示サンプル Version 1.00
;
; File:        lcd4a.asm
; Target:      PIC18F14K50 48Mhz
; アセンブラ:   Microchip MPASM(v5.51)
; 書き込み:     PICKit 3
; リリース:     2013/10/09 21:00
;
; 20モ文字*4行液晶に対応(ただし電源ピンの配置はSC1602と異なるので注意)
; LCD_LOCATEマクロとサブルーチンlcd_ddramにより任意の位置に文字を表示可能
;
; 液晶表示例
;       01234567890123456789
;       SC2004 LCD          
;       20モジ*4ギョウ         
;       Test
;            ↓
;       PIC18F14K50
;        ROM 16K
;         RAM 768
;          Hello
        #INCLUDE <p18f14k50.inc>
        #INCLUDE "lcd2.inc"
        ; 水晶発振(12MHz) クロック分周無 PLL有効(*4)
        ; ウォッチドッグタイマ無効 低電圧プログラム書き込みモード無効
        CONFIG FOSC = HS,CPUDIV = NOCLKDIV,PLLEN=ON,WDTEN=OFF,LVP=OFF
           UDATA   ; 変数の定義 バンク0
Tcount1     RES 1      ; wait
Tcount2     RES 1      ; wait
Tcount3     RES 1      ; wait
LCD_WRITE   RES 1      ; writeデータを指定
LCD_TEMP    RES 1
Temp1       RES 1      ; サブルーチン用の変数
ARG1        RES 1      ; サブルーチン引数
BYTE2HEX_TEMP RES 1
ARGL        RES 1
ARGH        RES 1
LCD_BUF     RES LCD_CMAX*LCD_RMAX     ; 液晶用バッファ
        GLOBAL  LCD_WRITE,LCD_TEMP,ARG1,ARGL,ARGH
        GLOBAL  Temp1,BYTE2HEX_TEMP
        GLOBAL  Tcount1,Tcount2,Tcount3
; プログラムメモリのアドレスadsをTBLPTRレジスタに設定
LDTBLPTR MACRO   ads
        movlw   UPPER ads
        movwf   TBLPTRU
        movlw   HIGH ads
        movwf   TBLPTRH
        movlw   LOW ads
        movwf   TBLPTRL
        ENDM
        CODE
        ORG 0
        goto   start    ;   リセット時
start
        clrf    ANSEL   ; RC3-RC0,RA4をデジタル入力バッファに設定
        clrf    ANSELH  ; RB5-RB4,RC7-RC6をデジタル入力バッファに設定
        clrf    SLRCON  ; PORTA,PORTB,PORTCをスルーレートを標準に設定
        clrf    TRISA   ; PORTAを全部出力に設定
        movlw   0f0h
        movwf   TRISB   ; RB7-RB4を入力に設定
        clrf    TRISC   ; PORTCを全部出力に設定する
        clrf    PORTC   ; PORTCを全部0にする。
        rcall   lcd_init    ;   液晶初期化
        LDTBLPTR lcd_init_str
        lfsr    FSR0,LCD_BUF
        movlw   LCD_CMAX*LCD_RMAX
        call    prog2mem
        lfsr    FSR1,LCD_BUF
        call    lcd_disp
        movlw   d'200'      ; 10ms*200=2s
wait_loop
        call    wait10
        decfsz  Temp1       ;   Temp1から1を引き結果が0になるまで繰り返す
        bra     wait_loop
        clrf    WREG
        call    lcd_ddram
        LDTBLPTR row1_str
        lfsr    FSR0,LCD_BUF
        movlw   d'11'
        call    prog2mem
        movlw   d'11'
        lfsr    FSR1,LCD_BUF
        call    lcd_puts
        LCD_LOCATE  1,1
        call    lcd_ddram
        LDTBLPTR    row2_str
        lfsr    FSR0,LCD_BUF
        movlw   7
        call    prog2mem
        movlw   7
        lfsr    FSR1,LCD_BUF
        call    lcd_puts
        LCD_LOCATE_XY  2,2
        call    lcd_ddramxy
        LDTBLPTR    row3_str
        lfsr    FSR0,LCD_BUF
        movlw   7
        call    prog2mem
        movlw   7
        lfsr    FSR1,LCD_BUF
        call    lcd_puts
        LCD_LOCATE  3,3
        call    lcd_ddram
        LDTBLPTR    row4_str
        lfsr    FSR0,LCD_BUF
        movlw   5
        call    prog2mem
        movlw   5
        lfsr    FSR1,LCD_BUF
        call    lcd_puts
        bra     $
lcd_init_str    ;0123456789abcdef0123
        DB      "01234567890123456789"
        DB      "SC2004 LCD          "
        DB      "20モジ*4ギョウ         "
        DB      "Test                "
row1_str
        DB      "PIC18F14K50"
row2_str
        DB      "ROM 16K"
row3_str
        DB      "RAM 768"
row4_str
        DB      "Hello"
prog2mem    ; プログラムメモリからデーターメモリへコピーする TABLAT->FSR0
        movwf   Temp1
prog2mem_loop
        tblrd   *+          ;   プログラムメモリTBLPTRから読み出し後TBLPTRを+1する
        movf    TABLAT,W
        movwf   POSTINC0    ;   間接アドレッシング アドレスはアクセス後に+1される
        decfsz  Temp1       ;   Temp1から1を引き結果が0になるまで繰り返す
        bra     prog2mem_loop
        return
        END
