;******************************************************
; アンプ&機体発見器   << PIC12F675 >> Nakasige-Tosikazu
; Version 2.30
;
; リポ　2S(7.4V) 3S(11.1V)対応
;
; 2005/02/15
; 2005/10/30
;******************************************************
;======================================================
;;発振器を４MHz
;- input -
#DEFINE     P_BATTERY   GPIO,0      ;GP0 = カット電圧入力
#DEFINE     P_IN        GPIO,1      ;GP1 = 信号線入力
;- output -
#DEFINE     P_BEEP      GPIO,2      ;GB2 = ブーザー
#DEFINE     P_DRIVE     GPIO,4      ;GP4 = モータドライブ
#DEFINE     P_BRAKE     GPIO,5      ;GP5 = ブレーキ
;                       
    LIST        P=PIC12F675
    INCLUDE     "P12F675.INC"
;
CB = _CPD_OFF               ;データEEPROMもプログラム・メモリも
CB &= _CP_OFF               ;コード・プロテクトしない
CB &= _BODEN_OFF            ;ブラウンアウト・リセットを使わない
CB &= _MCLRE_OFF            ;MCLRリセットを使わないがＨにしておく
CB &= _PWRTE_ON             ;パワーアップ・タイマを使う
CB &= _WDT_ON               ;ウォッチドッグ・タイマを使う
CB &= _INTRC_OSC_NOCLKOUT   ;内部発振器を使う

    __CONFIG CB             ;3F8C -> 3='11'BANDGAP

    __IDLOCS H'0230'        ;バージョン2.30
;
;----------------------
; Data Define
;----------------------
    CBLOCK          H'20'
            C_TIM1          ;遅延タイマカウンタ
            C_TIM2          ;遅延タイマカウンタ
            C_TIM3          ;遅延タイマカウンタ
            C_ADH           ;バッテリのA/D値 H側
            C_ADL           ;バッテリのA/D値 L側
            C_OUT           ;出力用変数
            C_CEL           ;バッテリ種類  2ｾﾙ=0H 3ｾﾙ=1H
            C_LOW           ;ステッイクのLOW判断カウンタ
            C_IN            ;入力信号用カウンタ
            C_NON1          ;入力信号なし用カウンタ
            C_NON2          ;入力信号なし用カウンタ
            C_ON            ;モータドライブ用 ONカウンタ
            C_OFF           ;モータドライブ用OFFカウンタ
            C_H             ;モータドライブ用PMW Hカウンタ
            C_L             ;モータドライブ用PMW Lカウンタ
            C_TEMP          ;汎用変数
            C_BATT          ;バッテリ定期判断カウンタ
            C_STOP          ;ローバッテリ
            C_END           ;ローバッテリで終了

    ENDC
;======================================================
;  Start program
;======================================================
;START
        ORG     H'0'        ;0番地スタート
        CALL    H'3FF'      ;内部発振器をキャリブレーションする
        BSF     STATUS,RP0
        MOVWF   OSCCAL      ;キャリブレーションデータを書く
        BCF     STATUS,RP0
        GOTO    MAIN
;
;======================================================
;  SubRoutines
;======================================================
;----------------------
;100us Timer Subroutine
;----------------------(101us)
TIM99
        MOVLW   D'24'       ;24回
        MOVWF   C_TIM1      ;ここまでで２サイクル
TIM99LP
        NOP
        DECFSZ  C_TIM1,F    ;このループは4サイクル
        GOTO    TIM99LP     ;2+4*24-1=97
        RETLW   0           ;97+2=99*1usec=99usec
;----------------------
;100ms Timer Subroutine
;----------------------(100ms)
TIME100ms
        MOVLW   D'148'      ;
        MOVWF   C_TIM1      ;
        MOVLW   D'100'      ;
        MOVWF   C_TIM2      ;ここまで4サイクル
TIMELP100ms
        NOP                 ;
        DECFSZ  C_TIM1,F    ;
        GOTO    TIMELP100ms ;4X148X 1= 592
        MOVLW   D'250'      ;4X250X99=99000
        MOVWF   C_TIM1      ;
        DECFSZ  C_TIM2,F    ;
        GOTO    TIMELP100ms ;4X100=400
        NOP                 ;4+592+400+99000+3=99,999
        RETLW   0           ;100,000usec
