;******************************************************************************************
;  シリアルLCDボード サンプルプログラム
;    Project      :
;    Program name : 
;    Creater      :
;    Create date  :  Version 1    H17.07.19  
;    History      :  
;*******************************************************************************************
;  (0)Display
;     2行16桁 LCD Board
;  (1)Descript I/O 
;     B0～B7  : LCD (D0～D7) 
;     A0      : LCD (RW)
;     A1      : LCD (RS)
;     A2      : LCD (E)
;     A3      : Serial Port(RX)
;     A4      : Serial Port(TX)
;     A5      : None
;     A6      : Mode SW
;     A7      : Mode SW
;*******************************************************************************************

	LIST	P=PIC16F88,ST=OFF,R=DEC
	INCLUDE	"P16F88.inc"	
	__CONFIG _CONFIG1 , _CP_OFF & _CCP1_RB0 & _DEBUG_OFF & _WRT_PROTECT_OFF & _CPD_OFF & _LVP_OFF & _BODEN_OFF & _MCLR_OFF & _PWRTE_OFF & _WDT_OFF & _INTRC_IO
;	__CONFIG _CONFIG1 , _CP_OFF & _CCP1_RB0 & _DEBUG_OFF & _WRT_PROTECT_OFF & _CPD_OFF & _LVP_OFF & _BODEN_OFF & _MCLR_OFF & _PWRTE_OFF & _WDT_OFF & _HS_OSC
	__CONFIG _CONFIG2 , _IESO_OFF & _FCMEN_OFF
;
LCDLN	EQU	20H
LCDPOS	EQU	21H
WP3A	EQU	22H
WP1A	EQU	23H
WP001A	EQU	24H
WP001B	EQU	25H
WT1A	EQU	26H
IODAT	EQU	27H
SENDLP	EQU	28H
SENDWAT	EQU	29H
RECLP	EQU	2AH
RECWAT	EQU	2BH
CNT	EQU	2CH
CNT1	EQU	2DH
;
	ORG	0
	GOTO	START
	ORG	4
	GOTO	START
START
; Bank0での設定
	BANKSEL	PORTA	; PortAのBankを選択する(Bank0)
	CLRF	PORTA	; PortAの初期化(Bank0)
	CLRF	PORTB	; PortBの初期化(Bank0,1,2,3)

; Bank1での設定
	BANKSEL	ANSEL	;(Bank1)
	MOVLW	B'01111110'	;内部OSC選択,内部OSCに8MHzを選択
	MOVWF	OSCCON
	MOVLW	B'00000000'	; 全てをDegitalに設定
	MOVWF	ANSEL	; Degital Inputに設定(Bank1)
	MOVLW	B'11001000'
	MOVWF	TRISA	; PortAのI/O設定(Bank1)
	MOVLW	B'00000000'
	MOVWF	TRISB	; PortBのI/O設定(Bank1)
; Bank0に戻す
	BANKSEL	PORTA	; PortAのBankを選択する(Bank0)

	CALL	LCDINI
	CALL	LCDINIP1

	CALL	DEMO1
MAIN
	CALL	TRMMOD
	GOTO	MAIN
;*******************************************************************************************
;   関数名    : DEMO1　　　　
;   機能      : LCD デモ 
;   引数      :
;   変数      :
;   LCD設定   : LCD DB(0-7)  ;  RB(0-7)
;               LCD R/W      ;  RA0 
;               LCD RS       ;  RA1 
;               LCD E        ;  RA2  
;   注意      :
;*******************************************************************************************
DEMO1
; 1行目(16文字)
	MOVLW	'I'
	CALL	LCDWRT
	MOVLW	'n'
	CALL	LCDWRT
	MOVLW	'i'
	CALL	LCDWRT
	MOVLW	't'
	CALL	LCDWRT
	MOVLW	'i'
	CALL	LCDWRT
	MOVLW	'a'
	CALL	LCDWRT
	MOVLW	'l'
	CALL	LCDWRT
	MOVLW	'i'
	CALL	LCDWRT
	MOVLW	'z'
	CALL	LCDWRT
	MOVLW	'e'
	CALL	LCDWRT
	MOVLW	'd'
	CALL	LCDWRT
	MOVLW	' '
	CALL	LCDWRT
	MOVLW	'L'
	CALL	LCDWRT
	MOVLW	'C'
	CALL	LCDWRT
	MOVLW	'D'
	CALL	LCDWRT
	MOVLW	' '
	CALL	LCDWRT

; 2行目(16文字)
;	CALL	LCDCR	; 2行目設定
	CALL	LCDINIP2
	RETURN
