目次>5章 第2ステップ(色々な実験)>スイッチでLEDの点滅パターンを変更>ソース

スイッチでLEDの点滅パターンを変更(ソース)

更新日2005.10.2

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

; ========================== ここから ==============================
;   CLOCK   10MHz
;   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


cnt04   EQU     0Ch         ; 0.4mS待つサブルーチン用カウンタ
cnt20   EQU     0Dh         ; 20mS待つサブルーチン用カウンタ
old_sw  EQU     0Eh         ; 前回SW状態
mode    EQU     0Fh         ; LED表示モード
cnt500  EQU     10h         ; 500mSをカウント(20mS×25)

        ORG     0           ; リセットベクタ(0番地)を指定する。
INIT
    ; << PICの初期化 >>
        CLRF    PORTB       ; PORTBを全てOFF

        BSF     STATUS,RP0  ; ファイルレジスタSTATUSのRP0をセット(1)する → バンク1
        CLRF    TRISB       ; ファイルレジスタTRISBをクリア(0) → PORTBは全て出力
        MOVLW   01h
        MOVWF   TRISA       ; ファイルレジスタTRISAの0ビット目のみON → RA0は入力
        BCF     STATUS,RP0  ; STATUSのRP0をクリア(0) → バンク0

        CLRF    old_sw      ; 0 → 前回SW状態
        MOVLW   01h
        MOVWF   mode        ; 1 → LED表示モード
        MOVLW   D'25'
        MOVWF   cnt500      ; 25 → 500mSカウンタ(20mS×25)

    ; << メイン処理 >>
MAIN
        BTFSC   PORTA,0     ; スイッチの状態チェック
        GOTO    SW_ON       ; スイッチがONの時

SW_OFF                      ; スイッチがOFFの時
        CALL    T20mS       ; 20mS待つ
        BTFSS   PORTA,0     ; スイッチの状態チェック
        CLRF    old_sw      ; OFFなら0→前回SW状態
        GOTO    DISP        ; LED表示処理へ

SW_ON                       ; スイッチがONの時
        CALL    T20mS       ; 20mS待つ
        BTFSS   PORTA,0     ; スイッチの状態チェック
        GOTO    DISP        ; OFFならLED表示処理へ

        BTFSC   old_sw,0    ; 前回のスイッチ状態はOFF?
        GOTO    DISP        ; ONならLED表示処理へ

        BSF     old_sw,0    ; 前回のスイッチ状態がOFFなら1→前回SW状態
        INCF    mode,F      ; 表示モード+1


DISP
        MOVLW   D'1'
        SUBWF   mode,W
        BTFSC   STATUS,Z
        GOTO    DISP1       ; 表示モードが1の時

        MOVLW   D'2'
        SUBWF   mode,W
        BTFSC   STATUS,Z
        GOTO    DISP2       ; 表示モードが2の時

        MOVLW   D'3'
        SUBWF   mode,W
        BTFSC   STATUS,Z
        GOTO    DISP3       ; 表示モードが3の時

                            ; 表示モードが1〜3以外の時
        MOVLW   D'1'
        MOVWF   mode        ; 1 → 表示モード
        GOTO    MAIN

DISP1       ; 表示モードが1の時 緑色LEDのみ点灯
        MOVLW   01h
        MOVWF   PORTB       ; PORTBのRB0のみONにする(緑色LED点灯)
        GOTO    MAIN


DISP2       ; 表示モードが2の時 緑と赤のLEDを0.5秒毎に交互に点灯
        DECFSZ  cnt500
        GOTO    MAIN
                            ; 500mS経過
        MOVLW   D'25'
        MOVWF   cnt500      ; 25 → 500mSカウンタ(20mS×25)

        BTFSS   PORTB,0
        GOTO    DISP21

        MOVLW   02h
        MOVWF   PORTB       ; RB0=0 RB1=1 緑消灯,赤点灯
        GOTO    MAIN

DISP21
        MOVLW   01h
        MOVWF   PORTB       ; RB0=1 RB1=0 緑点灯,赤消灯
        GOTO    MAIN


DISP3       ; 表示モードが3の時 赤色LEDのみ点灯
        MOVLW   02h
        MOVWF   PORTB       ; PORTBのRB1のみONにする(赤色LED点灯)
        GOTO    MAIN



    ; << 20mS待つサブルーチン >>   
T20mS
        MOVLW   D'50'       ; 50(20mS)
;        MOVLW   D'100'       ; 100(40mS)
        MOVWF   cnt20       ;  (ループ回数として50をセット)
T20LP   CALL    T04mS       ; 0.4mS待つ
        DECFSZ  cnt20,F     ; ループ回数−1して0になったら次の命令をスキップ
        GOTO    T20LP       ;
        RETURN              ; このサブルーチン呼出し元に戻る


    ; << 0.4mS待つサブルーチン >>   
T04mS
        MOVLW   D'249'      ; 249
        MOVWF   cnt04       ;  (ループ回数として249をセット)
T04LP   NOP                 ; 何もせず1サイクル消費
        DECFSZ  cnt04,F     ; ループ回数−1して0になったら次の命令をスキップ
        GOTO    T04LP
        RETURN              ; このサブルーチン呼出し元に戻る

        END                 ; プログラムの終了をアセンブラに指示する
; =========================== ここまで ===============================