;
;----------------------
;BATTERY     Subroutine
;----------------------(59us)
BATT
       ;----- A/Dコンバータを電源オン -----
        MOVLW   B'00000001' ;結果データは左詰にする
                            ;リファレンス電圧はVddを使う
                            ;GP0/AN0ピンから入力する
        MOVWF   ADCON0      ;A/Dコンバータを電源オンする
BATT010
        ;----- 蓄積時間の待ち -----
        MOVLW   D'7'        ;7回
        MOVWF   C_TIM1      ;ここまでで2サイクル
BATT015
        DECFSZ  C_TIM1,F    ;このループは3サイクル
        GOTO    BATT015     ;2+3*7-1=22us
BATT020
        ;----- A/D変換開始 -----
        BSF     ADCON0,GO   ;A/D変換開始する
BATT030
        ;----- A/D変換時間待ち -----
        MOVLW   D'7'        ;7回
        MOVWF   C_TIM1      ;ここまでで2サイクル
BATT035
        DECFSZ  C_TIM1,F    ;このループは3サイクル
        GOTO    BATT035     ;2+3*7-1=22us
BATT040
        ;----- A/D変換終了確認 -----
        BTFSC   ADCON0,GO   ;ADCON0,GOが０になるとA/D変換終了
        GOTO    BATT040     ;A/D変換終了待ち
BATT050
        ;----- A/D変換結果の代入 -----
        MOVF    ADRESH,W    ;A/D変換結果をWに代入
        MOVWF   C_ADH       ;WからC_C_ADHに代入 左詰めで、こちらだけで２５６分解能
        BSF     STATUS,RP0  ;STATUSレジスタのRP0ビットを１にBank1(Page1)に
        MOVF    ADRESL,W    ;A/D変換結果をWに代入
        BCF     STATUS,RP0  ;Bank0(Page0)に戻る
        MOVWF   C_ADL       ;WからC_C_ADLに代入
BATT060
        RETLW   0           ;サブルーチンの終了リターン
;
;----------------------
;LowBATTERY  Subroutine
;----------------------(79us)
LowBATT
        ;===== モータ停止時のバッテリーチェック =====
LowBATT010
        ;----- A/D変換 -----
        CALL    BATT        ;計算結果が0ならば、Z=1なのでA/D変換へ分岐
        MOVF    C_ADH,W     ;A/D変換結果
        MOVWF   C_OUT       ;出力用の変数に代入
LowBATT020
        ;----- バッテリ電圧値表示 -----
        CLRWDT
        BTFSS   C_CEL,0     ;レジスタの第0ビット目が1だったらスキップ
        GOTO    LowBATT030  ;2ｾﾙと判断
        GOTO    LowBATT040  ;3ｾﾙと判断
LowBATT030
        ;----- 2ｾﾙの係数を代入 -----
        MOVLW   D'84'       ;カット電圧           6.0V
        MOVWF   C_STOP      ;係数を変数に代入
        GOTO    LowBATT050  ;
LowBATT040
        ;----- 3ｾﾙの係数を代入 -----
        MOVLW   D'126'      ;カット電圧           9.0V
        MOVWF   C_STOP      ;係数を変数に代入
LowBATT050
        ;----- カット電圧を判断 -----
        CLRWDT
        MOVF    C_STOP,W    ;カット電圧の係数をWへ代入
        SUBWF   C_OUT,W     ;C_OUT - C_STOP = W
        BTFSS   STATUS,C    ;計算結果がO以上ならば、(C=1)スキップへ
        GOTO    LowBATT060  ;終了と判断
        GOTO    LowBATT070  ;継続と判断
LowBATT060
        ;----- モータストップのための処理 -----
        CALL    ReStart     ;ＲＥスタート処理
        GOTO    LowBATT     ;終了で待つ
LowBATT070
        RETLW   0           ;LowBATTサブルーチンの終了リターン
;
;----------------------
;Position    Subroutine
;----------------------
POSITION
        ;===== ステックのＬＯＷ位置を検知する =====
PS010
        CLRWDT
        BTFSC   P_IN        ;入力信号がＬかどうか       【BTFSC】０だったらスキップ 
        GOTO    PS010       ;入力信号がＬになれば下の処理へ
