PICマイコンによるキャラクタLCDモジュールの駆動:アセンブラ記述

秋月電子で扱う、キャラクタ2行タイプのLCDモジュールを使って、「何かを作りたい」、「とりあえず何かを表示させて、それから発展に結び付けたい」という貴方に向けて掲げます。

LCDモジュールの扱い方はWEBや書籍でも多く取り上げられているので、シーケンスや理屈抜きで好きな文字列を表示してみましょう。

16文字2行のタイプや8文字2行タイプのモジュールでも使えます。

以下に掲げるASMは、1秒毎に「DenshiMuscat」と「www.zea.jp/audio」の表示を入れ替えるようにしています。
この部分はメインルーチン内のLOOPラベル、DISP01ルーチン、DISP02ルーチンで判るでしょう?

また、タイムディレイのサブルーチンは10MHzの発振源を基に記述しています。異なる周波数の場合は、50μSのサブルーチンのみ見直すだけでOKです。
簡単でしょ?
その他、コメントも確認しておいて下さい。

PIC16F628A、16F648Aを基に記述していますが、16Fシリーズならば何でも使えます。この場合はコンフィグビットを見直して下さい。
また、まず全てデジタルI/Oにして動作確認してみて下さい。
PIC16F628Aならば記述しているASMをビルドするだけで、直ぐにLCDモジュールを駆動できます。

当然ながらLCDの駆動に馴れたら、どんどん改変してオリジナルのプログラムへと進んでください。
改変時の注意は、LCD_BUSYルーチンでポートのI/Oを切り替えている部分だけです。

ハードウェアは最下部を参考にして下さい。

私が確認したキャラクタ2行タイプのLCDモジュールは、
SC1602BS*B(バックライトがないので薄型。コントラスト文句なし。)
SC1602BSLB(コントラスト文句なしだがSC1602BBWB-XA-Gの存在を知ってしまうと古いイメージがある。)
ACM0802C-NLW-BBH(8文字タイプで小さく、青と白のコントラストが綺麗だがSC1602BBWB-XA-Gと比較すると劣る。)
SC1602BBWB-XA-G(青と白のコントラストが綺麗でカッコイイ!見やすい!最高!膨張色の白なので文字が大きく見える。)
になります。カッコ内のコメントは4機種を比較してみた私の感想です。あまり参考にしないでね。




;***********************************************************************
;	LCDモジュールの駆動
;***********************************************************************

	LIST	P=PIC16F628A
	INCLUDE	P16F628A.INC
	ERRORLEVEL -302
	__CONFIG _BODEN_OFF & _CP_OFF & _DATA_CP_OFF & _PWRTE_ON & _WDT_OFF & _LVP_OFF & _MCLRE_ON & _HS_OSC

;***** レジスタ ************************************************************************
W_TEMP		EQU	020h	;VARIABLE USED FOR CONTEXT SAVING
STATUS_TEMP	EQU	021h	;VARIABLE USED FOR CONTEXT SAVING
PCLATH_TEMP	EQU	022h	;VARIABLE USED FOR CONTEXT SAVING

CNT_1		EQU	023h	;50uSタイマー用
CNT_2		EQU	024h	;1mSタイマー用
CNT_3		EQU	025h	;5mSタイマー用
CNT_4		EQU	026h	;15mSタイマー用
CNT_5		EQU	027h	;1Sタイマー用
LCD_D		EQU	028h	;LCD送信データレジスタ

;***** 定数定義 ***********************************************************************
#DEFINE	RW	PORTA,0
#DEFINE	E	PORTA,1
#DEFINE	RS	PORTA,2
#DEFINE	BUSY	PORTB,7

;***** プログラム ************************************************************************
	ORG	000h		;PROCESSOR RESET VECTOR
	GOTO	START		;GO TO BEGINNING OF PROGRAM

;	ORG	004h		;INTERRUPT VECTOR LOCATION
;	MOVWF	W_TEMP		;SAVE OFF CURRENT W REGISTER CONTENTS
;	MOVF	STATUS,W	;MOVE STATUS REGISTER INTO W REGISTER
;	MOVWF	STATUS_TEMP	;SAVE OFF CONTENTS OF STATUS REGISTER
;	MOVF	PCLATH,W	;MOVE PCLATH REGISTER INTO W REGISTER
;	MOVWF	PCLATH_TEMP	;SAVE OFF CONTENTS OF PCLATH REGISTER
;
;	CALL	INTR		;ISR CODE CAN GO HERE OR BE LOCATED AS A CALL SUBROUTINE ELSEWHERE
;
;	MOVF	PCLATH_TEMP,W	;RETRIEVE COPY OF PCLATH REGISTER
;	MOVWF	PCLATH		;RESTORE PRE-ISR PCLATH REGISTER CONTENTS
;	MOVF	STATUS_TEMP,W	;RETRIEVE COPY OF STATUS REGISTER
;	MOVWF	STATUS		;RESTORE PRE-ISR STATUS REGISTER CONTENTS
;	SWAPF	W_TEMP,F
;	SWAPF	W_TEMP,W	;RESTORE PRE-ISR W REGISTER CONTENTS
;	RETFIE			;RETURN FROM INTERRUPT

