;*****************************************************
; 簡易風速計    << PIC16F84A >>
; Version 1.10
; 2006/02/28 Nakasige-Tosikazu
;******************************************************
;======================================================
M01M        EQU         D'20'       ;風速1m時カウント
M02M        EQU         D'40'       ;風速2m時カウント
M03M        EQU         D'60'       ;風速3m時カウント
M04M        EQU         D'80'       ;風速4m時カウント
M05M        EQU         D'100'      ;風速5m時カウント
M06M        EQU         D'120'      ;風速6m時カウント
M07M        EQU         D'140'      ;風速7m時カウント
M08M        EQU         D'160'      ;風速8m時カウント
M09M        EQU         D'180'      ;風速9m時カウント
M10M        EQU         D'200'      ;風速10m時カウント
M11M        EQU         D'220'      ;風速11m時カウント
M12M        EQU         D'240'      ;風速12m時カウント
;======================================================
;;発振器を４MHz
;- input -
#DEFINE     P_IN        PORTA,4     ;RA4 = パルス入力
;- output -
#DEFINE     P_1M        PORTA,0     ;RA0 = 風速1m時LED点灯
#DEFINE     P_2M        PORTA,1     ;RA1 = 風速2m時LED点灯
#DEFINE     P_3M        PORTA,2     ;RA2 = 風速3m時LED点灯
#DEFINE     P_4M        PORTA,3     ;RA3 = 風速4m時LED点灯
#DEFINE     P_5M        PORTB,0     ;RB0 = 風速5m時LED点灯
#DEFINE     P_6M        PORTB,1     ;RB1 = 風速6m時LED点灯
#DEFINE     P_7M        PORTB,2     ;RB2 = 風速7m時LED点灯
#DEFINE     P_8M        PORTB,3     ;RB3 = 風速8m時LED点灯
#DEFINE     P_9M        PORTB,4     ;RB4 = 風速9m時LED点灯
#DEFINE     P_10M       PORTB,5     ;RB5 = 風速10m時LED点灯
#DEFINE     P_11M       PORTB,6     ;RB6 = 風速11m時LED点灯
#DEFINE     P_12M       PORTB,7     ;RB7 = 風速12m時LED点灯
;                       
    LIST        P=PIC16F84
    INCLUDE     "P16F84A.INC"
    __CONFIG _PWRTE_OFF & _WDT_OFF & _XT_OSC
;
;----------------------
; Data Define
;----------------------
    CBLOCK          H'0D'
            W_TEMP          ;割込用、Wレジスタ待避
            ST_TEMP         ;割込用、STATUS待避 
            C_TIM1          ;遅延タイマカウンタ
            C_TIM2          ;遅延タイマカウンタ
            C_TIM3          ;遅延タイマカウンタ
            C_IN            ;入力信号用カウンタ
            C_INTR          ;割込み回数カウンタ
            C_TEMP          ;汎用変数
    ENDC
;======================================================
;  Start program
;======================================================
;START
        ORG     0           ;0番地スタート
        GOTO    MAIN        ;メインへジャンプ
;
        ORG     4           ;4番地スタート
        GOTO    INTR        ;割込みへジャンプ
;
;======================================================
;  SubRoutines
;======================================================
;----------------------
;100us  Timer Subroutine
;----------------------
TIM99us
        MOVLW   D'24'       ;24回
        MOVWF   C_TIM1      ;ここまでで２サイクル
TIM99LP
        NOP
        DECFSZ  C_TIM1,F    ;このループは4サイクル
        GOTO    TIM99LP     ;2+4*24-1=97
        RETURN              ;97+2=99*1usec=99usec
;
;----------------------
;100ms Timer Subroutine
;----------------------
TIM100ms
        MOVLW   D'148'      ;
        MOVWF   C_TIM1      ;
        MOVLW   D'100'      ;
        MOVWF   C_TIM2      ;ここまで4サイクル
TIM100mLP
        NOP                 ;
        DECFSZ  C_TIM1,F    ;
        GOTO    TIM100mLP   ;4X148X 1= 592
        MOVLW   D'250'      ;4X250X99=99000
        MOVWF   C_TIM1      ;
        DECFSZ  C_TIM2,F    ;
        GOTO    TIM100mLP   ;4X100=400
        NOP                 ;4+592+400+99000+3=99,999
        RETURN              ;100,000usec
;
;----------------------
;LED TEST    Subroutine
;----------------------
LEDtest
        ;===== LEDのテストをして、チャタリングの時間稼ぎ =====
Lt01
        MOVLW   D'3'        ;３回繰り返す
        MOVWF   C_TIM3      ;
