LCD は文字等を表示するデバイスであるが,多彩な表示制御機能が搭載されている.
LCD を利用する場合,LCD に対して制御命令や表示データ等の書き込みが頻繁に行うことになるが,それらをサブルーチンとして利用することによって効率の良いプログラムを作製することができる.
ただし,それらのサブルーチンの作成には,LCD のハードウェアおよびソフトウェア仕様を十分把握している必要があり,短時間での作成は困難である.
本実習では,PIC16F84A で利用できる,SC1602BS*B 用の各種サブルーチンをまとめ,以下に示すライブラリファイル(LCD 制御ライブラリ:LCDctrl.inc)として提供する.各サブルーチンは,ライブラリファイルをインクルード命令によりプログラム中に定義することで利用できる.
LCD 制御ライブラリに含まれるサブルーチンを以下に示す.
LCD_RESET |
リセットシーケンス |
LCD_INST |
制御命令出力 |
LCD_DATA |
表示データ出力 |
LCD_BUSY |
内部動作終了待ち |
LCD_INIT |
リセット専用命令出力 |
T1ms |
1 ms 時間待ち |
T100ms |
100 ms 時間待ち |
以下に,各サブルーチンの詳細および使用条件を示す.
◆9.1.1 使用条件 |
LCD 制御用サブルーチン“LCDctrl.inc”を利用するために必要な条件,および設定を示す.
▼ハードウェア接続 |
SC1602BS*B と PIC16F84A とは,以下に示すインターフェイス仕様を満たすように接続されていること.
信号種別 |
SC1602BS*B |
PIC16F84A |
データ信号
(データバス) |
DB7-DB0 |
PORTB の全ポート(初期値:任意) |
制御信号 |
E(STB),R/W,RS(D/1) |
PORTA の任意のポート(初期値:0) |
|
|
|
▼定数および変数設定 |
LCD 制御ライブラリのインクルード宣言より先に,以下に示す定数および変数が定義されていること.
定数 |
E |
E 端子に接続した PIC16F84A の PORTA のポート番号 |
RW |
RW 端子に接続した PIC16F84A の PORTA のポート番号 |
RS |
接続した PIC16F84A の PORTA のポート番号 |
BF |
7(SC1602BS*B の Busy フラグビット) |
変数 |
cnt_1ms |
T1ms サブルーチン用カウンタ |
cnt_1hms |
T100ms サブルーチン用カウンタ |
|
|
|
|
|
◆9.1.2 LCD_RESET(リセットシーケンス) ≪LCD_INIT,T1ms,T100ms 含む≫ |
ソフトウェアにより SC1602BS*B を初期化するサブルーチン.
入力 |
なし |
使用法 |
通信用ポートである PORTA および PORTB の設定完了後,直ちに CALL する.
;LCD reset ----------------------------
CALL LCD_RESET |
|
なお,LCD_RESET の実行には,LCD_INIT,LCD_INST,T1ms,T100ms の各サブブルーチンが必要である.それらの中で,LCD_INIT,T1ms,T100ms
の各サブブルーチンは LCD_RESET 以外では利用しないため,ここで合わせて示す.
以下に,LCD 表示仕様を満たす,2 行,5x7 文字,カーソル表示オフ,カーソル点滅オフ,カーソルインクリメント,表示シフトオフ設定となるリセットシーケンスのフローチャートとソースコードを示す.
各待ち時間は大幅に余裕を持たせて設定している.
また,初期の 8 bit モード設定時には,リセットシーケンス専用の制御命令書き込み用サブルーチンである LCD_INIT を利用する.LCD_INIT は,後に示す LCD_INST より Busy 解除待ちを除いたものであるため,詳細は LCD_INST を参考とすること.
フローチャート |
ソースコード |
 |
;----------------------------------------------
; LCD reset sequence
;----------------------------------------------
LCD_RESET
CALL T100ms
;wait >15ms
MOVLW 030H
;8bit mode set
CALL LCD_INIT
CALL T100ms ;wait >4.1ms
MOVLW 030H
;8bit mode set
CALL LCD_INIT
CALL T1ms
;wait >100us
MOVLW 030H
;8bit mode set
CALL LCD_INST
MOVLW 030H
;interface mode set
CALL LCD_INST
MOVLW 038H
;function set
CALL LCD_INST
MOVLW 008H
;display off
CALL LCD_INST
MOVLW 001H
;display clear
CALL LCD_INST
MOVLW 006H
;entry mode set
CALL LCD_INST
RETURN
; |
 |