;*******************************************************************************************
;   関数名    : TRMMOD　　　　
;   機能      : ターミナルモード 
;   引数      : なし
;   変数      : なし　
;   注意      :
;*******************************************************************************************	
TRMMOD
	CALL	REC
	MOVF	IODAT,W
	XORLW	H'80'	; '80'なら1行目入力
	BTFSS	STATUS,Z
	GOTO	TRMMOD1
	CALL	LCDINIP1
	CALL	SEND
	RETURN
TRMMOD1
	MOVF	IODAT,W
	XORLW	H'81'	; '81'なら2行目入力
	BTFSS	STATUS,Z
	GOTO	TRMMOD2
	CALL	LCDINIP2
	CALL	SEND
	RETURN
TRMMOD2
	CALL	LCDSETPOS	
	MOVF	IODAT,W
	CALL	LCDWRT
	CALL	SEND
	RETURN
;*******************************************************************************************
;   関数名    : LCDINI　　　　
;   機能      : LCD 初期化 
;   引数      :
;   変数      :
;   LCD設定   : LCD DB(0-7)  ;  RB(0-7)
;               LCD R/W      ;  RA0 
;               LCD RS       ;  RA1 
;               LCD E        ;  RA2  
;   注意      :
;*******************************************************************************************
LCDINI
;  1.15mS以上 Wait
	CALL	WATP1
;  2.設定(STEP1)
;    1)DB(0011****)
	MOVLW	B'00110000'
	MOVWF	PORTB
;    2)R/WをWにする
	BCF	PORTA,0
;    3)RSをインストラクションにする
	BCF	PORTA,1
;    4)Enable_Signal
	BSF	PORTA,2
	CALL	WATP001
	CALL	WATP001
	BCF	PORTA,2
;  3.4.1mS以上 Wait
	CALL	WATP1
;  4.設定(STEP2)
;    1)DB(0011****)
	MOVLW	B'00110000'
	MOVWF	PORTB
;    2)R/WをWにする
	BCF	PORTA,0
;    3)RSをインストラクションにする
	BCF	PORTA,1
;    4)Enable_Signal
	BSF	PORTA,2
	CALL	WATP001
	CALL	WATP001
	BCF	PORTA,2
;  5.100μS以上 Wait
	CALL	WATP001
;  6.設定(STEP2)
;    1)DB(0011****)
	MOVLW	B'00110000'
	MOVWF	PORTB
;    2)R/WをWにする
	BCF	PORTA,0
;    3)RSをインストラクションにする
	BCF	PORTA,1
;    4)Enable_Signal
	BSF	PORTA,2
	CALL	WATP001
	CALL	WATP001
	BCF	PORTA,2
;  7.Function_SET
	CALL	WATP1
;    1)Function_SET(8bit_bas/2行/5*7Dot)
	MOVLW	B'00111000'
	CALL	LCDCMD
;    2)Clear_Display
	MOVLW	B'00000001'
	CALL	LCDCMD
;    3)Entry_MODE_SET(Incliment/Shift)
	MOVLW	B'00000110'
	CALL	LCDCMD
;    4)Display_ON
	MOVLW	B'00001100'
	CALL	LCDCMD
;    5)Display_Clear 
;	CALL	LCDCLR
;
	RETURN
;*******************************************************************************************
;   関数名    : LCDINIP1　　　
;   機能      : LCDの表示位置を１行目の先頭位置にする 
;   引数      : LCDLN  LCD表示行制御(0:1行目, 1:2行目)
;               LCDPOS LCD表示行制御(表示文字数)なし
;   変数      :
;   注意      :
;*******************************************************************************************
LCDINIP1
	MOVLW	H'01'
	MOVWF	LCDLN		; LCD表示行制御(0:1行目, 1:2行目)
	MOVLW	H'0F'		; LCD表示行制御
	MOVWF	LCDPOS		; LCD表示行制御(表示文字数)
	RETURN
;*******************************************************************************************
;   関数名    : LCDINIP2　　　
;   機能      : LCDの表示位置を２行目の先頭位置にする 
;   引数      : LCDLN  LCD表示行制御(0:1行目, 1:2行目)
;               LCDPOS LCD表示行制御(表示文字数)なし
;   変数      :
;   注意      :
;*******************************************************************************************
LCDINIP2
	CLRF	LCDLN		; LCD表示行制御(0:1行目, 1:2行目)
	MOVLW	H'0F'		; LCD表示行制御
	MOVWF	LCDPOS		; LCD表示行制御(表示文字数)
	RETURN
;*******************************************************************************************
;   関数名    : LCDSETPOS　　　　
;   機能      : LCDの表示位置を制御 
;   引数      : LCDLN  LCD表示行制御(0:1行目, 1:2行目)
;               LCDPOS LCD表示行制御(表示文字数)なし
;   変数      :
;   注意      :
;*******************************************************************************************
LCDSETPOS
	MOVLW	H'01'
	ADDWF	LCDPOS,F
	MOVF	LCDPOS,W
	XORLW	H'10'
	BTFSS	STATUS,Z
	RETURN
	CLRF	LCDPOS
	MOVF	LCDLN,W
	XORLW	H'00'
	BTFSS	STATUS,Z
	GOTO	LCDSETPOS1
	MOVLW	H'01'	
	MOVWF	LCDLN
	CALL	LCDCR
	RETURN