;***** 本プログラム ************************************************************************
START
	MOVLW	B'00000111'	;全てデジタルI/Oで使う(デバイスで異なります)
	MOVWF	CMCON		;デバイスで異なります

	BSF	STATUS,RP0	;バンク1へ
	MOVLW	000h
	MOVWF	TRISA		;RAは全て出力
	MOVLW	000h
	MOVWF	TRISB		;RBは全て出力
	BCF	STATUS,RP0	;バンク0へ戻る

	CLRF	PORTA
	CLRF	PORTB
	CALL	LCD_INI		;LCD 初期化


LOOP
	CALL	DISP01		;DISP01の内容を1秒間表示
	CALL	T_1000MS
	CALL	LCD_CL
	CALL	DISP02		;DISP02の内容を1秒間表示
	CALL	T_1000MS
	CALL	LCD_CL

	GOTO	LOOP


;***** 表示内容1 ***********************************************************
DISP01
	CALL	LCD_HP		;1行目から
	MOVLW	'D'
	CALL	LCD_SEND
	MOVLW	'e'
	CALL	LCD_SEND
	MOVLW	'n'
	CALL	LCD_SEND
	MOVLW	's'
	CALL	LCD_SEND
	MOVLW	'h'
	CALL	LCD_SEND
	MOVLW	'i'
	CALL	LCD_SEND

	CALL	LCD_2L		;2行目から
	MOVLW	'M'
	CALL	LCD_SEND
	MOVLW	'u'
	CALL	LCD_SEND
	MOVLW	's'
	CALL	LCD_SEND
	MOVLW	'c'
	CALL	LCD_SEND
	MOVLW	'a'
	CALL	LCD_SEND
	MOVLW	't'
	CALL	LCD_SEND

	RETURN

;***** 表示内容2 ***********************************************************
DISP02
	CALL	LCD_HP		;1行目から
	MOVLW	'z'
	CALL	LCD_SEND
	MOVLW	'e'
	CALL	LCD_SEND
	MOVLW	'a'
	CALL	LCD_SEND
	MOVLW	'.'
	CALL	LCD_SEND
	MOVLW	'j'
	CALL	LCD_SEND
	MOVLW	'p'
	CALL	LCD_SEND

	CALL	LCD_2L		;2行目から
	MOVLW	'/'
	CALL	LCD_SEND
	MOVLW	'a'
	CALL	LCD_SEND
	MOVLW	'u'
	CALL	LCD_SEND
	MOVLW	'd'
	CALL	LCD_SEND
	MOVLW	'i'
	CALL	LCD_SEND
	MOVLW	'o'
	CALL	LCD_SEND

	RETURN


;***** LCD:データ送信 ****************************************************
LCD_SEND
	MOVWF	LCD_D
	CALL	LCD_WAIT

	BCF	RW
	BSF	RS

	MOVF	LCD_D,W
	ANDLW	B'11110000'
	MOVWF	PORTB		;上位4bit

	BSF	E		;転送
	GOTO	$+1
;	GOTO	$+1		;発振源が20MHzを超える場合のみ使用
	BCF	E

	SWAPF	LCD_D,W
	ANDLW	B'11110000'
	MOVWF	PORTB		;下位4bit

	BSF	E		;転送
	GOTO	$+1
;	GOTO	$+1		;発振源が20MHzを超える場合のみ使用
	BCF	E

	RETURN


;***** LCD:表示クリア ****************************************************
LCD_CL
	MOVLW	001h
	CALL	LCD_COM
	RETURN

;***** LCD:1行目ホームポジション *********************************************
LCD_HP
	MOVLW	002h
	CALL	LCD_COM
	RETURN

;***** LCD:2行目ホームポジション *********************************************
LCD_2L
	MOVLW	0C0h
	CALL	LCD_COM
	RETURN

;***** LCD:表示ON ******************************************************
LCD_ON
	MOVLW	00Ch
	CALL	LCD_COM
	RETURN

;***** LCD:表示OFF ****************************************************
LCD_OFF
	MOVLW	008h
	CALL	LCD_COM
	RETURN

;***** LCD:コマンド送信 ****************************************************
LCD_COM
	MOVWF	LCD_D
	CALL	LCD_WAIT

	BCF	RW
	BCF	RS

	MOVF	LCD_D,W
	ANDLW	B'11110000'
	MOVWF	PORTB		;上位4bit

	BSF	E		;転送
	GOTO	$+1
;	GOTO	$+1		;発振源が20MHzを超える場合のみ使用
	BCF	E

	SWAPF	LCD_D,W
	ANDLW	B'11110000'
	MOVWF	PORTB		;下位4bit

	BSF	E		;転送
	GOTO	$+1