PS020
        CLRWDT
        BTFSS   P_IN        ;入力信号がＨかどうか       【BTFSS】１だったらスキップ 
        GOTO    PS020       ;入力信号がＨになれば下の処理へ
PS030
        CLRWDT
        BTFSC   P_IN        ;入力信号がＬかどうか       【BTFSC】０だったらスキップ 
        GOTO    PS030       ;入力信号がＬになれば下の処理へ
        CLRF    C_IN        ;入力信号用カウンタ 初期クリア
PS040   
        ;-----  信号の幅を計測 (106us)-----
        INCF    C_IN,F      ;入力信号用カウンタに＋１
        CALL    TIM99       ;100usタイマー
        BTFSS   P_IN        ;入力信号がＨかどうか       【BTFSS】１だったらスキップ 
        GOTO    PS040       ;入力信号がＨになれば下の処理へ
PS050   
        ;-----  信号の幅を判断 -----
        MOVLW   D'13'       ;13をWORKへ代入(1200usよりの大小比較)
        SUBWF   C_IN,W      ;C_IN - 13 = W  1300-100(1ｻｲｸﾙ)=1200us
        BTFSS   STATUS,C    ;計算結果がO以上ならば、(C=1)スキップへ
        GOTO    PS060       ;Low側
        GOTO    PS010       ;もう一度
PS060
        ;-----  Low側 NEXT -----
        RETLW   0           ;POSITIONサブルーチンのリターン
;
;----------------------
;ReStart     Subroutine
;----------------------
ReStart
        ;===== LowBatt時のReStart処理 =====
        MOVLW   D'70'       ;約108usX70=約7565usX70 =0.53秒
        MOVWF   C_NON1      ;入力信号なし用カウンタ
        MOVWF   C_NON2      ;入力信号なし用カウンタ
RE010
        ;-----  入力信号がＨの場合信号なしを検知 -----
        CLRWDT
        BTFSS   P_IN        ;入力信号がＨかどうか       【BTFSS】１だったらスキップ 
        GOTO    RE050       ;入力信号がＨになれば下の処理へ
        CALL    TIM99       ;100usタイマー
RE020
        ;----- C_NONが(約108usX70=約7565usX70 =0.53秒)で本当の入力信号なしとする -----
        DECF    C_NON1,F    ;NON1のカウントダウン
        BTFSS   STATUS,Z    ;Oになればスキップ
        GOTO    RE010       ;まだ信号なしと判断しない
RE030
        MOVLW   D'70'       ;NON1を0->70に戻す
        MOVWF   C_NON1      ;
        DECF    C_NON2,F    ;NON2のカウントダウン
        BTFSS   STATUS,Z    ;Oになればスキップ
        GOTO    RE010       ;まだ信号なしと判断しない
RE040
        ;----- C_NONが(約108usX70=約7565usX70 =0.53秒)で本当の入力信号なしとする -----
        CALL    BEEPloop    ;OSOブザーを鳴らす
        GOTO    RE010       ;まだ信号なしと判断しない
RE050
        ;----- 入力信号を検知 -----
        CLRWDT
        BTFSS   P_IN        ;入力信号がＨかどうか       【BTFSS】１だったらスキップ 
        GOTO    RE050       ;入力信号がＨになれば下の処理へ
RE060
        CLRWDT
        BTFSC   P_IN        ;入力信号がＬかどうか       【BTFSC】０だったらスキップ 
        GOTO    RE060       ;入力信号がＬになれば下の処理へ
        CLRF    C_IN        ;入力信号用カウンタ 初期クリア
RE070   
        ;===== ステックのＬＯＷ位置を検知する =====
        ;-----  信号の幅を計測 (106us)-----
        INCF    C_IN,F      ;入力信号用カウンタに＋１
        CALL    TIM99       ;100usタイマー
        BTFSS   P_IN        ;入力信号がＨかどうか       【BTFSS】１だったらスキップ 
        GOTO    RE070       ;入力信号がＨになれば下の処理へ