Lt02
        CALL    TIM100ms    ;100ms Time
        BSF     P_1M        ;レジスタを１にしてＬＥＤ点灯
        CALL    TIM100ms    ;100ms Time
        BCF     P_1M        ;レジスタを０にしてＬＥＤ消灯
        BSF     P_2M        ;レジスタを１にしてＬＥＤ点灯
        CALL    TIM100ms    ;100ms Time
        BCF     P_2M        ;レジスタを０にしてＬＥＤ消灯
        BSF     P_3M        ;レジスタを１にしてＬＥＤ点灯
        CALL    TIM100ms    ;100ms Time
        BCF     P_3M        ;レジスタを０にしてＬＥＤ消灯
        BSF     P_4M        ;レジスタを１にしてＬＥＤ点灯
        CALL    TIM100ms    ;100ms Time
        BCF     P_4M        ;レジスタを０にしてＬＥＤ消灯
        BSF     P_5M        ;レジスタを１にしてＬＥＤ点灯
        CALL    TIM100ms    ;100ms Time
        BCF     P_5M        ;レジスタを０にしてＬＥＤ消灯
        BSF     P_6M        ;レジスタを１にしてＬＥＤ点灯
        CALL    TIM100ms    ;100ms Time
        BCF     P_6M        ;レジスタを０にしてＬＥＤ消灯
        BSF     P_7M        ;レジスタを１にしてＬＥＤ点灯
        CALL    TIM100ms    ;100ms Time
        BCF     P_7M        ;レジスタを０にしてＬＥＤ消灯
        BSF     P_8M        ;レジスタを１にしてＬＥＤ点灯
        CALL    TIM100ms    ;100ms Time
        BCF     P_8M        ;レジスタを０にしてＬＥＤ消灯
        BSF     P_9M        ;レジスタを１にしてＬＥＤ点灯
        CALL    TIM100ms    ;100ms Time
        BCF     P_9M        ;レジスタを０にしてＬＥＤ消灯
        BSF     P_10M       ;レジスタを１にしてＬＥＤ点灯
        CALL    TIM100ms    ;100ms Time
        BCF     P_10M       ;レジスタを０にしてＬＥＤ消灯
        BSF     P_11M       ;レジスタを１にしてＬＥＤ点灯
        CALL    TIM100ms    ;100ms Time
        BCF     P_11M       ;レジスタを０にしてＬＥＤ消灯
        BSF     P_12M       ;レジスタを１にしてＬＥＤ点灯
        CALL    TIM100ms    ;100ms Time
        BCF     P_12M       ;レジスタを０にしてＬＥＤ消灯
        DECFSZ  C_TIM3,F    ;
        GOTO    Lt02        ;
        RETURN              ;戻る
;
;----------------------
;LED UP      Subroutine
;----------------------
LEDup
        ;----- LEDをすべて消す -----
        CLRF    PORTA       ;all clear
        CLRF    PORTB       ;all clear
LEDup010
        ;----- 風速1mＬＥＤ点灯 -----

        MOVLW   M01M        ;EQUをWORKへ代入
        SUBWF   C_IN,W      ;C_IN-EQU=W
        BTFSC   STATUS,C    ;C_IN-EQU<0 (C=0)  【BTFSC】０だったらスキップ
        BSF     P_1M        ;レジスタを１にしてＬＥＤ点灯
LEDup020
        ;----- 風速2mＬＥＤ点灯 -----
        MOVLW   M02M        ;EQUをWORKへ代入
        SUBWF   C_IN,W      ;C_IN-EQU=W
        BTFSC   STATUS,C    ;C_IN-EQU<0 (C=0)  【BTFSC】０だったらスキップ
        BSF     P_2M        ;レジスタを１にしてＬＥＤ点灯
LEDup030
        ;----- 風速3mＬＥＤ点灯 -----
        MOVLW   M03M        ;EQUをWORKへ代入
        SUBWF   C_IN,W      ;C_IN-EQU=W
        BTFSC   STATUS,C    ;C_IN-EQU<0 (C=0)  【BTFSC】０だったらスキップ
        BSF     P_3M        ;レジスタを１にしてＬＥＤ点灯
LEDup040
        ;----- 風速4mＬＥＤ点灯 -----
        MOVLW   M04M        ;EQUをWORKへ代入
        SUBWF   C_IN,W      ;C_IN-EQU=W
        BTFSC   STATUS,C    ;C_IN-EQU<0 (C=0)  【BTFSC】０だったらスキップ
        BSF     P_4M        ;レジスタを１にしてＬＥＤ点灯