;	GOTO	$+1		;発振源が20MHzを超える場合のみ使用
	BCF	E

	RETURN


;***** LCD:初期化ルーチン ****************************************************
LCD_INI
	CALL	T_15MS
	BCF	RW
	BCF	RS
	BCF	E

	MOVLW	00FH
	ANDWF	PORTB,W
	IORLW	B'00110000'
	MOVWF	PORTB
	BSF	E		;ファンクションセット1st
	GOTO	$+1
;	GOTO	$+1		;発振源が20MHzを超える場合のみ使用
	BCF	E
	CALL	T_5MS

	MOVLW	00FH
	ANDWF	PORTB,W
	IORLW	B'00110000'
	MOVWF	PORTB
	BSF	E		;ファンクションセット2nd
	GOTO	$+1
;	GOTO	$+1		;発振源が20MHzを超える場合のみ使用
	BCF	E
	CALL	T_5MS

	MOVLW	00FH
	ANDWF	PORTB,W
	IORLW	B'00110000'
	MOVWF	PORTB
	BSF	E		;ファンクションセット3rd
	GOTO	$+1
;	GOTO	$+1		;発振源が20MHzを超える場合のみ使用
	BCF	E
	CALL	T_5MS

	MOVLW	00FH
	ANDWF	PORTB,W
	IORLW	B'00100000'	;4ビットモード
	MOVWF	PORTB
	BSF	E
	GOTO	$+1
;	GOTO	$+1		;発振源が20MHzを超える場合のみ使用
	BCF	E
	CALL	T_1MS

	MOVLW	028h		;4ビットモード,2行表示,7ドットモード
	CALL	LCD_COM
	CALL	LCD_OFF
	CALL	LCD_CL
	MOVLW	06H
	CALL	LCD_COM		;カーソルモード
	CALL	LCD_ON

	RETURN


;***** LCD:ビジー待機 ****************************************************
LCD_WAIT
	BCF	E
	BCF	RS
	BSF	RW		;ビジーフラグ読み込み

	BSF	STATUS,RP0	;バンク1へ
	MOVLW	0F0H
	MOVWF	TRISB		;RB4-7を入力
	BCF	STATUS,RP0	;バンク0へ戻る
	BSF	E
	GOTO	$+1
;	GOTO	$+1		;発振源が20MHzを超える場合のみ使用
	BTFSS	BUSY		;BUSY確認
	GOTO	LCD_WAIT_1	;OK
	BCF	E
	GOTO	$+1
;	GOTO	$+1		;発振源が20MHzを超える場合のみ使用
	BSF	E
	GOTO	$+1
;	GOTO	$+1		;発振源が20MHzを超える場合のみ使用
	BCF	E
	GOTO	LCD_WAIT

LCD_WAIT_1
	BSF	E
	GOTO	$+1
;	GOTO	$+1		;発振源が20MHzを超える場合のみ使用
	BCF	E
	BSF	STATUS,RP0	;バンク1へ
	MOVLW	000h
	MOVWF	TRISB		;RBを全て出力
	BCF	STATUS,RP0	;バンク0に戻る

	RETURN


;***** 1Sタイマー ***********************************************************************
T_1000MS
	MOVLW	043h
	MOVWF	CNT_5
T_1000MS_1
	CALL	T_15MS
	DECFSZ	CNT_5,F
	GOTO	T_1000MS_1
	RETURN

;***** 15mSタイマー ***********************************************************************
T_15MS
	MOVLW	003h
	MOVWF	CNT_4
T_15MS_1
	CALL	T_5MS
	DECFSZ	CNT_4,F
	GOTO	T_15MS_1
	RETURN

;***** 5mSタイマー ***********************************************************************
T_5MS
	MOVLW	05Eh
	MOVWF	CNT_3
T_5MS_1
	CALL	T_50US
	DECFSZ	CNT_3,F
	GOTO	T_5MS_1
	RETURN

;***** 1mSタイマー ***********************************************************************
T_1MS
	MOVLW	013h
	MOVWF	CNT_2
T_1MS_1
	CALL	T_50US
	DECFSZ	CNT_2,F
	GOTO	T_1MS_1
	RETURN

;***** 50uSタイマー ***********************************************************************
T_50US
	MOVLW	02Ah
	MOVWF	CNT_1
T_50US_1
	DECFSZ	CNT_1,F
	GOTO	T_50US_1
	RETURN


	END



ハードウェアは下図の通りです。
秋月電子で扱う、16文字2行のタイプや8文字2行タイプのモジュールが扱えますが、VddとVssのピン番号に注意して下さい。
DB0〜DB3は未接続とします。

型番によってVddとVssが逆になっている場合があります!
万が一、VddとVssを逆に接続して通電してしまうと過電流が流れて壊れる恐れがあります!



回路図集インデックスページに戻る