RE080   
        ;-----  信号の幅を判断 -----
        MOVLW   D'13'       ;13をWORKへ代入(1200usよりの大小比較)
        SUBWF   C_IN,W      ;C_IN - 13 = W  1300-100(1ｻｲｸﾙ)=1200us
        BTFSS   STATUS,C    ;計算結果がO以上ならば、(C=1)スキップへ
        GOTO    RE090       ;Low側
        GOTO    ReStart     ;もう一度
RE090
        ;-----  Low側 NEXT -----
        CALL    beepL       ;長音
        RETLW   0           ;POSITIONサブルーチンのリターン
;
;----------------------
;OSO Beep    Subroutine
;----------------------(3.600067s)
        ;===== ブザーをOSO鳴らす =====
BEEPloop
        CALL    beepL       ;長音
        CALL    beepL       ;長音
        CALL    beepL       ;長音
        CALL    TIME100ms   ;100ms
        CALL    TIME100ms   ;100ms
        CALL    beepS       ;短音
        CALL    beepS       ;短音
        CALL    beepS       ;短音
        CALL    TIME100ms   ;100ms
        CALL    TIME100ms   ;100ms
        CALL    beepL       ;長音
        CALL    beepL       ;長音
        CALL    beepL       ;長音
        CALL    TIME100ms   ;100ms
        CALL    TIME100ms   ;100ms
        RETLW   0           ;
BEEPloopEND
;----------------------
beepL
        ;===== 長音 =====
        CLRWDT
        BSF     P_BEEP      ;ブザーを鳴らす
        CALL    TIME100ms   ;100ms
        CALL    TIME100ms   ;100ms
        CALL    TIME100ms   ;100ms
        BCF     P_BEEP      ;ブザーを鳴らさない
        CALL    TIME100ms   ;100ms
        RETLW   0           ;
;----------------------
beepS
        ;===== 短音 =====
        CLRWDT
        BSF     P_BEEP      ;ブザーを鳴らす
        CALL    TIME100ms   ;100ms
        BCF     P_BEEP      ;ブザーを鳴らさない
        CALL    TIME100ms   ;100ms
        RETLW   0           ;
;----------------------
;
;----------------------
;STOP Motor  Subroutine
;----------------------(10us)
        ;===== モーターを止める =====
STOP010
        ;----- モータの停止の処理 -----
        BSF     P_DRIVE     ;レジスタを１にしてモータを止める
        BSF     P_BRAKE     ;レジスタを１にしてブレーキ
STOP020
        ;----- 作用幅の代入 (C_ON=MIN C_OFF=MAX) -----
        MOVLW   D'1'        ;1をWORKへ代入
        MOVWF   C_ON        ;WをC_ONに代入
        MOVLW   D'14'       ;14をWORKへ代入
        MOVWF   C_OFF       ;WをC_OFFに代入
        RETLW   0           ;
;
;----------------------
;IN to PMW   Subroutine
;----------------------(45us)
INpmw   ;
        CLRWDT
        ;===== 入力信号がＬ(信号あり)Ｈ(信号なし)の信号を判断 =====
        BTFSC   P_IN        ;入力信号がＬかどうか           【BTFSC】０だったらスキップ 
        GOTO    NON010      ;入力信号がＬにならばスキップ、Ｈならば信号なしNON010へ
;----------------------------------------------------------------------
        ;----- 入力信号がＬ(信号あり) -----
IN010
        ;----- 入力信号のカウント -----
        INCF    C_IN,F      ;入力信号用カウンタに＋１       【INCF】ｆのカウントアップ 
IN020
                            ;スイッチの切断時の対策???
        MOVLW   D'42'       ;約53usX42=2200us以上は信号異常とする
        SUBWF   C_IN,W      ;C_IN - 40 = W
        BTFSC   STATUS,C    ;計算結果がマイナスならば、信号OKなのでスキップへ
        CLRF    C_IN        ;入力信号用カウンタクリア
IN030
        ;----- 信号なしカウンタの初期設定 ----
        MOVLW   D'100'      ;約53usX100=5300
        MOVWF   C_NON1      ;入力信号なし用カウンタ
        MOVLW   D'100'      ;約5300usX100 =0.53秒
        MOVWF   C_NON2      ;入力信号なし用カウンタ
IN040
        ;----- 全体時間補正 -----
        MOVLW   D'9'        ;9回
        MOVWF   C_TIM1      ;ここまでで２サイクル
