;**************************************************************************
; Battery charging monitor
;**************************************************************************

	list	p=16f873
	include <p16F873.inc>

	__config _HS_OSC & _WDT_OFF & _PWRTE_OFF & _CP_OFF & _LVE_OFF

	radix	dec

;--------------------------------------------------------------------------
; Variables
;--------------------------------------------------------------------------
LCD_RS	EQU	2	;RS
LCD_E	EQU	3	;E	NEED _LVE_OFF
CUTINIT	EQU	90	;AUTO-CUT CHECK TIME

;BANK-0
	ORG	H'20'
LCDMODE	RES	1

TEMPCUT	RES	1
HOUR_T	RES	1
MIN_T	RES	1
SEC_T	RES	1
MAX_T	RES	1

HOUR_V	RES	1
MIN_V	RES	1
SEC_V	RES	1
MAX_V	RES	1

HOUR1	RES	1
MIN1	RES	1
SEC1	RES	1

CUTTIME	RES	1
COUNT	RES	1
HOUR_C	RES	1
MIN_C	RES	1
SEC_C	RES	1
BUZON	RES	1
BUZCNT1	RES	1
BUZCNT2	RES	1

AD0	RES	1	;TEMP SENSOR
AD1	RES	1	;VR
AD2	RES	1	;NO USE
AD3	RES	1	;NO USE
AD4	RES	1	;BATTERY VOLTAGE

MOZI4	RES	1	;4bitモード用文字Temp変数
MOZI8	RES	1	;8bitモード用文字Temp変数
STR_L	RES	1	;文字列ラベル
STR_I	RES	1	;文字インデックス
TIME1	RES	1	;WAIT用
TIME2	RES	1
TIME3	RES	1
HEX1	RES	1
HEX2	RES	1
VOLT1	RES	1
VOLT2	RES	1
MUL10_1	RES	1

NUM0	RES	1
NUMTEMP	RES	1
FIGLANK	RES	1
FIGCNT	RES	1

;--------------------------------------------------------------------------
; Reset vectors
;--------------------------------------------------------------------------
        ORG     0       
        GOTO    Start

	ORG	4
	RETFIE			;INTERRUPT

;--------------------------------------------------------------------------
; Strings
;--------------------------------------------------------------------------
S_INIT1	DT	"ﾊﾞｯﾃﾘｰｼﾞｭｳﾃﾞﾝｶﾝｼ",0
S_INIT2	DT	"forPIC 2001.10.5",0
S_RESET	DT	"**** RESET ****",0
S_TEMP	DT	"T:",0
S_VR	DT	" VR:",0
S_VOLT	DT	"V:",0
S_TP	DT	"Tp:",0
S_VP	DT	"Vp:",0
S_LOW	DT	"Low",0
S_I	DT	"AD2:",0
S_J	DT	" AD3:",0
S_CUT	DT	"Ct:",0
S_BUZ	DT	" Bz:",0

;--------------------------------------------------------------------------
; Main Program
;--------------------------------------------------------------------------
Start
	BCF	STATUS,RP0	;BANK 0
	BCF	STATUS,RP1
	CLRF	LCDMODE
	
	; INIT IO PORTS
	BSF	STATUS,RP0	;BANK 1
	BCF	STATUS,RP1
	MOVLW	B'11111111'	;PORT A INPUT
	MOVWF	TRISA	;WRITE
	MOVLW	B'00000000'	;PORT B OUTPUT
	MOVWF	TRISB	;WRITE
	MOVLW	B'00000000'	;PORT C OUTPUT
	MOVWF	TRISC	;WRITE
	BCF	STATUS,RP0	;BANK 0
	BCF	STATUS,RP1
	MOVLW	0xFF
	MOVWF	PORTC

	; INIT LCD
	CALL	LCD_INIT
	MOVLW	S_INIT1
	CALL	LCD_STR
	CALL	LCD_LINE2
	MOVLW	S_INIT2
	CALL	LCD_STR
	CALL	WAIT1S
	CALL	WAIT1S
