;--------------------------------------------------------------------------------
;	PIC16F88 充電電流 & 電池電圧メーター
;	Programmed by GRANADA
;	Original 12F675 version	: since 2008/11/18-11/20
;	16F88 version			: since 2008/11/28-
;
;--------------------------------------------------------------------------------

	LIST		P=16F88
	INCLUDE		P16F88.INC
	ERRORLEVEL	-302

	__CONFIG  _CONFIG1, _CP_OFF & _CCP1_RB0 & _DEBUG_OFF & _WRT_PROTECT_OFF & _CPD_OFF & _LVP_OFF & _BODEN_OFF & _MCLR_ON & _PWRTE_OFF & _WDT_OFF & _INTRC_IO
	__CONFIG  _CONFIG2, _IESO_OFF & _FCMEN_OFF

;--------------------------------------------------------------------------------
;	ファイルアドレス定義
;--------------------------------------------------------------------------------

VOLTAGE			EQU		H'20'	; 電流値ストア用
VOLTAGE_TMP		EQU		H'21'	; 測定電圧一時保存用
BATTERY_V		EQU		H'22'	; 電池電圧ストア用

BLINK_COUNTER	EQU		H'24'	; LED BLINK 処理用カウンタ

LED_BIT			EQU		H'25'	; 電池電圧 LED 表示の際の表示位置保持用

W_WORK			EQU		H'30'	; 割り込み時の W レジスタ退避用（未使用）
ST_WORK			EQU		H'31'	; 割り込み時のステータスレジスタ退避用（未使用）
WORK1			EQU		H'32'	; 割り込み時の時間待ち変数退避用
WORK2			EQU		H'33'	; 割り込み時の時間待ち変数退避用

COUNTER1		EQU		H'40'	; 時間待ち用ワーク
COUNTER2		EQU		H'41'	; 時間待ち用ワーク

DISPLAY_COUNTER	EQU		H'43'	; LED 点灯回数用カウンタ
INT_COUNTER		EQU		H'44'	; 割り込み処理用カウンタ

;--------------------------------------------------------------------------------
;	定数定義
;--------------------------------------------------------------------------------

CURRENT_IN		EQU		D'0'	; 電流値入力 	RA0(AN0)
BATTERY_IN		EQU		D'1'	; 電池電圧入力	RA1(AN1)

LED1			EQU		D'2'	; RA2
LED2			EQU		D'3'	; RA3

LED3			EQU		D'0'	; RB0
LED4			EQU		D'1'	; RB1
LED5			EQU		D'2'	; RB2
LED6			EQU		D'3'	; RB3
LED7			EQU		D'4'	; RB4
LED8			EQU		D'5'	; RB5

LED9			EQU		D'6'	; RA6
LED10			EQU		D'7'	; RA7

;
;	電流検出抵抗 40mオーム だと 1A で 40mV 発生。
;	1.0A max ならゲイン 125倍 で 5V
;	0.5A max ならゲイン 250倍 で 5V
;	ただしオペアンプの入力オフセットの補正は必要
;
;	・・・・などといろいろ考えたが、要は測定最大電流を流した際に
;	LED が全点灯するよう VR でゲインを調整し、A/D変換値はオペアンプの
;	最大出力電圧を考慮して等分すればいいと。
;	NJM2119D は max 4V スイングなので Vref+ 5V 時の A/D 変換最大値は 201
;
							; Ratio	 1A max時	300mA max時
LED1_V		EQU		D'10'	;  1/20	 50mA		 15mA
LED2_V		EQU		D'30'	;  3/20	 150mA		 45mA
LED3_V		EQU		D'50'	;  5/20	 250mA		 75mA
LED4_V		EQU		D'70'	;  7/20	 350mA		105mA
LED5_V		EQU		D'90'	;  9/20	 450mA		135mA
LED6_V		EQU		D'110'	; 11/20	 550mA		165mA
LED7_V		EQU		D'130'	; 13/20	 650mA		195mA
LED8_V		EQU		D'150'	; 15/20	 750mA		225mA
LED9_V		EQU		D'170'	; 17/20	 850mA		255mA
LED10_V		EQU		D'190'	; 19/20	 950mA		285mA

