目次>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
; =========================== ここまで ===============================