LCDSETPOS1
	CLRF	LCDLN
	CALL	LCDCLR
	RETURN

;*******************************************************************************************
;   関数名    : LCDCR　　　　
;   機能      : LCDの２行目を入力 
;   引数      : なし
;   変数      :
;   注意      :
;*******************************************************************************************
LCDCR
	MOVLW	H'C0'
	CALL	LCDCMD
	RETURN				
;*******************************************************************************************
;   関数名    : LCDCLR　　　　
;   機能      : LCD 表示クリア(LCDの1行目を入力) 
;   引数      : なし
;   変数      :
;   注意      :
;*******************************************************************************************
LCDCLR
	MOVLW	B'00000001'
	CALL	LCDCMD
	RETURN		
;*******************************************************************************************
;   関数名    : LCDCMD　　　　
;   機能      : LCD制御コマンド実行 
;   引数      : W レジスタ
;   変数      : なし
;   LCD設定   : LCD DB(0-7)  ;  RB(0-7)
;               LCD R/W      ;  RA0 
;               LCD RS       ;  RA1 
;               LCD E        ;  RA2  
;   注意      : 
;*******************************************************************************************
LCDCMD
;    1)PORTDに出力
	MOVWF	PORTB
;    2)R/WをWにする
	BCF	PORTA,0
;    3)RSをインストラクションにする
	BCF	PORTA,1
;    4)Enable_Signal
	BSF	PORTA,2
	CALL	WATP001
	CALL	WATP001
	BCF	PORTA,2
;    5)WAIT
	CALL	LCDBSY 
	RETURN

;*******************************************************************************************
;   関数名    : LCDBSY　　　　
;   機能      : LCD Busyチェック 
;   引数      : なし
;   変数      : なし
;   LCD設定   : LCD DB(0-7)  ;  RB(0-7)
;               LCD R/W      ;  RA0 
;               LCD RS       ;  RA1 
;               LCD E        ;  RA2  
;   注意      : 
;*******************************************************************************************
LCDBSY
;    1)PortDを入力に変更
	BANKSEL	ANSEL	; ANSELのBankを選択する(Bank1)
	MOVLW	B'11111111'
	MOVWF	TRISB
	BANKSEL	PORTA	; PortAのBankを選択する(Bank0 ※PortBは0,2,3にあるので指定注意)
LCDBSY1
;    2)R/WをWにする
	BSF	PORTA,0
;    3)RSをインストラクションにする
	BCF	PORTA,1
;    4)Enable_Signal
	BSF	PORTA,2
	CALL	WATP001
	CALL	WATP001
	BCF	PORTA,2
;    5)Bisy チェック
	BTFSC   PORTB,7
	GOTO	LCDBSY1
;    6)戻す
	BCF	PORTA,0
	BANKSEL	ANSEL	; ANSELのBankを選択する(Bank1)
	MOVLW	B'00000000'
	MOVWF	TRISB
	BANKSEL	PORTA	; PortAのBankを選択する(Bank0 ※PortBは0,2,3にあるので指定注意)
	RETURN
;*******************************************************************************************
;   関数名    : LCDWRT　　　　
;   機能      : LCD文字表示 
;   引数      : W レジスタ
;   変数      : なし
;   LCD設定   : LCD DB(0-7)  ;  RB(0-7)
;               LCD R/W      ;  RA0 
;               LCD RS       ;  RA1 
;               LCD E        ;  RA2  
;   注意      : 
;*******************************************************************************************
LCDWRT
;    1)PORTDに出力
	MOVWF	PORTB
;    2)R/WをWにする
	BCF	PORTA,0
;    3)RSをインストラクションにする
	BSF	PORTA,1
;    4)Enable_Signal
	BSF	PORTA,2
	CALL	WATP001
	BCF	PORTA,2
;    3)WAIT
	CALL	WATP001 
	RETURN

;*******************************************************************************************
;   関数名    : WAT1　　　　
;   機能      : WAIT 1秒 
;   引数      : なし
;   変数      : なし
;   注意      : 10(Hz)  => 1(Hz)/10分周   
;*******************************************************************************************
WAT1
	MOVLW	H'0A'	; 10分周(>10分周)
	MOVWF	WT1A
WA1A	CALL	WATP1
	DECFSZ	WT1A,F	
	GOTO	WA1A
	RETURN 