;
;	12v 電池電圧表示用, 抵抗比は 1:3 (=1/4入力)
;

BATTERY_LED2_V		EQU		D'143'	; 11.2/4 * 256/5	2.80v	RED
BATTERY_LED3_V		EQU		D'151'	; 11.8				2.95v	YELLOW
BATTERY_LED4_V		EQU		D'153'	; 12.0				3.00v	YELLOW
BATTERY_LED5_V		EQU		D'160'	; 12.5				3.12v	GREEN
BATTERY_LED6_V		EQU		D'166'	; 13.0				3.25v	GREEN
BATTERY_LED7_V		EQU		D'173'	; 13.5				3.37v	GREEN
BATTERY_LED8_V		EQU		D'185'	; 14.5				3.62v	GREEN
BATTERY_LED9_V		EQU		D'194'	; 15.2/4 * 256/5	3.80v	GREEN

;--------------------------------------------------------------------------------
;	プログラム先頭
;--------------------------------------------------------------------------------

	ORG		H'0'
	GOTO	INITIALIZE

;--------------------------------------------------------------------------------
;	割り込み処理
;--------------------------------------------------------------------------------

	ORG		H'4'			; 割り込み処理先頭アドレス

PUSH_REG:

	MOVWF	W_WORK			; レジスタ待避
	SWAPF	STATUS,W		; Z フラグが影響しないよう、MOVF ではなく SWAPF を使用
	MOVWF	ST_WORK

;
;	割り込み処理（電池電圧表示）
;
	DECFSZ	INT_COUNTER,F
	GOTO	POP_REG					; 所定回数に達しなければ割り込み終了

;
;	変数退避
;

	MOVF	COUNTER1,W
	MOVWF	WORK1
	MOVF	COUNTER2,W
	MOVWF	WORK2

;
;	電池電圧表示実行
;

	CALL	DISPLAY_BATTERY_VOLTAGE

;
;	変数復帰
;

	MOVF	WORK1,W
	MOVWF	COUNTER1
	MOVF	WORK2,W
	MOVWF	COUNTER2

	CLRF	DISPLAY_COUNTER
	INCF	DISPLAY_COUNTER,F		; 復帰後すぐ電流測定を開始するよう表示カウンタを最小にしておく

	CALL	SET_INT_COUNTER			; 割り込みカウンタを初期化

POP_REG:

	SWAPF	ST_WORK,W        ;レジスタ復帰
	MOVWF	STATUS
	SWAPF	W_WORK,F
	SWAPF	W_WORK,W

	BCF		PIR1,TMR1IF		; TMR1割り込みフラグをクリアしておく
							; フラグをクリアしておかないと次回の割り込みがかからないので注意
	RETFIE					; 割り込み処理終了

;--------------------------------------------------------------------------------
;	初期化
;--------------------------------------------------------------------------------