INITV	CALL	WAIT1S
	BCF	STATUS,RP0	;BANK 0
	BCF	STATUS,RP1
	CLRF	SEC1
	CLRF	MIN1
	CLRF	HOUR1
	MOVLW	CUTINIT
	MOVWF	CUTTIME
	MOVLW	1
	MOVWF	BUZON

	CLRF	TEMPCUT
	CLRF	HOUR_T
	CLRF	MIN_T
	CLRF	SEC_T
	MOVLW	255
	MOVWF	MAX_T

	CLRF	HOUR_V
	CLRF	MIN_V
	CLRF	SEC_V
	CLRF	MAX_V

	CLRF	HOUR_C
	CLRF	MIN_C
	CLRF	SEC_C
	
	; INIT AD CONVERTER
	BSF	STATUS,RP0	;BANK 1
	BCF	STATUS,RP1
	CLRF	ADCON1		;0..+5V,ADFM=0,all A-ports are analog inputs
	BCF	PIE1,ADIE	;AD interrupt off
LOOP
	CALL	AD0IN
	MOVWF	AD0
	CALL	AD1IN
	MOVWF	AD1
	CALL	AD2IN
	MOVWF	AD2
	CALL	AD3IN		; SW3
	MOVWF	AD3
	CALL	AD4IN
	MOVWF	AD4

	BCF	STATUS,RP0	;BANK 0
	BCF	STATUS,RP1
	BTFSC	AD3,7		;SW3 CHECK (0V=ON)
	GOTO	LOOP0
	CALL	LCD_CLEAR
	MOVLW	S_RESET
	CALL	LCD_STR
	GOTO	INITV
LOOP0	BTFSS	PORTA,4		;SW4 CHECK (0=ON)
	INCF	LCDMODE,F
	MOVF	LCDMODE,W
	SUBLW	2
	BTFSS	STATUS,C	;=>0 IS C=1
	CLRF	LCDMODE		;0,1,2,0,1,2,...

	CALL	CLOCK
	CALL	MAX
	CALL	LCD_CLEAR
	
	MOVF	LCDMODE,W
	SUBLW	1
	BTFSC	STATUS,Z
	GOTO	LOOP1
	MOVF	LCDMODE,W
	SUBLW	2
	BTFSC	STATUS,Z
	GOTO	LOOP2

	; DISPLAY CURRENT DATA
	CALL	LCD_CURRENT
	GOTO	LOOP3
LOOP1
	; DISPLAY PEAK DATA
	CALL	LCD_PEAK
	GOTO	LOOP3
LOOP2
	CALL	LCD_SUB
LOOP3
; Check Auto-Cut off
	MOVF	BUZON,W
	BTFSC	STATUS,Z	;IF BUZON=0 GOTO CUTOFF
	GOTO	CUTOFF	
	DECF	CUTTIME,F
	BTFSS	STATUS,Z
	GOTO	CUTOFF
	CALL	BUZZER
	MOVF	HOUR1,W
	MOVWF	HOUR_C
	MOVF	MIN1,W
	MOVWF	MIN_C
	MOVF	SEC1,W
	MOVWF	SEC_C
	CLRF	CUTTIME
	CLRF	BUZON
CUTOFF
; Comapare 2 AD datas and set LED
	BCF	STATUS,RP0	;BANK0
	BCF	STATUS,RP1

	MOVF	AD0,0		;AD0 -> (W)
	SUBWF	AD1,0
	BTFSS	STATUS,C	;if C=1(Positive)
	GOTO	COMPOFF
	BCF	PORTB,0		;LED ON
	MOVLW	0xFC
	MOVWF	PORTC		;RELAY OFF
	GOTO	COMPEND
COMPOFF
	BSF	PORTB,0		;LED OFF
	MOVLW	0xFF
	MOVWF	PORTC		;RELAY OFF
COMPEND
	CALL	WAIT1S
	GOTO	LOOP
;-----------------------------------------------
BUZZER
	MOVLW   100		  ;10sec = 10000times
	MOVWF	BUZCNT1
BUZZER1
	MOVLW	100
	MOVWF	BUZCNT2
BUZZER2
	MOVLW	0xF3
	MOVWF	PORTC		;SPEAKER ON
	CALL	WAIT01MS	;1000Hz=0.5ms
	CALL	WAIT01MS
	CALL	WAIT01MS
	CALL	WAIT01MS
	CALL	WAIT01MS
	MOVLW	0xFF
	MOVWF	PORTC
	CALL	WAIT01MS	;1000Hz=0.5ms
	CALL	WAIT01MS
	CALL	WAIT01MS
	CALL	WAIT01MS
	CALL	WAIT01MS
	
        DECFSZ  BUZCNT2,F
        GOTO    BUZZER2
        DECFSZ  BUZCNT1,F
        GOTO    BUZZER1
        RETURN