;----------------------------------------------
; LCD initialize code set [input:Wreg]
;----------------------------------------------LCD_INIT
MOVWF PORTB
BCF PORTA,RS ;RS=0
BCF PORTA,RW
;R/W=0
BSF PORTA,E
;E=1
BCF PORTA,E
;E=0
RETURN
; |
 |
;----------------------------------------------
; 1ms timer (1cycle=1us) 1001cycle(inc CALL)
;----------------------------------------------
T1ms
MOVLW 0F9H
;1cycle 249
MOVWF cnt_1ms
;1cycle
L_T1ms
NOP
;1cycle
DECFSZ cnt_1ms,F
;1(2atSkip)cycle
GOTO L_T1ms ;2cycle
RETURN
; |
 |
;----------------------------------------------
; 100ms timer (1sycle=1us) 100405cycle(inc CALL)
;----------------------------------------------
T100ms
MOVLW 064H
;1cycle 100
MOVWF cnt_1hms
;1cycle
L_T100ms
CALL T1ms
;1001cycle
DECFSZ cnt_1hms,F ;1(2atSkip)cycle
GOTO L_T100ms
;2cycle
RETURN
; |
|
|
◆9.1.3 LCD_BUSY(内部動作終了待ち) |
SC1602BS*B の内部動作が終了するまで復帰しないサブルーチン.なお LCD_BUSYは,LCD_INIT,LCD_INST,LCD_DATA
より呼び出されるサブルーチンであり,通常はユーザが直接 CALL する必要はない.
SC1602BS*B では,制御命令や表示データの入力に対する内部動作に 40 us〜1.64 ms 程度の処理時間を要し,この間は次の命令を受け付けることができない.
したがって,何らかの方法で内部動作が完了したことを知る必要があるが,内部動作の状態は“Busy フラグ/アドレス読み出し命令“によってBusy フラグ(BF ビット)を読み出すことによって知ることができる.
SC1602BS*B より Busy フラグを入力する場合のタイミングチャートを以下に示す.
 |
|
注) |
PIC16F84A の命令クロックは最高でも 20/4=5 MHz であるため,1 サイクルは 200 ns 以上である.
したがって,信号を切り替える順番さえ守れば必然的に書き込みのタイミング条件を満たすことになる. |
PIC16F84A のデータバス(PORTB)を一時的に入力モードに設定し,RS,R/W,E 信号を規定のタイミングで操作することにより,Busy フラグを読み出すことができる.なお,Busy フラグは DB7 ビットに割り当てられている.
SC1602BS*B の内部動作状態とBusyフラグとの関係を以下に示す.
内部動作状態 |
動作中 |
動作完了 |
Busy フラグ |
1 |
0 |
タイミングチャートに基づき,内部動作完了まで(Busy フラグ(BF)が’0’になるまで)復帰しないよう作成した
LCD_BUSY のフローチャートとソースコードを示す.
フローチャート |
ソースコード |
 |
;----------------------------------------------
; LCD Busy clear wait
;----------------------------------------------
LCD_BUSY
;data bus(PORTB) all input set ---------
BSF STATUS,RP0
;set Bank1
MOVLW 0FFH
MOVWF TRISB
BCF STATUS,RP0
;
;BUSY check ----------------------------
BCF PORTA,RS
;RS=0
BSF PORTA,RW
;R/W=1
L_BUSY
BSF PORTA,E
;E=1
BCF PORTA,E
;E=0
BTFSC PORTB,BF
GOTO L_BUSY
;
;data bus(PORTB) all output set --------
BSF STATUS,RP0
;set Bank1
CLRF TRISB
BCF STATUS,RP0
RETURN
; |
|
|
◆9.1.4 LCD_INST(制御命令出力) |
SC1602BS*B へ制御命令を出力するサブルーチン.
入力 |
Wreg |
使用法 |
Wreg に制御命令コードを格納後に CALL する.
MOVLW 008H
;display off
CALL LCD_INST |
|
なお,LCD_INST の実行には,LCD_BUSY サブブルーチンが必要である.
SC1602BS*B へ制御命令を出力する場合のタイミングチャートを以下に示す.