IN040LP
        DECFSZ  C_TIM1,F    ;このループは3サイクル
        GOTO    IN040LP     ;2+3*9-1=28
        NOP                 ;29usec
        RETLW   0           ;INpmwサブルーチンの終了リターン
;
;----------------------------------------------------------------------
        ;===== 入力信号がＨの場合は、≪信号なしのカウント≫ (6+34us=45us) =====
NON010
        ;----- C_NONが1回目はﾊﾟﾙｽ立ち上がり(入力信号終了)と考え ＰＭＷ生成へ分岐 ------
        MOVLW   D'100'      ;Wに100を代入
        SUBWF   C_NON2,W    ;C_NON2 - 100 = W
        BTFSS   STATUS,Z    ;計算結果が0ならば、(Z=1)スキップへ
        GOTO    NON020      ;1回目でない
;
        MOVLW   D'100'      ;Wに100を代入
        SUBWF   C_NON1,W    ;C_NON2 - 100 = W
        BTFSS   STATUS,Z    ;計算結果が0ならば、(Z=1)スキップへ
        GOTO    NON030      ;1回目でない
        DECF    C_NON1,F    ;1回目なのでNON1のカウントダウン
        GOTO    CHEK010     ;1回目なので定期的に電圧チェックかＰＭＷ生成へ
NON020
        NOP                 ;NON010の時間補正
        NOP
        NOP
        NOP
NON030
        ;----- C_NONが10000回(約53usX10000=約0.53秒)で本当の入力信号なしとする -----
        DECF    C_NON1,F    ;NON1のカウントダウン
        BTFSS   STATUS,Z    ;Oになればスキップ
        GOTO    NON050      ;まだ信号なしと判断しない
;
        MOVLW   D'100'      ;NON1を0->100に戻す
        MOVWF   C_NON1      ;
        DECF    C_NON2,F    ;NON2のカウントダウン
        BTFSS   STATUS,Z    ;Oになればスキップ
        GOTO    NON060      ;まだ信号なしと判断しない
NON040
        ;----- モータストップのための処理 -----
        MOVLW   D'100'      ;NON2を0->100に戻す
        MOVWF   C_NON2      ;
        CALL    STOP010     ;モーターを止める
        CALL    BEEPloop    ;OSOブザーを鳴らす
        GOTO    NON070      ;時間補正へ
NON050
        ;----- 時間補正 -----5us
        NOP                 ;NON030の時間補正
        NOP
        NOP
        NOP
        NOP
NON060
        ;----- 時間補正 -----19us
        MOVLW   D'6'        ;6回   NON040の時間補正
        MOVWF   C_TIM1      ;ここまでで２サイクル
NON060LP
        DECFSZ  C_TIM1,F    ;このループは3サイクル
        GOTO    NON060LP    ;2+3*6-1=19usec
NON070
        RETLW   0           ;INpmwサブルーチンの終了リターン
;
;----------------------------------------------------------------------
        ;===== 入力信号幅によってモータ制御PMW数 計算処理 (17+92us=108us) =====
CHEK010
        ;----- 定期的に電圧ﾁｪｯｸをする -----
        DECF    C_BATT,F    ;C_BATT - 1 = C_BATT
        BTFSS   STATUS,Z    ;計算結果が0ならば、Z=1なのでスキップ
        GOTO    CALK010     ;計算結果が0以外ならばCALK010へ分岐
        CALL    BATT        ;計算結果が0ならば、Z=1なのでA/D変換へ分岐
        MOVF    C_ADH,W     ;A/D変換結果
        MOVWF   C_OUT       ;出力用の変数に代入
CHEK020
        ;----- バッテリ電圧値表示 -----
        CLRWDT
        BTFSS   C_CEL,0     ;レジスタの第0ビット目が1だったらスキップ
        GOTO    CHEK030     ;2ｾﾙと判断
        GOTO    CHEK040     ;3ｾﾙと判断
CHEK030
        ;----- 2ｾﾙの係数を代入 -----
        MOVLW   D'69'       ;カット電圧           5.0V
        MOVWF   C_STOP      ;係数を変数に代入
        GOTO    CHEK050     ;
CHEK040
        ;----- 3ｾﾙの係数を代入 -----
        MOVLW   D'105'      ;カット電圧           7.5V
        MOVWF   C_STOP      ;係数を変数に代入
