目次>5章 第2ステップ(色々な実験)>(6)LEDの明るさを序所に変える(TMR0割込み使用)>ソース

LEDの明るさを序所に変える(TMR0割込み使用)(ソース)

更新日2005.10.15

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

; ========================== ここから ==============================
;   CLOCK   10MHz
;   PORTB   0:LED緑,1:LED赤
;
;   緑のLEDの明るさを徐々に変える(TMR0使用)
;
        LIST    P=PIC16F84A  ; LIST宣言で、使用するPICをPIC16F84Aと定義する
        INCLUDE P16F84A.INC  ; 設定ファイルp16f84a.incを読み込む

        __CONFIG _HS_OSC & _WDT_OFF & _PWRTE_ON & _CP_OFF


t_cycle EQU     0Ch         ; 1周期(サイクル)をカウント(0〜99)
t_width EQU     0Dh         ; ONの時間(パルス幅)をカウント(0〜99)
t_add   EQU     0Eh         ; t_widthに加算する値(1 or −1)
save_st EQU     0Fh         ; STATUSのセーブ領域
save_w  EQU     010h        ; W-regのセーブ領域

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

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

        INCF    t_cycle,F

        MOVLW   d'100'
        SUBWF   t_cycle,W
        BTFSS   STATUS,Z    ; t_cycle = 100 ?
        GOTO    T0EXIT      ;  no
                            ;  yes
        CLRF    t_cycle     ; 0 → t_cycle
        MOVF    t_add,W
        ADDWF   t_width,F   ; t_widthにt_addを加算
        BSF     PORTB,0     ; RB0を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   080h        ; OPTIONレジスタの設定
        MOVWF   OPTION_REG  ; ^RBPU:1 ,T0CS:0(内部クロック) ,PSA:0(プリスケーラはTMR0) ,PS2-PS0:000(2倍)

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

        MOVLW   0A0h        ; INTCONの設定
        MOVWF   INTCON      ; GIE:1 ,T0IE:1

        CLRF    PORTB       ; PORTBのLEDをOFF

        MOVLW   d'1'
        MOVWF   t_add       ; 1 → t_add
        CLRF    t_cycle     ; 0 → t_cycle
        CLRF    t_width     ; 0 → t_width

        CLRF    TMR0        ; TMR0をクリア


    ; << メイン処理 >>
LOOP
        MOVF    t_width,W
        SUBWF   t_cycle,W
        BTFSC   STATUS,Z    ; t_cycle = t_width ?
        BCF     PORTB,0     ;  yes  RB0をOFF

        MOVLW   d'99'
        SUBWF   t_width,W
        BTFSC   STATUS,Z    ; t_width = 99 ?
        GOTO    MAIN20      ;  yes

        MOVF    t_width,W
        BTFSS   STATUS,Z    ; t_width = 0 ?
        GOTO    LOOP        ;  no

        MOVLW   d'1'
        MOVWF   t_add       ; 1 → t_add
        BSF     PORTB,1     ; RB1 ON (赤色LED点灯)
        GOTO    LOOP

MAIN20
        MOVLW   0FFh
        MOVWF   t_add       ; -1 → t_add
        BCF     PORTB,1     ; RB1 OFF (赤色LED消灯)
        GOTO    LOOP

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