INITIALIZE:

	BANKSEL	OSCCON				; Bank1
	MOVLW	B'01111100'			; 内部クロック 8MHz に設定
	MOVWF	OSCCON

	BCF		OPTION_REG,7		; Bank1, PORTB weak pull up enable ( 0 = enable )

								; Bank1, ANSEL 設定は TRISA/B 設定より前でないダメというウワサあり
	BSF		ANSEL,0				; AN0, アナログポートのみ再指定、他はデジタル入出力に設定される
	NOP
	BSF		ANSEL,1				; AN1

	CLRF	TRISA				; Bank1, ひとまず全ポートを出力に指定
	BSF		TRISA,CURRENT_IN	; 電流計測ポートを入力に再指定
	NOP							; 安定するまで待つ
	BSF		TRISA,BATTERY_IN	; 電圧計測ポートを入力に再指定

	CLRF	TRISB				; Bank1, ひとまず全ポートを出力に設定
								; しかし TMR1 使用時 RB6, RB7 は TRISB 設定に関わらず
								; 入力専用となり常に 0 になる(!)点に注意
								; この場合、PORTB 状態変化割り込みもかからない

	BANKSEL	INTCON				; Bank0
	CLRF	INTCON

	MOVLW	B'00000111'			; コンパレータ未使用（12F675 ではこれを設定しないと Port 0 の挙動が怪しいので念のため）
	MOVWF	CMCON				; Bank0

	MOVLW	B'10000001'			; 32 Tosc, AN0 使用, AD コンバータ電源 ON
	MOVWF	ADCON0				; Bank0

	BANKSEL ADCON1				; Bank1
	CLRF	ADCON1				; 左詰、32 Tosc（の最上位ビット）, Vref+ = VDD, Vref- = Vss

	BANKSEL	PIE1				; Bank1
	CLRF	PIE1				; ひとまず全ての割り込みを不許可
	BSF		PIE1,TMR1IE			; TMR1割り込み許可

	BANKSEL	TMR1H				; Bank0
	MOVLW	H'EA'				; 6万カウントで割り込み発生
	MOVWF	TMR1H
	MOVLW	H'60'				; 8MHz時 1カウント = 0.5us なので
	MOVWF	TMR1L				; 6万カウントなら 30ms毎に割り込み発生

	BSF		INTCON,PEIE			; Bank0, 周辺割り込み有効
	NOP
	BSF		INTCON,GIE			; グローバル割り込み許可

	MOVLW	B'00111000'			; プリスケース1:8なら240ms毎に割り込み発生
	MOVWF	T1CON				; Bank0, タイマーレジスタ設定
	BSF		T1CON,TMR1ON		; TMR1 スタート

	CALL	SET_INT_COUNTER		; 割り込みカウンタを初期化

;	CALL	BLINK_LED			; 全 LED を点滅させて正常起動を確認

;--------------------------------------------------------------------------------
;	メインループ開始
;--------------------------------------------------------------------------------

MAIN_LOOP:

	CALL	READ_VOLTAGE		; オペアンプからの電圧を読んで
	MOVF	VOLTAGE_TMP,W
	MOVWF	VOLTAGE				; 電流表示用電圧としてストア

	CALL	SET_DISPLAY_COUNTER	; LED 表示回数をリセット

;--------------------------------------------------------------------------------
;	LED 表示
;--------------------------------------------------------------------------------

EXEC_DISPLAY:

	CALL	DISPLAY_LED			; LED 表示

	DECFSZ	DISPLAY_COUNTER,F
	GOTO	EXEC_DISPLAY		; 所定回数まで表示

	GOTO	MAIN_LOOP

;--------------------------------------------------------------------------------
;	メインループ終了、ここからサブルーチン群
;--------------------------------------------------------------------------------

;--------------------------------------------------------------------------------
;	A/D 変換を実行し、値をメモリにストアする
;--------------------------------------------------------------------------------

READ_VOLTAGE:

	CALL	WAIT_100us		; サンプリングまで 2TAD 以上待つ
	BSF		ADCON0,GO		; GO (start) bit を立てて A/D 変換開始

EXEC_AD:					; 通常の A/D 変換

	BTFSC	ADCON0,GO		; A/D 変換終了したか? 0 なら次をスキップ
	GOTO	EXEC_AD			; まだ変換中

	MOVF	ADRESH,W		; A/D 変換値を読み出して
	MOVWF	VOLTAGE_TMP		; メモリにストアしておく

	RETURN

;--------------------------------------------------------------------------------
;	ダイナミック点灯サブルーチン
;--------------------------------------------------------------------------------

DISPLAY_LED:

	CALL	ALL_LED_OFF			; 全 LED 消灯

	MOVF	VOLTAGE,W			; 測定電圧値を読み出す
	SUBLW	LED1_V				; LED1_V - VOLTAGE -> W
	BTFSC	STATUS,C			; LED1_V 以上なら借り入れが発生するので C=0 となり、次の命令がスキップされる
	RETURN						; 最低電圧以下なのでメインループに戻る

	BSF		PORTA,LED1			; LED1 点灯
	CALL	HOLD_LED			; LED 点灯をしばらくホールド