CHEK050
        ;----- カット電圧を判断 -----
        CLRWDT
        MOVF    C_STOP,W    ;カット電圧の係数をWへ代入
        SUBWF   C_OUT,W     ;C_OUT - C_STOP = W
        BTFSS   STATUS,C    ;計算結果がO以上ならば、(C=1)スキップへ
        GOTO    CHEK060     ;終了と判断
        GOTO    CHEK070     ;継続と判断
CHEK060
        ;----- モータストップのための処理 -----
        CALL    STOP010     ;モーターを止める
        CALL    ReStart     ;ＲＥスタート処理
CHEK070
        CLRF    C_IN        ;入力信号用カウンタクリア
        RETLW   0           ;INpmwサブルーチンの終了リターン
;
;----------------------------------------------------------------------
        ;===== 入力信号幅によってモータ制御PMW数 計算処理 (21+24us=45us) =====
CALK010
        ;----- LOW 作用幅をチェックと代入 -----
        MOVLW   D'24'       ;24をWORKへ代入(1166usよりの小さければ1166usとする)
        SUBWF   C_IN,W      ;C_IN - 24     (53usX24=1272us)
        BTFSS   STATUS,C    ;C_INが大きいければスキップ C_IN >=24
        GOTO    CALK040     ;C_ON=MIN C_OFF=MAX         C_IN < 24
CALK020
        ;----- HIGH 作用幅をチェックと代入 -----
        MOVLW   D'36'       ;36をWORKへ代入(1802usよりの大きければ1802usとする)
        SUBWF   C_IN,W      ;C_IN - 36     (53usX36=1908us)
        BTFSC   STATUS,C    ;C_INが小さければスキップ   C_IN < 36
        GOTO    CALK050     ;C_ON=MAX C_OFF=MIN         C_IN >=36
CALK030
        ;----- 作用幅の代入 (計算) -----
        MOVLW   D'15'       ;15をC_TEMPへ代入
        MOVWF   C_TEMP      ;C_TEMP = 15
        MOVLW   D'22'       ;22をWORKへ代入
        SUBWF   C_IN,W      ;C_IN - 22 = C_ON  (24～36=>2～13回にする)
        MOVWF   C_ON        ;WをC_ONに代入
        SUBWF   C_TEMP,W    ;15 - C_ON = C_OFF (24～36=>13～2回にする)
        MOVWF   C_OFF       ;WをC_OFFに代入
        GOTO    CALK060     ;
CALK040
        ;----- 作用幅の代入 (C_ON=MIN C_OFF=MAX) -----
        MOVLW   D'1'        ;1をWORKへ代入(作用幅を53usX14=742usとする)
        MOVWF   C_ON        ;WをC_ONに代入
        MOVLW   D'14'       ;14をWORKへ代入
        MOVWF   C_OFF       ;WをC_OFFに代入
        NOP
        NOP
        NOP
        GOTO    CALK060     ;
CALK050
        ;----- 作用幅の代入 (C_ON=MAX C_OFF=MIN) -----
        MOVLW   D'14'       ;14をWORKへ代入(作用幅を53usX14=742usとする)
        MOVWF   C_ON        ;WをC_ONに代入
        MOVLW   D'1'        ;1をWORKへ代入
        MOVWF   C_OFF       ;WをC_OFFに代入
        NOP
        NOP
        NOP
        GOTO    CALK060     ;
CALK060
        ;----- 変数の再初期設定 -----
        CLRF    C_IN        ;入力信号用カウンタ
        NOP
CALK070
        ;----- 全体時間補正 -----
        NOP
        NOP                 
        NOP
        NOP
        NOP
        NOP
        RETLW   0           ;INpmwサブルーチンの終了リターン