データを DB0-7 へ設定後,RS,R/W,E 信号を規定のタイミングで操作することにより,制御命令を書き込むことができる.
タイミングチャートに基づき作成した LCD_INST のフローチャートとソースコードを示す.
なお,命令出力後は Busy 状態をが解除されるまで待って復帰する.
フローチャート |
ソースコード |
 |
;----------------------------------------------
; LCD instruction code set [input:Wreg]
;----------------------------------------------
LCD_INST
MOVWF PORTB
BCF PORTA,RS
;RS=0
BCF PORTA,RW ;R/W=0
BSF PORTA,E
;E=1
BCF PORTA,E
;E=0
CALL LCD_BUSY
;busy clear wait
RETURN
; |
|
|
◆9.1.5 LCD_DATA(表示データ出力) |
SC1602BS*B へ表示データを出力するサブルーチン.
入力 |
Wreg |
使用法 |
Wreg に表示データコードを格納後に CALL する.
MOVLW 031H
;'1'
CALL LCD_DATA |
|
なお,LCD_DATA の実行には,LCD_BUSY サブブルーチンが必要である.
SC1602BS*B へ表示データを出力する場合のタイミングチャートを以下に示す.

データを DB0-7 へ設定後,RS,R/W,E 信号を規定のタイミングで操作することにより,表示データを書き込むことができる.
タイミングチャートに基づき作成した LCD_DATA のフローチャートとソースコードを示す.
なお,命令出力後は Busy 状態をが解除されるまで待って復帰する.
フローチャート |
ソースコード |
 |
;----------------------------------------------
; LCD display data code set [in:Wreg]
;----------------------------------------------
LCD_DATA
MOVWF PORTB
BSF PORTA,RS
;RS=1
BCF PORTA,RW
;R/W=0
BSF PORTA,E
;E=1
BCF PORTA,E
;E=0
CALL LCD_BUSY
;busy clear wait
RETURN
; |
|
|
◆9.1.6 利用例 |
LCD 制御ライブラリ(LCDctrl.inc)を利用した簡単な LCD 表示プログラム例を示す.

ソースコード |
;***********************************************************
; step09 program for PIC16F84A
; step09.asm, H. OSADA, Jan. 2005
;***********************************************************
;
;=================================================
; definitions
;=================================================
;- hardware -----------------------------------
LIST P=PIC16F84A
#INCLUDE "P16F84A.INC"
;
__CONFIG _HS_OSC & _WDT_OFF & _PWRTE_ON
& _CP_OFF
;
;- constant label -----------------------------
E EQU 000H ;LCD
E pin
RW EQU 001H ;LCD
R/W pin
RS EQU 002H ;LCD
RS pin
BF EQU 007H ;LCD
Busy flag bit
;
;- file register ------------------------------
CBLOCK 0CH
cnt_1ms
;1ms counter
cnt_1hms
;100ms counter
ENDC
;
;=================================================
; run start
;=================================================
;- reset start --------------------------------
ORG 0
GOTO INIT
;
;- interrupt start ----------------------------
ORG 4
GOTO ISR
;
;- initialize ---------------------------------
INIT
BSF STATUS,RP0
;set Bank1
MOVLW 018H
;RA0-2:out, RA3-4:in
MOVWF TRISA
CLRF TRISB
;RB0-7:out
BCF STATUS,RP0
;set Bank0
;
CALL LCD_RESET ;LCD reset
MOVLW 00CH
;disp on, cursor off, blink off
CALL LCD_INST
;
;=================================================
; main routine
;=================================================
MAIN
MOVLW 080H
;pos line:1st,column:1st
CALL LCD_INST
;
MOVLW 'S'
;print 'S'
CALL LCD_DATA
MOVLW 't'
;print 't'
CALL LCD_DATA
MOVLW 'e'
;print 'e'
CALL LCD_DATA
MOVLW 'p'
;print 'p'
CALL LCD_DATA
MOVLW '0'
;print '0'
CALL LCD_DATA
MOVLW 039H
;print '9'
CALL LCD_DATA
;
LOOP
GOTO LOOP
;
;=================================================
; interrupt service routine
;=================================================
ISR
;** procedure
;
;=================================================
; subroutine
;=================================================
#INCLUDE "LCDctrl.inc"
;
;***********************************************************
END |
|
|
|
|