;*******************************************************************************************
;   関数名    : WATP3　　　　
;   機能      : WAIT 0.3秒 
;   引数      : なし
;   変数      : なし
;   注意      :    
;*******************************************************************************************
WATP3
	MOVLW	H'03'	; 3分周
	MOVWF	WP3A
WTP3A	CALL	WATP1
	DECFSZ	WP3A,F	
	GOTO	WTP3A
	RETURN 

;*******************************************************************************************
;   関数名    : WATP1　　　　
;   機能      : WAIT 0.1秒 
;   引数      : なし
;   変数      : なし
;   注意      : 1,000(Hz)  => 10(Hz)/100分周   
;*******************************************************************************************
WATP1
	MOVLW	H'64'	; 100分周(>100分周)
	MOVWF	WP1A
WTP1A	CALL	WATP001
	DECFSZ	WP1A,F	
	GOTO	WTP1A
	RETURN 


;*******************************************************************************************
;   関数名    : WATP001　　　　
;   機能      : WAIT 0.001秒 
;   引数      : なし
;   変数      : なし
;   注意      : 4MHzの内部発振仕様
;               4,000,000(Hz)  => 1,000(Hz)/4,000分周   
;*******************************************************************************************
WATP001
	MOVLW	H'14'	;  20分周(>100分周)
	MOVWF	WP001B
WTP001B	MOVLW	H'63'	;  99分周(200分周)
	MOVWF	WP001A
WTP001A	DECFSZ	WP001A,F
	GOTO	WTP001A
	DECFSZ	WP001B,F
	GOTO	WTP001B
	RETURN 

;******************************************************************************************
;   Function Name : REC
;   Disctiption   : ＲＳ２３２Ｃ受信サブルーチン(PORTA3)
;                   9600BPS OSC;8.000MHz仕様
;   Input         : 
;   Output        :
;******************************************************************************************
REC
; (0)変数初期化
	CLRF	IODAT
; (1)受信データを待つ
REC0	BTFSC	PORTA,3
	GOTO	REC0
; (2)1/2ビット分待つ
	MOVLW	H'21'	; 9600BPS OSC;8.000MHz仕様
	MOVWF   RECWAT
REC1	DECFSZ	RECWAT,F
	GOTO	REC1
; (3)データ受信(8ビット分)
	MOVLW	8
	MOVWF	RECLP
	NOP
REC2	MOVLW	H'42'	; 9600BPS OSC;8.000MHz仕様
	MOVWF	RECWAT
REC3	DECFSZ	RECWAT,F
	GOTO	REC3
	NOP
	BTFSS	PORTA,3	; ビットデータが0の時, 0を立てる
	BCF	STATUS,C
	BTFSC	PORTA,3	; ビットデータが1の時, 1を立てる
	BSF	STATUS,C
	RRF	IODAT,F	; 変数内でビットをシフトする
	DECFSZ	RECLP,F
	GOTO	REC2
	NOP
	NOP
;
	RETURN

;******************************************************************************************
;   Function Name : SEND
;   Disctiption   : ＲＳ２３２Ｃ送信サブルーチン(PORTA4)
;                   9600BPS OSC;8.000MHz仕様
;   Input         : 
;   Output        :
;******************************************************************************************
; (1)送信開始
SEND	BCF	PORTA,4	; 送信開始
	MOVLW	H'42'	; 9600BPS OSC;8.000MHz仕様
	MOVWF	SENDWAT
SEND1	DECFSZ	SENDWAT,F
	GOTO	SEND1
;
; (2)データ送信(8ビット)
	MOVLW	8	; 8ビットデータ分、送信する
	MOVWF	SENDLP
	NOP
SEND2	RRF	IODAT,F
	NOP
	BTFSS	STATUS,C ; ビットデータが0の時, 0を立てる	
	BCF	PORTA,4
	BTFSC	STATUS,C ; ビットデータが1の時, 1を立てる
	BSF	PORTA,4

	MOVLW	H'42'	; 9600BPS OSC;8.000MHz仕様
	MOVWF	SENDWAT
SEND3	DECFSZ	SENDWAT,F
	GOTO	SEND3

	DECFSZ	SENDLP,F
	GOTO	SEND2
; (3)終了
	BSF	PORTA,4	; フラグを戻す
; (4)少し待つ
	CALL	TIMER

	RETURN
;
;******************************************************************************************
;   Function Name : TIMER
;   Disctiption   : タイマー(1000回ループ)
;   Input         : 
;   Output        :
;******************************************************************************************
TIMER
	MOVLW	H'0A'
	MOVWF	CNT1
TIMER1
	MOVLW	H'64'
	MOVWF	CNT
TIMER2
	DECFSZ	CNT,F
	GOTO	TIMER2 
	DECFSZ	CNT1,F
	GOTO	TIMER1

	RETURN

	END