;-----------------------------------------------
LCD_CURRENT	;現在の温度、設定温度、電圧、時間を表示
	MOVLW	S_TEMP	
	CALL	LCD_STR		;文字列表示
	MOVF	AD0,W
	CALL	LCD_TEMP
	MOVLW	0xDF		;'°'
	CALL	LCD_CHAR

	MOVLW	S_VR	
	CALL	LCD_STR		;文字列表示
	MOVF	AD1,W
	CALL	LCD_TEMP
	MOVLW	0xDF		;'°'
	CALL	LCD_CHAR
	
	CALL	LCD_LINE2

	MOVLW	S_VOLT	
	CALL	LCD_STR		;文字列表示
	MOVF	AD4,W
	CALL	LCD_VOLT

	MOVLW	0x20		;' '
	CALL	LCD_CHAR
	MOVF	HOUR1,W
	CALL	LCD_DEC2
	MOVLW	0x3A		;':'
	CALL	LCD_CHAR
	MOVF	MIN1,W
	CALL	LCD_DEC2
	MOVLW	0x3A		;':'
	CALL	LCD_CHAR
	MOVF	SEC1,W
	CALL	LCD_DEC2
	RETURN
;-----------------------------------------------
LCD_PEAK	; ピーク時の温度と電圧、それらの時間を表示
	MOVLW	S_TP
	CALL	LCD_STR
	MOVF	MAX_T,W
	CALL	LCD_TEMP
	MOVLW	0xDF		;'°'
	CALL	LCD_CHAR
	MOVLW	0x20		;' '
	CALL	LCD_CHAR
	MOVF	HOUR_T,W
	CALL	LCD_DEC2
	MOVLW	0x3A		;':'
	CALL	LCD_CHAR
	MOVF	MIN_T,W
	CALL	LCD_DEC2
	MOVLW	0x3A		;':'
	CALL	LCD_CHAR
	MOVF	SEC_T,W
	CALL	LCD_DEC2

	CALL	LCD_LINE2
	MOVLW	S_VP
	CALL	LCD_STR
	MOVF	MAX_V,W
	CALL	LCD_VOLT
	MOVLW	0x20		;' '
	CALL	LCD_CHAR
	MOVF	HOUR_V,W
	CALL	LCD_DEC2
	MOVLW	0x3A		;':'
	CALL	LCD_CHAR
	MOVF	MIN_V,W
	CALL	LCD_DEC2
	MOVLW	0x3A		;':'
	CALL	LCD_CHAR
	MOVF	SEC_V,W
	CALL	LCD_DEC2
	RETURN
;-----------------------------------------------
LCD_SUB		; 予備ADポート、補助情報
	MOVLW	S_I
	CALL	LCD_STR
	MOVF	AD2,W
	CALL	LCD_DEC3
	MOVLW	S_J
	CALL	LCD_STR
	MOVF	AD3,W
	CALL	LCD_DEC3
	
	CALL	LCD_LINE2
	MOVLW	S_CUT
	CALL	LCD_STR
	MOVF	CUTTIME,W
	CALL	LCD_DEC2
	MOVLW	S_BUZ
	CALL	LCD_STR
	MOVF	BUZON,W
	CALL	LCD_DEC1

	MOVLW	0x20		;' '
	CALL	LCD_CHAR
	MOVF	HOUR_C,W
	CALL	LCD_DEC2
	MOVLW	0x3A		;':'
	CALL	LCD_CHAR
	MOVF	MIN_C,W
	CALL	LCD_DEC2

	RETURN
;-----------------------------------------------
; 時計計算
;-----------------------------------------------
CLOCK
	INCF	SEC1,F
	MOVF	SEC1,W	;CHECK 60
	SUBLW	60
	BTFSS	STATUS,Z
	GOTO	CLOCK1
	;SEC OVER 60, INCREMENT MIN
	CLRF	SEC1
	INCF	MIN1,F
	MOVF	MIN1,W	;CHECK 60
	SUBLW	60
	BTFSS	STATUS,Z
	GOTO	CLOCK1
	;MIN OVER 60, INCREMENT HOUR
	CLRF	MIN1
	INCF	HOUR1,F
CLOCK1
	RETURN
;-----------------------------------------------
; 温度、電圧の最大値を得る
;-----------------------------------------------
MAX
	MOVF	AD0,W	;温度が上がるとAD0が下がる
	SUBWF	MAX_T,W	;IF MAX_T-AD0>0
	BTFSS	STATUS,C
	GOTO	MAX1
	MOVF	AD0,W	;THEN MAX_T := AD0
	MOVWF	MAX_T
	MOVF	HOUR1,W
	MOVWF	HOUR_T
	MOVF	MIN1,W
	MOVWF	MIN_T
	MOVF	SEC1,W
	MOVWF	SEC_T