;--------------------------------------------------------------------------------
;	LED2 以上の電圧?
;--------------------------------------------------------------------------------

	MOVF	VOLTAGE,W			; 測定電圧値を読み出す
	SUBLW	LED2_V				; LED2_V - VOLTAGE -> W
	BTFSC	STATUS,C			; LED2_V 以上なら借り入れが発生するので C=0 となり、次の命令がスキップされる
	GOTO	ALL_LED_OFF

	BCF		PORTA,LED1			; ひとつ前の LED を消す
	CALL	WAIT_2us
	BSF		PORTA,LED2			; LED2 点灯

	CALL	HOLD_LED			; LED 点灯をしばらくホールド

;--------------------------------------------------------------------------------
;	LED3 以上の電圧?
;--------------------------------------------------------------------------------

	MOVF	VOLTAGE,W			; 測定電圧値を読み出す
	SUBLW	LED3_V				; LED3_V - VOLTAGE -> W
	BTFSC	STATUS,C			; LED3_V 以上なら借り入れが発生するので C=0 となり、次の命令がスキップされる
	GOTO	ALL_LED_OFF

	BCF		PORTA,LED2			; ひとつ前の LED を消す
	CALL	WAIT_2us
	BSF		PORTB,LED3			; LED3 点灯

	CALL	HOLD_LED			; LED 点灯をしばらくホールド

;--------------------------------------------------------------------------------
;	LED4 以上の電圧?
;--------------------------------------------------------------------------------

	MOVF	VOLTAGE,W			; 測定電圧値を読み出す
	SUBLW	LED4_V				; LED4_V - VOLTAGE -> W
	BTFSC	STATUS,C			; LED4_V 以上なら借り入れが発生するので C=0 となり、次の命令がスキップされる
	GOTO	ALL_LED_OFF

	BCF		PORTB,LED3			; ひとつ前の LED を消す
	CALL	WAIT_2us
	BSF		PORTB,LED4			; LED4 点灯

	CALL	HOLD_LED			; LED 点灯をしばらくホールド

;--------------------------------------------------------------------------------
;	LED5 以上の電圧?
;--------------------------------------------------------------------------------

	MOVF	VOLTAGE,W			; 測定電圧値を読み出す
	SUBLW	LED5_V				; LED5_V - VOLTAGE -> W
	BTFSC	STATUS,C			; LED5_V 以上なら借り入れが発生するので C=0 となり、次の命令がスキップされる
	GOTO	ALL_LED_OFF

	BCF		PORTB,LED4			; ひとつ前の LED を消す
	CALL	WAIT_2us
	BSF		PORTB,LED5			; LED5 点灯

	CALL	HOLD_LED			; LED 点灯をしばらくホールド

;--------------------------------------------------------------------------------
;	LED6 以上の電圧?
;--------------------------------------------------------------------------------

	MOVF	VOLTAGE,W			; 測定電圧値を読み出す
	SUBLW	LED6_V				; LED6_V - VOLTAGE -> W
	BTFSC	STATUS,C			; LED6_V 以上なら借り入れが発生するので C=0 となり、次の命令がスキップされる
	GOTO	ALL_LED_OFF

	BCF		PORTB,LED5			; ひとつ前の LED を消す
	CALL	WAIT_2us
	BSF		PORTB,LED6			; LED6 点灯

	CALL	HOLD_LED			; LED 点灯をしばらくホールド

;--------------------------------------------------------------------------------
;	LED7 以上の電圧?
;--------------------------------------------------------------------------------

	MOVF	VOLTAGE,W			; 測定電圧値を読み出す
	SUBLW	LED7_V				; LED7_V - VOLTAGE -> W
	BTFSC	STATUS,C			; LED7_V 以上なら借り入れが発生するので C=0 となり、次の命令がスキップされる
	GOTO	ALL_LED_OFF

	BCF		PORTB,LED6			; ひとつ前の LED を消す
	CALL	WAIT_2us
	BSF		PORTB,LED7			; LED7 点灯

	CALL	HOLD_LED			; LED 点灯をしばらくホールド