;
;======================================================
;  Main Routine
;======================================================
MAIN
;----------------------
; Initialize Routine
;----------------------
INIT
        ; ----- 初期設定 -----
        BSF     STATUS,RP0  ;STATUSレジスタのRP0ビットを１に
                            ;してBank1(Page1)に切替える     【BSF】 ｆ レジスタの指定ビットを１にする
        MOVLW   B'11111110' ;弱プルアップなし
        MOVWF   OPTION_REG  ;WDTのTimeOutは18ms*64=1.152秒
        MOVLW   B'00001011' ;GP0,1入力にする
        MOVWF   TRISIO      ;GP2,4,5ピンを出力にする
        BCF     STATUS,RP0  ;Bank0(Page0)に戻る             【BCF】 ｆ レジスタの指定ビットを０にする 
        MOVLW   B'00000111' ;GP2/1/0 をデジタルI/Oに設定
        MOVWF   CMCON       ;CMCON = CM0/CM1/CM2 ON (COMPARATOR OFF)
        ;----- A/Dコンバータピンをアナログ設定 -----
        BSF     STATUS,RP0  ;STATUSレジスタのRP0ビットを１にBank1(Page1)に
        MOVLW   B'00110001' ;GP0/AN0ピンをアナログ入力モードにする
        MOVWF   ANSEL       ;A/D変換クロックはFrc(内部RC発振)
        BCF     STATUS,RP0  ;Bank0(Page0)に戻る
       ; ----- 初期クリア -----
        CLRF    C_TIM1      ;遅延タイマカウンタ
        CLRF    C_TIM2      ;遅延タイマカウンタ
        CLRF    C_TIM3      ;遅延タイマカウンタ
        CLRF    C_ADH       ;バッテリのA/D値 H側
        CLRF    C_ADL       ;バッテリのA/D値 L側
        CLRF    C_OUT       ;出力用変数
        CLRF    C_CEL       ;バッテリ種類　2ｾﾙ=0H 3ｾﾙ=1H
        CLRF    C_LOW       ;ステッイクのLOW判断カウンタ
        CLRF    C_IN        ;入力信号用カウンタ
        BSF     P_DRIVE     ;念のためモータを止める
        BSF     P_BRAKE     ;念のためモータブレーキ
        MOVLW   D'100'      ;約55usX100=5500
        MOVWF   C_NON1      ;入力信号なし用カウンタ
        MOVLW   D'100'      ;約5500usX100 =0.55秒
        MOVWF   C_NON2      ;入力信号なし用カウンタ
        CLRF    C_ON        ;モータドライブ用 ONカウンタ
        CLRF    C_OFF       ;モータドライブ用OFFカウンタ
        MOVLW   D'1'        ;1をWORKへ代入(作用幅を55usX13=715us(1155us-1870us)とする)
        MOVWF   C_ON        ;WをC_ONに代入
        MOVLW   D'14'       ;14をWORKへ代入
        MOVWF   C_OFF       ;WをC_OFFに代入
        CLRF    C_H         ;モータドライブ用PMW Highカウンタ
        CLRF    C_L         ;モータドライブ用PMW Lowカウンタ
        CLRF    C_TEMP      ;汎用変数
        CLRF    C_BATT      ;バッテリ定期判断カウンタ
        CLRF    C_STOP      ;ローバッテリ
        CLRF    C_END       ;ローバッテリで終了
;
;----------------------
; Procedure Routine
;----------------------
PROC
        ;-----  開始  -----
        CLRWDT
P010
        ;-----  遅延  -----
        MOVLW   D'15'       ;15回
        MOVWF   C_TIM3      ;ここまでで2サイクル
P015
        CLRWDT
        CALL    TIME100ms   ;100ms Timer Subroutine
        DECFSZ  C_TIM3,F    ;このループは4サイクル
        GOTO    P015        ;100ms*10=約1.5秒
P020
        ;-----  バッテリ電圧値  -----
        CLRWDT
        CALL    BATT        ;A/D変換
        MOVF    C_ADH,W     ;A/D変換結果
        MOVWF   C_OUT       ;出力用の変数に代入
P030
        ;-----  2ｾﾙ・3ｾﾙ バッテリ判断  -----
        CLRWDT
        MOVLW   B'00000000' ;とりあえず2ｾﾙ(0H)に変数セット(9V以下)
        MOVWF   C_CEL       ;バッテリ種類変数に代入
;
        MOVLW   D'126'      ;126をWORKへ代入(9Vの大小比較)
        SUBWF   C_OUT,W     ;C_OUT - 126
        BTFSS   STATUS,C    ;計算結果がO以上ならば、(C=1)スキップへ
        GOTO    P045        ;9V以下
        MOVLW   B'00000001' ;9V以上3ｾﾙ(1H)に変数セット
        MOVWF   C_CEL       ;バッテリ種類変数に代入