MAX1
	MOVF	AD4,W
	SUBWF	MAX_V,W	;IF MAX_V-AD4<=0
	BTFSC	STATUS,Z
	GOTO	MAX2
	BTFSC	STATUS,C
	GOTO	MAX3
MAX2
	MOVF	AD4,W	;THEN MAX_V := AD4
	MOVWF	MAX_V
	MOVF	HOUR1,W
	MOVWF	HOUR_V
	MOVF	MIN1,W
	MOVWF	MIN_V
	MOVF	SEC1,W
	MOVWF	SEC_V
MAX3	; カットオフ検出
	MOVF	AD4,W
	ADDLW	4
	SUBWF	MAX_V,W	;IF AD4=>MAX_V-4(0.25V)
	BTFSC	STATUS,C
	GOTO	MAX4
	MOVF	AD4,W	;THEN CUTTIME:=CUTINIT
	MOVLW	CUTINIT
	MOVWF	CUTTIME
MAX4
	RETURN
;-----------------------------------------------
; LCD初期化サブルーチン
;-----------------------------------------------
LCD_INIT
	BCF	STATUS,RP0	;BANK0
	BCF	STATUS,RP1

	BSF	PORTB,0		;DEBUG
	CALL	WAIT10
	BCF	PORTB,0

	CALL	WAIT15MS	;15ms待機
	BCF	PORTB,LCD_RS	;RS=0 特殊コマンド
       	MOVLW   B'00110000'	;function set 8bit
	CALL	LCD_WRITE_8

	CALL	WAIT5MS		;5ms待機
       	MOVLW   B'00110000'	;function set 8bit
	CALL	LCD_WRITE_8

	CALL	WAIT5MS		;0.1ms待機
       	MOVLW   B'00110000'	;function set 8bit
	CALL	LCD_WRITE_8

       	MOVLW   B'00100000'	;function set 4bit
	CALL	LCD_WRITE_8
       	MOVLW   B'00101000'	;function set 4bit 2行
	CALL	LCD_WRITE_4
	MOVLW	B'00001000'	;ディスプレイOFF
	CALL	LCD_WRITE_4
	MOVLW	B'00000001'	;画面クリア
	CALL	LCD_WRITE_4
	CALL	WAIT2MS		;クリア完了待機
	MOVLW	B'00000110'	;entry mode set 
	CALL	LCD_WRITE_4
	MOVLW	B'00001100'	;ディスプレイON カーソルOFF
	CALL	LCD_WRITE_4
	RETURN
;-----------------------------------------------
; LCD送信サブルーチン
;-----------------------------------------------
LCD_VOLT	; 電圧(=AD4/16)を表示
	MOVWF	VOLT1

	MOVWF	VOLT2
	BCF	STATUS,C
	RRF	VOLT2,F
	BCF	STATUS,C
	RRF	VOLT2,F
	BCF	STATUS,C
	RRF	VOLT2,F
	BCF	STATUS,C
	RRF	VOLT2,F
	MOVF	VOLT2,W
	CALL	LCD_DEC2

	MOVLW	0x2E		;'.'
	CALL	LCD_CHAR

	MOVLW	0x0F		;小数点一桁=10*(AD4%16)/16
	ANDWF	VOLT1,W
	CALL	MUL10
	MOVWF	VOLT2
	BCF	STATUS,C
	RRF	VOLT2,F
	BCF	STATUS,C
	RRF	VOLT2,F
	BCF	STATUS,C
	RRF	VOLT2,F
	BCF	STATUS,C
	RRF	VOLT2,F
	MOVF	VOLT2,W
	CALL	LCD_DEC1
	RETURN

LCD_TEMP	; 温度(=6*(86-AD0))を表示
	MOVWF	VOLT1		;VOLTの変数を借用
	MOVWF	VOLT2

	MOVLW	86
	SUBWF	VOLT2,F		;VOLT2 = VOLT2-86
	BTFSC	STATUS,C
	GOTO	LCD_TEMP1	;IF - NO DISPLAY
	
	COMF	VOLT2,F		;VOLT2 = -VOLT2
	MOVF	VOLT2,W		;VOLT2=VOLT2*6
	ADDWF	VOLT2,W
	ADDWF	VOLT2,W
	ADDWF	VOLT2,W
	ADDWF	VOLT2,W
	ADDWF	VOLT2,W

	CALL	LCD_DEC3
	RETURN