;--------------------------------------------------------------------------------
;	LED8 以上の電圧?
;--------------------------------------------------------------------------------

	MOVF	VOLTAGE,W			; 測定電圧値を読み出す
	SUBLW	LED8_V				; LED8_V - VOLTAGE -> W
	BTFSC	STATUS,C			; LED8_V 以上なら借り入れが発生するので C=0 となり、次の命令がスキップされる
	GOTO	ALL_LED_OFF

	BCF		PORTB,LED7			; ひとつ前の LED を消す
	CALL	WAIT_2us
	BSF		PORTB,LED8			; LED8 点灯

	CALL	HOLD_LED			; LED 点灯をしばらくホールド

;--------------------------------------------------------------------------------
;	LED9 以上の電圧?
;--------------------------------------------------------------------------------

	MOVF	VOLTAGE,W			; 測定電圧値を読み出す
	SUBLW	LED9_V				; LED9_V - VOLTAGE -> W
	BTFSC	STATUS,C			; LED9_V 以上なら借り入れが発生するので C=0 となり、次の命令がスキップされる
	GOTO	ALL_LED_OFF

	BCF		PORTB,LED8			; ひとつ前の LED を消す
	CALL	WAIT_2us
	BSF		PORTA,LED9			; LED9 点灯

	CALL	HOLD_LED			; LED 点灯をしばらくホールド

;--------------------------------------------------------------------------------
;	LED10 以上の電圧?
;--------------------------------------------------------------------------------

	MOVF	VOLTAGE,W			; 測定電圧値を読み出す
	SUBLW	LED10_V				; LED10_V - VOLTAGE -> W
	BTFSC	STATUS,C			; LED10_V 以上なら借り入れが発生するので C=0 となり、次の命令がスキップされる
	GOTO	ALL_LED_OFF

	BCF		PORTA,LED9			; ひとつ前の LED を消す
	CALL	WAIT_2us
	BSF		PORTA,LED10			; LED10 点灯

	CALL	HOLD_LED			; LED 点灯をしばらくホールド

	RETURN

;--------------------------------------------------------------------------------
;	LED 全消灯
;--------------------------------------------------------------------------------

ALL_LED_OFF:

	CLRF	PORTB				; LED3-8 消灯
	BCF		PORTA, LED1
	BCF		PORTA, LED2
	BCF		PORTA, LED9
	BCF		PORTA, LED10

	RETURN

;--------------------------------------------------------------------------------
;	LED 表示を一定時間保持
;--------------------------------------------------------------------------------

HOLD_LED:

	CALL	WAIT_1ms
	CALL	WAIT_1ms

	RETURN

;--------------------------------------------------------------------------------
;	LED 表示を一定時間保持（長め）
;--------------------------------------------------------------------------------

HOLD_LED_LONG:

	CALL	WAIT_100ms
	RETURN

;--------------------------------------------------------------------------------
;	全 LED 点滅表示
;--------------------------------------------------------------------------------

BLINK_LED:

	CALL	ALL_LED_OFF			; 全 LED 消灯
	CALL	HOLD_LED_LONG

	MOVLW	D'2'				; LED BLINK 回数
	MOVWF	BLINK_COUNTER

BLINK:

	MOVLW	B'11001100'			; 全 LED を点滅させて正常起動をアピール
	MOVWF	PORTA
	MOVLW	B'11111111'
	MOVWF	PORTB
	CALL	WAIT_100ms

	CALL	ALL_LED_OFF			; 全消灯
	CALL	WAIT_100ms

	DECFSZ	BLINK_COUNTER,F
	GOTO	BLINK				; 所定回数未満ならループ

	CALL	HOLD_LED_LONG
	CALL	ALL_LED_OFF			; 全 LED 消灯

	RETURN

;--------------------------------------------------------------------------------
;	LED ダイナミック表示ループの回数を初期化
;--------------------------------------------------------------------------------

SET_DISPLAY_COUNTER:

	MOVLW	D'10'				; 短め（電流表示用）
	MOVWF	DISPLAY_COUNTER		; ダイナミック表示を行う際のカウンタ

	RETURN

SET_DISPLAY_COUNTER2:			; 長め（電池電圧表示用）

	MOVLW	D'50'				; 
	MOVWF	DISPLAY_COUNTER		; ダイナミック表示を行う際のカウンタ

	RETURN

;--------------------------------------------------------------------------------
;	割り込み処理用カウンタをクリア
;--------------------------------------------------------------------------------