P040
        ;-----  2ｾﾙ・3ｾﾙ バッテリ告知Beep  -----
        ;3ｾﾙ Beep3回
        CALL    beepS       ;短音
        CALL    TIME100ms   ;100ms Timer Subroutine
P045
        ;2ｾﾙ Beep2回
        CALL    beepS       ;短音
        CALL    TIME100ms   ;100ms Timer Subroutine
        CALL    beepS       ;短音
P050
        ;-----  遅延  -----
        MOVLW   D'10'       ;10回
        MOVWF   C_TIM3      ;ここまでで2サイクル
P055
        CLRWDT
        CALL    TIME100ms   ;100ms Timer Subroutine
        DECFSZ  C_TIM3,F    ;このループは4サイクル
        GOTO    P055        ;100ms*10=約1.0秒
P060
        ;-----  ステックのLOW確認  -----
        CLRWDT
        CALL    POSITION    ;ステックがLOWになるまで待つ
        BSF     P_BEEP      ;ブザーを鳴らす
        CALL    TIME100ms   ;100ms
        CALL    TIME100ms   ;100ms
        CALL    TIME100ms   ;100ms
        CALL    TIME100ms   ;100ms
        CALL    TIME100ms   ;100ms
        BCF     P_BEEP      ;ブザーを鳴らさない
;
P100
        ;===== モータドライブ (1457Hz 688us/13=53us) =====
        CLRWDT
P110
        ;-----  ブレーキ -----
        DECF    C_ON,W      ;C_ON - 1 = W
        BTFSS   STATUS,Z    ;計算結果が0ならば、Z=1なのでスキップ
        GOTO    P120        ;
        BSF     P_DRIVE     ;レジスタを１にしてモータを止める
        BSF     P_BRAKE     ;レジスタを１にしてブレーキ
        ;-----  モータ停止時のバッテリチェック -----
        DECF    C_END,F     ;ローバッテリで終了　C_END - 1 = C_END
        BTFSS   STATUS,Z    ;計算結果が0ならば、Z=1なのでスキップ
        GOTO    P130        ;計算結果が0以外ならばP130へ分岐
        CALL    LowBATT     ;計算結果が0ならば、Z=1なのでA/D変換へ分岐
        GOTO    P130        ;チェック後容量ＯＫなので続行
P120
        BCF     P_BRAKE     ;レジスタを０にしてブレーキ解除
        CLRF    C_END       ;ローバッテリで終了クリア
P130
        ;----- ＰＭＷ数の代入 -----
        CLRWDT
        MOVF    C_ON,W      ;モータドライブ用 ONカウンタ(1-14)を
        MOVWF   C_H         ;モータドライブ用PMW Highカウンタへ
        MOVF    C_OFF,W     ;モータドライブ用OFFカウンタ(14-1)を
        MOVWF   C_L         ;モータドライブ用PMW Lowカウンタへ
P140
        ;----- C_Hの数でモータＰＭＷドライブ (51us)-----
        DECF    C_H,F       ;C_H - 1 = C_H
        BTFSC   STATUS,Z    ;計算結果が0以外ならば、Z=0なのでスキップ
        GOTO    P150        ;計算結果が0ならば、Z=1なのでP150へ分岐(モータを回さない)
        BCF     P_DRIVE     ;レジスタを０にしてモータを回す
        CALL    INpmw       ;遅延=入力信号のカウント・・（45us）
        GOTO    P140        ;モータＰＭＷのＯＮ
P150
        ;----- C_OFFの数でモータＰＭＷストップ (51us)-----
        DECF    C_L,F       ;C_L - 1 = C_L
        BTFSC   STATUS,Z    ;計算結果が0以外ならば、Z=0なのでスキップ
        GOTO    P160        ;計算結果が0ならば、Z=1なのでP160へ分岐(モータを止めない)
        BSF     P_DRIVE     ;レジスタを１にしてモータを止める
        CALL    INpmw       ;遅延=入力信号のカウント・・（45us）
        GOTO    P150        ;モータＰＭＷのＯＦＦ
P160
        GOTO    P100
;
;----------------------
        END