LCD_TEMP1
	MOVLW	S_LOW
	CALL	LCD_STR
	RETURN

MUL10	;W = W*10
	MOVWF	MUL10_1
	ADDWF	MUL10_1,W	;W=W*2
	ADDWF	MUL10_1,W
	ADDWF	MUL10_1,W
	ADDWF	MUL10_1,W
	ADDWF	MUL10_1,W
	ADDWF	MUL10_1,W
	ADDWF	MUL10_1,W
	ADDWF	MUL10_1,W
	ADDWF	MUL10_1,W
	RETURN
;-----------------------------------------------
LCD_HEX
	MOVWF	HEX1
	SWAPF	HEX1,W	 	;上位下位を入れ替える
	ANDLW	H'0F'
	MOVWF	HEX2
	SUBLW	9		;10以下なら'A'を足す
	BTFSC	STATUS,C
	GOTO	LESS10A
	MOVF	HEX2,W
	ADDLW	H'37'		;37='A'-10
	GOTO	LCD_HEX1
LESS10A	MOVF	HEX2,W
	ADDLW	H'30'		;30='0'
LCD_HEX1
	CALL	LCD_CHAR

	MOVF	HEX1,W
	ANDLW	H'0F'
	MOVWF	HEX2
	SUBLW	9		;10以下なら'A'を足す
	BTFSC	STATUS,C
	GOTO	LESS10B
	MOVF	HEX2,W
	ADDLW	H'37'		;37='A'-10
	GOTO	LCD_HEX2
LESS10B	MOVF	HEX2,W
	ADDLW	H'30'		;30='0'
LCD_HEX2
	CALL	LCD_CHAR
	RETURN

LCD_DEC3
	MOVWF	NUM0
	MOVLW	100
	MOVWF	FIGLANK
	CALL	DIVIDE
	MOVF	FIGCNT,W
	ADDLW	H'30'
	CALL	LCD_CHAR
	MOVF	NUMTEMP,W
LCD_DEC2			;W MUST BE <100
	MOVWF	NUM0
	MOVLW	10		;10をロードして
	MOVWF	FIGLANK    	;FIGLANKにセット
	CALL	DIVIDE
	MOVF	FIGCNT,W
	ADDLW	H'30'
	CALL	LCD_CHAR
	MOVF	NUMTEMP,W
LCD_DEC1
	ADDLW	H'30'
	CALL	LCD_CHAR
	RETURN

DIVIDE	;NUM0/FIGLANK -> FIGCNT(ANS) ... NUMTEMP(MOD)
	CLRF	FIGCNT		;FIGCNTをリセット
	MOVF	NUM0,W
	MOVWF	NUMTEMP
FIGLOOP	MOVF	FIGLANK,W  
	SUBWF	NUMTEMP,F  	;元のデータからFIGLANKを引く
	BTFSC	STATUS,C	;マイナスになるまで繰り返す	
	GOTO	CNTPLUS
	GOTO	ENDFIG
CNTPLUS	INCF	FIGCNT,F	;プラスのときはカウンタ+1
	GOTO	FIGLOOP
ENDFIG	MOVF	FIGLANK,W 	;マイナスになったら、FIGLANK	
	ADDWF	NUMTEMP,F	;を加えてプラスに戻す
	RETURN		
	
LCD_STR
	MOVWF	STR_L   	;文字列の先頭アドレスを格納
	MOVLW	0
	MOVWF	STR_I   	;インデックス変数を0リセット
STR_LOOP
	ADDWF	STR_L,W 	;先頭アドレス+インデックス→W
	CALL	GET_CHAR    	;文字の取得
	ADDLW	0	    	;取得した文字が0かチェック
	BTFSC	STATUS,Z    	;0だったら終了
	RETURN
	CALL	LCD_CHAR	;文字の書き込みを実行
	INCF	STR_I,F		;インデックス+1
	MOVF	STR_I,W
	GOTO	STR_LOOP	;文字が0になるまで繰り返し
GET_CHAR
	MOVWF	PCL	    	;文字をWに格納
;これはGOTO Wと同じでり、飛び先のDT文が、１文字ごとにRETLW命令を実行する

LCD_CHAR
	BCF	STATUS,RP0	;BANK0
	BCF	STATUS,RP1
 	BSF	PORTB,LCD_RS   	;RS=1 (文字コード送信モード)
	CALL	LCD_WRITE_4
	RETURN