SET_INT_COUNTER:

	MOVLW	D'40'			; 240ms x 40 = 9.6 sec 毎に割り込み処理
	MOVWF	INT_COUNTER		; カウンタを初期化

	RETURN

;--------------------------------------------------------------------------------
;	電池電圧表示（TMR1割り込みで飛んでくる）
;--------------------------------------------------------------------------------

DISPLAY_BATTERY_VOLTAGE:

	BSF		ADCON0,3			; AN1 使用（電池電圧を読む）
	CALL	READ_VOLTAGE		; 電圧を読んで
	BCF		ADCON0,3			; AN0 使用に戻す（電流を読む）

	MOVF	VOLTAGE_TMP,W
	MOVWF	BATTERY_V			; 電池電圧表示用としてストア

	CALL	READ_VOLTAGE		; アナログポートのチャージを廃棄

	CALL	ALL_LED_OFF			; 念のため全消灯

	CALL	WAIT_100ms
	CALL	WAIT_100ms

	CALL	SET_DISPLAY_COUNTER2	; LED 表示回数をリセット（長め）

;--------------------------------------------------------------------------------
;	電池電圧の LED 表示ループ
;--------------------------------------------------------------------------------

BATTERY_DISPLAY2:

	CALL	BATTERY_DISPLAY	; LED 表示

	DECFSZ	DISPLAY_COUNTER,F
	GOTO	BATTERY_DISPLAY2	; 所定回数まで表示

	CALL	WAIT_100ms
	CALL	WAIT_100ms

	RETURN

;--------------------------------------------------------------------------------
;	電池電圧 LED 表示サブルーチン
;--------------------------------------------------------------------------------

BATTERY_DISPLAY:

;--------------------------------------------------------------------------------
;	左端点灯
;--------------------------------------------------------------------------------

	BSF		TRISA,LED1			; 左端点灯
	CALL	HOLD_LED
	BCF		TRISA,LED1

;--------------------------------------------------------------------------------
;	どの LED を点灯させるか ?
;--------------------------------------------------------------------------------

	CLRF	LED_BIT				; どのポートを点灯させるべきかのフラグ

	MOVF	BATTERY_V,W			; 測定電圧値を読み出す
	SUBLW	BATTERY_LED2_V		; LED2_V - VOLTAGE -> W
	BTFSC	STATUS,C			; LED2_V 以上なら借り入れが発生するので C=0 となり、次の命令がスキップされる
	GOTO	RIGHT_LED_ON		; LED2 すら付かない

	MOVF	BATTERY_V,W			; 測定電圧値を読み出す
	SUBLW	BATTERY_LED3_V		; LED3_V - VOLTAGE -> W
	BTFSC	STATUS,C			; LED3_V 以上なら借り入れが発生するので C=0 となり、次の命令がスキップされる
	GOTO	LED2_ON				; LED2 点灯

	BSF		LED_BIT,0			; 0bit目(LED3) = 1

	MOVF	BATTERY_V,W			; 測定電圧値を読み出す
	SUBLW	BATTERY_LED4_V		; LED4_V - VOLTAGE -> W
	BTFSC	STATUS,C			; LED4_V 以上なら借り入れが発生するので C=0 となり、次の命令がスキップされる
	GOTO	SET_LED_PORT		; LED3 点灯

	BCF		LED_BIT,0
	BSF		LED_BIT,1			; 1bit目(LED4) = 1

	MOVF	BATTERY_V,W			; 測定電圧値を読み出す
	SUBLW	BATTERY_LED5_V		; LED5_V - VOLTAGE -> W
	BTFSC	STATUS,C			; LED5_V 以上なら借り入れが発生するので C=0 となり、次の命令がスキップされる
	GOTO	SET_LED_PORT		; LED4 点灯

	BCF		LED_BIT,1
	BSF		LED_BIT,2			; 2bit目(LED5) = 1

	MOVF	BATTERY_V,W			; 測定電圧値を読み出す
	SUBLW	BATTERY_LED6_V		; LED6_V - VOLTAGE -> W
	BTFSC	STATUS,C			; LED6_V 以上なら借り入れが発生するので C=0 となり、次の命令がスキップされる
	GOTO	SET_LED_PORT		; LED5 点灯

	BCF		LED_BIT,2
	BSF		LED_BIT,3			; 3bit目(LED6) = 1

	MOVF	BATTERY_V,W			; 測定電圧値を読み出す
	SUBLW	BATTERY_LED7_V		; LED7_V - VOLTAGE -> W
	BTFSC	STATUS,C			; LED7_V 以上なら借り入れが発生するので C=0 となり、次の命令がスキップされる
	GOTO	SET_LED_PORT		; LED6 点灯

	BCF		LED_BIT,3
	BSF		LED_BIT,4			; 4bit目(LED7) = 1

	MOVF	BATTERY_V,W			; 測定電圧値を読み出す
	SUBLW	BATTERY_LED8_V		; LED8_V - VOLTAGE -> W
	BTFSC	STATUS,C			; LED8_V 以上なら借り入れが発生するので C=0 となり、次の命令がスキップされる
	GOTO	SET_LED_PORT		; LED7 点灯

	BCF		LED_BIT,4
	BSF		LED_BIT,5			; 5bit目(LED8) = 1

	MOVF	BATTERY_V,W			; 測定電圧値を読み出す
	SUBLW	BATTERY_LED9_V		; LED9_V - VOLTAGE -> W
	BTFSC	STATUS,C			; LED9_V 以上なら借り入れが発生するので C=0 となり、次の命令がスキップされる
	GOTO	SET_LED_PORT		; LED8 点灯

