目次>5章 第2ステップ(色々な実験)>RB0/INT割込みを使う>ソース

RB0/INT割込みを使う(ソース)

更新日2005.11.26

以下のソースを取り込んで、アセンブル→PIC書き込み→実行して下さい。

; ========================== ここから ==============================
;   CLOCK   10MHz
;   PORTA   0:高輝度LED,1:LED緑
;   PORTB   0:NaPiOn
;
;   人の動きを検出したら明かりを点ける
;     ・TMR0割込み使用
;     ・RB0/INT割込み使用
;
;   SLEEP時、0.19mA
;
        LIST    P=PIC16F84A  ; LIST宣言で、使用するPICをPIC16F84Aと定義する
        INCLUDE P16F84A.INC  ; 設定ファイルp16f84a.incを読み込む

        __CONFIG _HS_OSC & _WDT_OFF & _PWRTE_ON & _CP_OFF


save_st EQU     0Ch         ; STATUSのセーブ領域
save_w  EQU     0Dh         ; W-regのセーブ領域
CNT38   EQU     0Eh         ; TMR0割り込みを38回カウントするカウンタ
CNT10   EQU     0Fh         ; 上記38回をさらに10回カウントするカウンタ
flag10s EQU     010h        ; 10秒経過フラグ
napion  EQU     011h        ; NaPiOnの出力変化の管理

        ORG     0           ; リセットベクタ(0番地)を指定する。
        GOTO    INIT        ; 初期処理に行く

    ; << 割込み処理 >>
        ORG     4           ; 割込みベクタ(4番地)を指定する。
        MOVWF   save_w      ; W-regセーブ
        SWAPF   STATUS,W
        MOVWF   save_st     ; STATUSレジスタセーブ

        BTFSC   INTCON,T0IF ; TMR0割込み?
        GOTO    T0INT       ;  Yes
        BTFSC   INTCON,INTF ; RB0/INT割込み?
        GOTO    RB0INT      ;  Yes
        GOTO    INTEXIT     ;  No


T0INT       ; TMR0割込み処理
        BCF     INTCON,T0IF ; 割込みフラグクリア

        DECFSZ  CNT38,F     ; CNT38−1が0か?
        GOTO    INTEXIT     ;  No
        MOVLW   d'38'
        MOVWF   CNT38       ; CNT38に38をセット

        DECFSZ  CNT10,F     ; CNT10−1が0か?
        GOTO    INTEXIT     ;  No
        MOVLW   d'10'
        MOVWF   CNT10       ; CNT10に10をセット
        BSF     flag10s,0   ; 10秒経過フラグをON
        GOTO    INTEXIT

RB0INT      ; RB0/INT割込み処理
        BCF     INTCON,INTF ; 割込みフラグクリア
        BSF     PORTA,0     ; RA0 ON
        MOVLW   d'1'
        MOVWF   napion      ; 1→NaPiOn状態

INTEXIT
        SWAPF   save_st,W
        MOVWF   STATUS      ; STATUSレジスタロード
        SWAPF   save_w,F
        SWAPF   save_w,W    ; W-regロード
        RETFIE              ; 割込み許可にしてリターン
    ; ここまで割込み処理



INIT
    ; << PICの初期化 >>

        BSF     STATUS,RP0  ; ↓STATUSのRP0をセット(1)する → バンク1

        MOVLW   01h
        MOVWF   TRISB       ; PORTBのRB0のみ入力

        CLRF    TRISA       ; PORTAは全て出力

        MOVLW   087h        ; OPTIONレジスタの設定
        MOVWF   OPTION_REG  ; ^RBPU:1 ,INTEDG:0 ,T0CS:0 ,PSA:0 ,PS2-PS0:111

        BCF     STATUS,RP0  ; ↑STATUSのRP0をクリア(0) → バンク0

        CLRF    PORTA       ; PORTAを全てOFF
        CLRF    PORTB       ; PORTBを全てOFF

        CLRF    TMR0        ; TMR0をクリア
        MOVLW   0A0h        ; INTCONの設定
        MOVWF   INTCON      ; GIE:1 ,T0IE:1(TMR0割り込み許可)

        MOVLW   d'38'
        MOVWF   CNT38       ; CNT38に38をセット
        MOVLW   d'10'
        MOVWF   CNT10       ; CNT10に10をセット

        CLRF    flag10s
        CLRF    napion


    ; << メイン処理 >>
        BSF     PORTA,1     ; 電源ON後10秒間RA1(緑LED)をONにする
WAIT10S     ; 電源ON後、NaPiOnの回路が安定するまで10秒待つ
        BTFSS   flag10s,0   ; 10秒経過フラグON?
        GOTO    WAIT10S     ;  No

        BCF     PORTA,1     ; 電源ONから10秒経過後、RA1をOFFにする

        BSF     INTCON,INTE ; RB0/INT割込み許可

MAIN
        CALL    DBG         ; RB0(NaPiOnの出力)の状態をRA1で表示
        BTFSS   napion,0    ; NaPiOn状態は1?
        GOTO    NAPI2       ;  No

NAPI1
    ; << NaPiOn状態が1の時(RB0/INT割込み発生) >>
        CLRF    TMR0        ; TMR0クリア

        MOVLW   d'38'
        MOVWF   CNT38       ; CNT38に38をセット
        MOVLW   d'10'
        MOVWF   CNT10       ; CNT10に10をセット

        CLRF    flag10s     ; 10秒経過フラグクリア

        MOVLW   d'2'
        MOVWF   napion      ; NaPiOn状態を2にする

        GOTO    MAIN

    ; << NaPiOn状態が1で無い時 >>
NAPI2
        BTFSS   napion,1    ; NaPiOn状態は2?
        GOTO    MAIN        ;  No

        BTFSS   flag10s,0   ; flag10s(10秒経過フラグ)=1?
        GOTO    MAIN        ;  No

        BCF     PORTA,0     ; RA0をOFFにする
        CLRF    napion      ; NaPiOn状態を0にする

        SLEEP               ; 省電力モードで待機(RB0/INT割込み待ち)

        GOTO    MAIN


    ; << RB0の状態をRA1に反映するサブルーチン >>
DBG
        BTFSS   PORTB,0     ; NaPiOn = ON?
        GOTO    DBG010      ;  No
        BSF     PORTA,1
        GOTO    DBG900
DBG010
        BCF     PORTA,1

DBG900
        RETURN

        END
; =========================== ここまで ===============================