;*********************************************************** ; 液晶表示器(LCD)テストプログラム(2) ; (4ビットインターフェースデータ長の場合) ; ; LCDの DB7〜DB4端子は、それぞれ PIC のRB4〜RB7端子に接続 ; LCDの DB3〜DB0端子は、GNDに接続 ; LCDの RS,R/W,E端子は、それぞれ PIC のRB2,RB1,RB0端子に接続 ; ; テスト表示例は、下記の文字を表示するものとする。 ; ; SPECTRUMホームへ゜ーシ゛ ; 0123456789ABCDEF ; ;*********************************************************** LIST P=PIC16F877 ; プロセッサの種別指定 INCLUDE "P16F877.INC" ; インクルードファイルの指定 ;*********************************************************** ; 変数定義とレジスタ割付 ;*********************************************************** COUNT EQU 20H ; ループカウンタ COUNT1 EQU 21H ; ループカウンタ COUNT2 EQU 22H ; ループカウンタ COUNT3 EQU 23H ; ループカウンタ COUNT4 EQU 24H ; ループカウンタ DPDT EQU 25H ; 一時保存データ POINT EQU 26H ; テーブルポインタ RS SET 2 ; LCD レジスタ選択信号のビット番号 RW SET 1 ; LCD 読み出し/書き込み選択信号のビット番号 E SET 0 ; LCD 動作起動信号のビット番号 BUSY_F SET 7 ; LCD ビジーフラグのビット番号 ORG 0 ; プログラムの開始番地の指定 ;*********************************************************** ; 入出力ピン初期化 ;*********************************************************** BSF STATUS,RP0 ; Bank 1 へ切替 CLRF TRISB ; 全PortB 出力モードに設定 BCF STATUS,RP0 ; Bank 0 へ戻す ;*********************************************************** ; メインプログラム ;*********************************************************** START CALL LCD_INI ; 液晶表示器の初期化サブルーチンへ CALL LCD_BUSY_4 ; BFチェック MOVLW B'00001110' ; 表示ON、カーソルON CALL LCD_CMD_4 ; 液晶表示器へコマンド出力 CALL TIME1S ; WAIT(1秒) TEXT_OUT1 CLRF POINT ; テーブルポインタのリセット ROW_1 ; 1行目のテキストデータ表示 MOVF POINT,W ; テーブルポインタの値をWregへロードする(OFFSET) CALL TABLE ; テキストデータの読み込みサブルーチンへ ADDLW 0 ; Wregレジスタに0を加算する BTFSC STATUS,Z ; 演算結果がゼロかチェック(テキストデータは「0」?) GOTO TEXT_OUT2 ; テキストデータが終了のとき TEXT_OUT2へジャンプ CALL LCD_DATA_4 ; テキストデータをLCD出力するためサブルーチンへ CALL TIME1S ; WAIT(1秒) INCF POINT,F ; テーブルポインタ +1 GOTO ROW_1 ; ROW_1 のラベルへ戻り繰り返す TEXT_OUT2 INCF POINT,F ; テーブルポインタ +1 MOVLW B'11000000' ; カーソルが2行目にくるようにアドレスセット CALL LCD_CMD_4 ; 液晶表示器へコマンド出力 CALL TIME1S ; WAIT(1秒) ROW_2 ; 2行目のテキストデータ表示 MOVF POINT,W ; テーブルポインタの値をWregへロードする(OFFSET) CALL TABLE ; テキストデータの読み込みサブルーチンへ ADDLW 0 ; Wregレジスタに0を加算する BTFSC STATUS,Z ; 演算結果がゼロかチェック(テキストデータは「0」?) GOTO TEXT_CLEAR ; テキストデータが終了のとき TEXT_CLEARへジャンプ CALL LCD_DATA_4 ; テキストデータをLCD出力するためサブルーチンへ CALL TIME1S ; WAIT(1秒) INCF POINT,F ; テーブルポインタ +1 GOTO ROW_2 ; ROW_2 のラベルへ戻り繰り返す TEXT_CLEAR MOVLW B'00000001' ; 表示クリア CALL LCD_CMD_4 ; 液晶表示器へコマンド出力 CALL TIME1S ; WAIT(1秒) ; GOTO TEXT_OUT1 ; テキスト文字を繰り返し表示する TABLE ADDWF PCL,F ; PC+OFFSET DT "SPECTRUMホームページ",0 DT "0123456789ABCDEF",0 ;TABLEの定義(PC+OFFSET相当のデータを持って戻る) ;*********************************************************** ; 液晶表示器の初期化サブルーチン ;*********************************************************** LCD_INI CALL TIME10M ; WAIT(10ms) CALL TIME10M ; WAIT(10ms) 10ms×2=20msを確保(15ms以上) MOVLW B'00110000' ; ファンクションセット(8bitモードに設定) CALL LCD_CMD ; 液晶表示器へコマンド出力 CALL TIME10M ; WAIT(10ms)を確保(4.1ms以上) MOVLW B'00110000' ; ファンクションセット(8bitモードに設定) CALL LCD_CMD ; 液晶表示器へコマンド出力 CALL TIME100 ; WAIT(100μs) MOVLW B'00110000' ; ファンクションセット(8bitモードに設定) CALL LCD_CMD ; 液晶表示器へコマンド出力 CALL TIME100 ; WAIT(100μs) MOVLW B'00100000' ; ファンクションセット(4bitモードに設定) CALL LCD_CMD ; 液晶表示器へコマンド出力 CALL LCD_BUSY_4 ; ここからBFチェックができます MOVLW B'00101000' ; ファンクションセット(4bitモード,1/16デューティ,5×7ドット) CALL LCD_CMD_4 ; 液晶表示器へコマンド出力 CALL LCD_BUSY_4 ; BFチェック MOVLW B'00001000' ; 表示オフ CALL LCD_CMD_4 ; 液晶表示器へコマンド出力 CALL LCD_BUSY_4 ; BFチェック MOVLW B'00000001' ; 表示クリア CALL LCD_CMD_4 ; 液晶表示器へコマンド出力 CALL LCD_BUSY_4 ; BFチェック MOVLW B'00000110' ; エントリーモードセット ;(アドレスを+1し、カーソルは右移動,表示シフトはしない) CALL LCD_CMD_4 ; 液晶表示器へコマンド出力 RETURN ;*********************************************************** ; 液晶表示器へコマンドを出力するサブルーチン ;*********************************************************** LCD_CMD_4 ; 4ビットモード MOVWF DPDT ; データを一時保存 ANDLW 0F0H ; 下位4ビットをマスクする CALL LCD_CMD ; データ出力(コマンドコードの上位4ビット相当) SWAPF DPDT,W ; 一時保存データの上位下位入れ替え ANDLW 0F0H ; 下位4ビットをマスクする CALL LCD_CMD ; データ出力(コマンドコードの下位4ビット相当) RETURN LCD_CMD ; MOVWF PORTB ; DB4〜DB7(データバスの設定) BCF PORTB,RW ; R/W = 0 (書き込みモードに設定) BCF PORTB,RS ; RS = 0 (コマンドモードに設定) BSF PORTB,E ; E = 1 (動作起動信号の設定:Hでストローブ) NOP ; Eのパルス幅を220ns以上確保するためのダミー命令 BCF PORTB,E ; E = 0 (動作起動信号の設定:Lに戻す) RETURN ;*********************************************************** ; 液晶表示器へデータを出力するサブルーチン ;*********************************************************** LCD_DATA_4 ; 4ビットモード MOVWF DPDT ; データを一時保存 ANDLW 0F0H ; 下位4ビットをマスクする CALL LCD_DATA ; データ出力(文字コードの上位4ビット相当) SWAPF DPDT,W ; 一時保存データの上位下位入れ替え ANDLW 0F0H ; 下位4ビットをマスクする CALL LCD_DATA ; データ出力(文字コードの下位4ビット相当) RETURN LCD_DATA MOVWF PORTB ; DB4〜DB7(データバスの設定) BCF PORTB,RW ; R/W = 0 (書き込みモードに設定) BSF PORTB,RS ; RS = 1 (データモードに設定) BSF PORTB,E ; E = 1 (動作起動信号の設定:Hでストローブ) NOP ; Eのパルス幅を220ns以上確保するためのダミー命令 BCF PORTB,E ; E = 0 (動作起動信号の設定:Lに戻す) RETURN ;*********************************************************** ; ビジーチェック(BF)を行うサブルーチン ;*********************************************************** LCD_BUSY_4 BSF STATUS,RP0 ; Bank 1 へ切替 MOVLW 0F0H ; 上位4ビットを入力モードに MOVWF TRISB ; PortB を設定 BCF STATUS,RP0 ; Bank 0 へ戻す BCF PORTB,RS ; RS = 0 (コマンドモードに設定) BSF PORTB,RW ; R/W = 1 (読み込みモードに設定) BSF PORTB,E ; E = 1 (動作起動信号の設定:Hでストローブ) MOVF PORTB,W ; DDRAMからのデータ(上位4ビット相当)の読み出し BCF PORTB,E ; E = 0 (動作起動信号の設定:Lに戻す) MOVWF DPDT ; 読み込みデータをレジスタファイルに一時保存 ; BSF PORTB,E ; E = 1 (動作起動信号の設定:Hでストローブ) MOVF PORTB,W ; DDRAMからのデータ(下位4ビット相当)の読み出し BCF PORTB,E ; E = 0 (動作起動信号の設定:Lに戻す) ; BTFSC DPDT,BUSY_F ; ビジーフラグのチェック(読み込みデータの7ビット目) GOTO LCD_BUSY_4 ; BUSY_F=1のとき LCD_BUSY_4 間をループする ; BUSY_F=0のときループを抜ける BCF PORTB,RW ; R/W = 0 (書き込みモードに設定) BSF STATUS,RP0 ; Bank 1 へ切替 MOVLW 0H ; 出力モードに MOVWF TRISB ; PortB を設定 BCF STATUS,RP0 ; Bank 0 へ戻す RETURN ;*********************************************************** ;遅延サブルーチン ;*********************************************************** ;100μs遅延サブルーチン(20MHzクロック時) TIME100 MOVLW 0A5H ; 1サイクル A5H=165 MOVWF COUNT ; 1サイクル NOP ; 1サイクル 微調整ダミー NOP ; 1サイクル 微調整ダミー LOOP DECFSZ COUNT,F ; 1×(165-1)+2 = 166サイクル GOTO LOOP ; 2×(165-1) = 328サイクル RETURN ; 2サイクル ;10ms遅延サブルーチン(20MHzクロック時) TIME10M MOVLW 63H ; 1サイクル 63H=99 MOVWF COUNT1 ; 1サイクル NOP ; 1サイクル 微調整ダミー NOP ; 1サイクル 微調整ダミー LOOP1 CALL TIME100 ; (2+500)×99=49698サイクル DECFSZ COUNT1,F ; 1×(99-1)+2 = 100サイクル GOTO LOOP1 ; 2×(99-1) = 196サイクル RETURN ; 2サイクル ;1s遅延サブルーチン(20MHzクロック時) TIME1S MOVLW 63H ; 1サイクル 63H=99 MOVWF COUNT2 ; 1サイクル MOVLW 62H ; 1サイクル 62H=98 MOVWF COUNT3 ; 1サイクル MOVLW 03H ; 1サイクル 03H=3 MOVWF COUNT4 ; 1サイクル NOP ; 1サイクル 微調整ダミー LOOP2 CALL TIME10M ;(2+50000)×99=4950198サイクル DECFSZ COUNT2,F ; 1×(99-1)+2 = 100サイクル GOTO LOOP2 ; 2×(99-1) = 196サイクル LOOP3 CALL TIME100 ;(2+500)×98=49196 DECFSZ COUNT3,F ; 1×(98-1)+2 = 99サイクル GOTO LOOP3 ; 2×(98-1) = 194サイクル LOOP4 DECFSZ COUNT4,F ; 1×(3-1)+2 = 4サイクル GOTO LOOP4 ; 2×(3-1) = 4サイクル RETURN ; 2サイクル END