LEDup050
        ;----- 風速5mＬＥＤ点灯 -----
        MOVLW   M05M        ;EQUをWORKへ代入
        SUBWF   C_IN,W      ;C_IN-EQU=W
        BTFSC   STATUS,C    ;C_IN-EQU<0 (C=0)  【BTFSC】０だったらスキップ
        BSF     P_5M        ;レジスタを１にしてＬＥＤ点灯
LEDup06
        ;----- 風速6mＬＥＤ点灯 -----
        MOVLW   M06M        ;EQUをWORKへ代入
        SUBWF   C_IN,W      ;C_IN-EQU=W
        BTFSC   STATUS,C    ;C_IN-EQU<0 (C=0)  【BTFSC】０だったらスキップ
        BSF     P_6M        ;レジスタを１にしてＬＥＤ点灯
LEDup070
        ;----- 風速7mＬＥＤ点灯 -----
        MOVLW   M07M        ;EQUをWORKへ代入
        SUBWF   C_IN,W      ;C_IN-EQU=W
        BTFSC   STATUS,C    ;C_IN-EQU<0 (C=0)  【BTFSC】０だったらスキップ
        BSF     P_7M        ;レジスタを１にしてＬＥＤ点灯
LEDup080
        ;----- 風速8mＬＥＤ点灯 -----
        MOVLW   M08M        ;EQUをWORKへ代入
        SUBWF   C_IN,W      ;C_IN-EQU=W
        BTFSC   STATUS,C    ;C_IN-EQU<0 (C=0)  【BTFSC】０だったらスキップ
        BSF     P_8M        ;レジスタを１にしてＬＥＤ点灯
LEDup090
        ;----- 風速9mＬＥＤ点灯 -----
        MOVLW   M09M        ;EQUをWORKへ代入
        SUBWF   C_IN,W      ;C_IN-EQU=W
        BTFSC   STATUS,C    ;C_IN-EQU<0 (C=0)  【BTFSC】０だったらスキップ
        BSF     P_9M        ;レジスタを１にしてＬＥＤ点灯
LEDup100
        ;----- 風速10mＬＥＤ点灯 -----
        MOVLW   M10M        ;EQUをWORKへ代入
        SUBWF   C_IN,W      ;C_IN-EQU=W
        BTFSC   STATUS,C    ;C_IN-EQU<0 (C=0)  【BTFSC】０だったらスキップ
        BSF     P_10M        ;レジスタを１にしてＬＥＤ点灯
LEDup110
        ;----- 風速11mＬＥＤ点灯 -----
        MOVLW   M11M        ;EQUをWORKへ代入
        SUBWF   C_IN,W      ;C_IN-EQU=W
        BTFSC   STATUS,C    ;C_IN-EQU<0 (C=0)  【BTFSC】０だったらスキップ
        BSF     P_11M        ;レジスタを１にしてＬＥＤ点灯
LEDup120
        ;----- 風速12mＬＥＤ点灯 -----
        MOVLW   M12M        ;EQUをWORKへ代入
        SUBWF   C_IN,W      ;C_IN-EQU=W
        BTFSC   STATUS,C    ;C_IN-EQU<0 (C=0)  【BTFSC】０だったらスキップ
        BSF     P_12M        ;レジスタを１にしてＬＥＤ点灯
LEDend
        RETURN              ;戻る
;
;======================================================
;  Main Routine
;======================================================
MAIN
;----------------------
; Initialize Routine
;----------------------
INIT
        ; ----- 初期設定 -----
        BSF     STATUS,RP0  ;STATUSレジスタのRP0ビットを１に
                            ;してBank1(Page1)に切替える     【BSF】 ｆ レジスタの指定ビットを１にする
        MOVLW   B'00000111' ;ＰＯＲＴ Ｂを入力に使う時には内部プルアップをＯＮとする。
        MOVWF   OPTION_REG  ;TMROブリスケーラ256
        MOVLW   B'00010000' ;B'00010000'
        MOVWF   TRISA       ;PORTAを4入力他を出力モードに設定
        MOVLW   B'00000000' ;B'00000000'
        MOVWF   TRISB       ;PORTBをすべて出力モードに設定
        BCF     STATUS,RP0  ;Bank0(Page0)に戻る             【BCF】 ｆ レジスタの指定ビットを０にする 
       ; ----- 初期クリア -----
        BCF     P_1M        ;風速1m時ＬＥＤ消灯
        BCF     P_2M        ;風速2m時ＬＥＤ消灯
        BCF     P_3M        ;風速3m時ＬＥＤ消灯
        BCF     P_4M        ;風速4m時ＬＥＤ消灯
        BCF     P_5M        ;風速5m時ＬＥＤ消灯
        BCF     P_6M        ;風速6m時ＬＥＤ消灯
        BCF     P_7M        ;風速7m時ＬＥＤ消灯
        BCF     P_8M        ;風速8m時ＬＥＤ消灯
        BCF     P_9M        ;風速9m時ＬＥＤ消灯
        BCF     P_10M       ;風速10m時ＬＥＤ消灯
        BCF     P_11M       ;風速11m時ＬＥＤ消灯
        BCF     P_12M       ;風速12m時ＬＥＤ消灯
        CLRF    C_TIM1      ;遅延タイマカウンタ
        CLRF    C_TIM2      ;遅延タイマカウンタ
        CLRF    C_TIM3      ;遅延タイマカウンタ
        CLRF    C_IN        ;入力信号用カウンタ
        MOVLW   D'11'       ;11を代入50msX11=550ms
        MOVWF   C_INTR      ;割込み回数カウンタ
        CLRF    C_TEMP      ;汎用変数
