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