;--------------------------------------------------------------------------------
;	真ん中点灯
;--------------------------------------------------------------------------------

LED9_ON:

	BSF		PORTA,LED9			; LED 9 点灯
	CALL	HOLD_LED
	BCF		PORTA,LED9			; 消灯
	GOTO	RIGHT_LED_ON

LED2_ON:

	BSF		PORTA,LED2			; 点灯
	CALL	HOLD_LED
	BCF		PORTA,LED2			; 消灯
	GOTO	RIGHT_LED_ON

SET_LED_PORT:

	MOVF	LED_BIT,W
	MOVWF	PORTB				; LED 点灯
	CALL	HOLD_LED
	CLRF	PORTB				; 消灯

;--------------------------------------------------------------------------------
;	右端点灯
;--------------------------------------------------------------------------------

RIGHT_LED_ON:

	BSF		TRISA,LED10			; 右端点灯
	CALL	HOLD_LED
	BCF		TRISA,LED10

	RETURN

;--------------------------------------------------------------------------------
;	時間待ちサブルーチン
;--------------------------------------------------------------------------------

WAIT_2us:				; 8MHz時だいたい2us

	MOVLW	D'1'
	MOVWF	COUNTER2
	GOTO	WAIT_LOOP0

WAIT_100us:

	MOVLW	D'50'
	MOVWF	COUNTER2

WAIT_LOOP0:

	NOP
	DECFSZ	COUNTER2,F
	GOTO	WAIT_LOOP0

	RETURN

WAIT_1ms:

	MOVLW	D'2'
	GOTO	SET_COUNTER

WAIT_10ms:

	MOVLW	D'20'
	GOTO	SET_COUNTER

WAIT_100ms:

	MOVLW	D'200'
	GOTO	SET_COUNTER

;--------------------------------------------------------------------------------
;	時間待ちサブルーチン・コア部分、4MHz 時 1ms ループ
;	（クロック 4MHz 時 1 step = 1/4000000 x 4 (sec) = 1μs）
;--------------------------------------------------------------------------------

SET_COUNTER:

	MOVWF	COUNTER1

WAIT_LOOP1:

	MOVLW	H'F9'		; 4MHz 時 F9H で 1ms のループになる
	MOVWF	COUNTER2

WAIT_LOOP2:

	NOP
	DECFSZ	COUNTER2,F
	GOTO	WAIT_LOOP2

	DECFSZ	COUNTER1,F
	GOTO	WAIT_LOOP1

	RETURN

;--------------------------------------------------------------------------------
;	プログラム終了
;--------------------------------------------------------------------------------

	END