;----------------------
; Procedure Routine
;----------------------
PROC
        ;-----  チャタリングの待ち -----
        CALL    LEDtest     ;LEDのテストで時間稼ぎ
        ; ----- 割込み設定 -----
        ; (50ms) 50000ｶｳﾝﾄ/256 = 195(C3H)
        ; TMROはｱｯﾌﾟｶｳﾝﾀなので FFH-C3H=3CH
        MOVLW   03CH        ;カウント値ロード
        MOVWF   TMR0        ;TMR0へ出力
        BCF     INTCON,T0IF ;ｵｰﾊﾞｰﾌﾛｰフラグクリア
        BSF     INTCON,T0IE ;タイマ割込み許可
        BSF     INTCON,GIE  ;全体割込み許可;
;----------------------
; Loop Routine
;----------------------
P100
        ;-----  立ち上り判断 -----
        CALL    TIM99us     ;ノイズ飛ばし？
        BTFSS   P_IN        ;入力信号がＨかどうか       【BTFSS】１だったらスキップ 
        GOTO    P100        ;入力信号がＨになれば下の処理へ
P110
        ;-----  入力信号のカウント -----
        INCF    C_IN,F      ;入力信号用カウンタに＋１
        BTFSC   STATUS,Z    ;C_INが桁オーバー
        GOTO    P140        ;エラー表示へ
P120
        ;-----  立ち下がり判断 -----
        CALL    TIM99us     ;ノイズ飛ばし？
        BTFSC   P_IN        ;入力信号がＬかどうか       【BTFSC】０だったらスキップ
        GOTO    P120        ;入力信号がＬになれば下の処理へ
P130
        GOTO    P100        ;入力信号のカウント続行
P140
        ;----- 入力信号のカウント失敗 -----
        ;----- LEDの1と12を点灯しエラー表示 -----
        BSF     P_1M        ;エラー表示
        BSF     P_12M       ;エラー表示
        GOTO    P100        ;入力信号のカウント続行
;
;======================================================
;  WedgeIn Routine
;======================================================
INTR
;----------------------
; 割込み処理
;----------------------
INTRst
        ; ----- レジスタ保存 -----
        MOVWF   W_TEMP      ;Wレジスタ待避
        SWAPF   STATUS,W    ;STATUS取り出し
        MOVWF   ST_TEMP     ;STATUS待避 
        ; ----- 割込み設定 -----
        ; (50ms) 50000ｶｳﾝﾄ/256 = 195(C3H)
        ; TMROはｱｯﾌﾟｶｳﾝﾀなので FFH-C3H=3CH
        BCF     INTCON,T0IE ;タイマ割込みフラグクリア
        MOVLW   03CH        ;カウント値ロード
        MOVWF   TMR0        ;TMR0へ出力
        BCF     INTCON,T0IF ;ｵｰﾊﾞｰﾌﾛｰフラグクリア
INTR010
        ; ----- インターバルを200msにする -----
        DECFSZ  C_INTR,F    ;カウントダウン
        GOTO    INTRend     ;まだ200mSでない
INTR020
        ; ----- ＬＥＤの点灯 -----
        CALL    LEDup       ;ＬＥＤの点灯
INTR030
        ; ----- カウンタクリア -----
        MOVLW   D'11'       ;11を代入50msX11=550ms
        MOVWF   C_INTR      ;割込み回数カウンタ
INTR040
        ; ----- カウンタクリア -----
        CLRF    C_IN        ;入力信号用カウンタクリア
INTRend
        ; ----- レジスタ復帰 -----
        SWAPF   ST_TEMP,W   ;STATUSを戻す
        MOVWF   STATUS      ;
        SWAPF   W_TEMP,F    ;Wレジスタを戻す
        SWAPF   W_TEMP,W
        BSF     INTCON,T0IE ;タイマ割込み許可
        RETFIE              ;割込み許可リターン
;
;----------------------
;----------------------
        END
