目次>5章 第2ステップ(色々な実験)>人が近づいたら明かりを点ける>ソース

人が近づいたら明かりを点ける(ソース)

更新日2005.11.12

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

; ========================== ここから ==============================
;   CLOCK   10MHz
;   PORTA   0:NaPiOn
;   PORTB   0:LED緑,1:LED赤
;
;   人の動きを検出したら明かりを点ける
;
        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        ; 初期処理に行く

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

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

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

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



INIT
    ; << PICの初期化 >>

        BSF     STATUS,RP0  ; ↓ファイルレジスタSTATUSのRP0をセット(1)する → バンク1

        CLRF    TRISB       ; ファイルレジスタTRISBをクリア(0) → PORTBは全て出力
        MOVLW   01h
        MOVWF   TRISA       ; ファイルレジスタTRISAの0ビット目のみON → RA0は入力

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

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

        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


    ; << メイン処理 >>
WAIT10S     ; 電源ON後、NaPiOnの回路が安定するまで10秒待つ
        BTFSS   flag10s,0   ; 10秒経過フラグON?
        GOTO    WAIT10S     ;  No


MAIN
        BTFSC   PORTA,0     ; RA0の状態チェック
        GOTO    RA0_ON      ;  ONの時

RA0_OFF                     ; NaPiOnの出力OFF
        BCF     PORTB,0     ; RB0をOFF

        BTFSS   napion,0    ; NaPiOn状態は1?
        GOTO    OFF_200     ;  No

    ; << NaPiOn状態が1の時(ONからOFFになった) >>
        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で無い時 >>
OFF_200
        BTFSS   napion,1    ; NaPiOn状態は2?
        GOTO    MAIN        ;  No

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

;       BCF     PORTB,1     ; RB0をOFFにする
        BCF     PORTB,1     ; RB1をOFFにする(20090224コメントのミス修正)
        CLRF    napion      ; NaPiOn状態を0にする

        GOTO    MAIN

RA0_ON                      ; NaPiOnの出力ON
        MOVLW   03h
        MOVWF   PORTB       ; RB0をON,RB1をON

        MOVLW   01h
        MOVWF   napion      ; NaPiOnの状態管理に'1'を設定

        GOTO    MAIN

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