LCD_CLEAR
	MOVLW	B'00000001'	;クリアコマンド
	CALL	LCD_CMD
	CALL	WAIT2MS
	RETURN

LCD_LINE2
	MOVLW	B'11000000'	;LCD表示アドレスを2行目に変更
	CALL	LCD_CMD
	RETURN

LCD_SET_ADDR
	IORLW	B'10000000'	;LCD表示アドレスをWレジスタで
	CALL	LCD_CMD		;指定されたアドレスに変更
	RETURN

LCD_CMD
	BCF	STATUS,RP0	;BANK0
	BCF	STATUS,RP1
	BCF	PORTB,LCD_RS   	;RS=0 (特殊コマンド送信モード)
	CALL	LCD_WRITE_4
	RETURN

LCD_WRITE_4
	MOVWF	MOZI4		;W-->MOZI4
	CALL	LCD_WRITE_8	;上位4bitの送信
	SWAPF	MOZI4,W 	;上位下位を入れ替える
	CALL	LCD_WRITE_8	;下位4bitの送信
	RETURN

LCD_WRITE_8
	ANDLW	0XF0		;上位4bitを取り出す
	MOVWF	MOZI8
	MOVF	PORTB,W
	ANDLW	0X0F
	IORWF	MOZI8,W
	MOVWF	PORTB		;PortBに出力
	CALL	WAIT10		;電圧が安定するまで待つ
	BSF	PORTB,LCD_E	;E=1  表示準備
	CALL	WAIT10
	BCF	PORTB,LCD_E	;E=0  表示実行(トリガ)
	CALL	WAIT01MS
	RETURN

;-----------------------------------------------
; AD converter Input ->W
;-----------------------------------------------
AD0IN
	MOVLW	B'10000001'	;Fosc/32,ch0,AD=on
	GOTO	ADIN
AD1IN
	MOVLW	B'10001001'	;Fosc/32,ch1,AD=on
	GOTO	ADIN
AD2IN
	MOVLW	B'10010001'	;Fosc/32,ch2,AD=on
	GOTO	ADIN
AD3IN
	MOVLW	B'10011001'	;Fosc/32,ch3,AD=on
	GOTO	ADIN
AD4IN
	MOVLW	B'10100001'	;Fosc/32,ch4,AD=on
ADIN
	BCF	STATUS,RP0	;BANK0
	BCF	STATUS,RP1
	MOVWF	ADCON0		;WRITE
	; WAIT 200 STEPS (23*n+1)
	MOVLW	8		;LOOP START
	MOVWF	COUNT
PREWAIT
	CALL	WAIT20
	DECFSZ	COUNT,1
	GOTO	PREWAIT		;LOOP END

	BSF	ADCON0,	GO	;A/D START
	NOP
ADWAIT
	BTFSC	ADCON0,GO_DONE
	GOTO	ADWAIT		;LOOP END

	BCF	ADCON0, ADON	;A/D off
	MOVF	ADRESH,W
	RETURN

;--------------------------------
; Wait
;--------------------------------
WAIT1S 	MOVLW   D'100' ;1s待機
	MOVWF   TIME3
	GOTO	WLOOP3
WAIT05S MOVLW   D'50'  ;0.5s待機
	MOVWF   TIME3
	GOTO	WLOOP3
WLOOP3  CALL    WAIT10MS
        DECFSZ  TIME3,F
        GOTO    WLOOP3
        RETURN

WAIT15MS
	MOVLW  	D'150'	;約15ms待機
	MOVWF   TIME2
	GOTO	WLOOP2
WAIT10MS
	MOVLW  	D'100'	;約10ms待機
	MOVWF   TIME2
	GOTO	WLOOP2
WAIT5MS
  	MOVLW  	D'50'	;約5ms待機
	MOVWF   TIME2
	GOTO	WLOOP2
WAIT2MS
  	MOVLW  	D'20'	;約2ms待機
	MOVWF   TIME2
	GOTO	WLOOP2
WLOOP2
	CALL    WAIT01MS
	DECFSZ  TIME2,F
	GOTO    WLOOP2
	RETURN

WAIT01MS		;0.1ms待機
	MOVLW   D'164'
	MOVWF   TIME1
WLOOP1
	DECFSZ  TIME1,F
	GOTO    WLOOP1
	RETURN

WAIT20	nop
	nop
	nop
	nop
	nop
	nop
	nop
	nop
	nop
	nop
WAIT10	nop
	nop
	nop
	nop
	nop
	nop
	RETURN		;goto-2 return-2 and nop

	END
