; Copyright 2005 Noriaki Mitsunaga list p=16f877a ; PIC16F877A 用のプログラムであることを宣言 #include p16f877a.inc ; PIC16F877A 用のヘッダファイルを読み込む __config _HS_OSC & _CP_OFF & _PWRTE_ON & _WDT_OFF & _LVP_OFF CT_DELAY1MS equ 0x20 CT_DELAY20MS equ 0x21 ; 初期設定をする bcf STATUS, RP0 ; この2行でバンク0にする bcf STATUS, RP1 clrf PORTC ; LED が点灯しないように0に clrf PORTD ; 出力は0にしておく clrf PORTE ; 出力は0にしておく bsf STATUS, RP0 ; バンク1にする clrf ADCON1 ; ポートAはアナログ入力 movlw 0xff movwf TRISB ; ポートBはデジタル入力 bcf OPTION_REG, NOT_RBPU ; ポートBのウィークプルアップを有効に bcf OPTION_REG, INTEDG ; RB0/INT ピン割り込みは立ち下がりエッジ clrf TRISC ; 全ピン出力に clrf TRISD ; 全ピン出力に clrf TRISE ; 全ピン出力に bcf STATUS, RP0 ; バンク0にする movlw 0x10 ; RB0/INT ピンの割り込みを有効にする movwf INTCON ; 初期設定は終了 ; goto $ ; LED を点灯する movlw B'00000001' movwf PORTC ;; ----- ここからメインループ -------- loop ; スイッチ 0 が押される(PORTB<0>が0になる)まで待つ lp1 bcf INTCON, INTF ; RB0/INT フラグをクリア ; ハードウェアでクリアされないので sleep 前にクリアする sleep ; INT0 の割り込み待ち nop ; 割り込みルーチンへジャンプするときのために nop を入れておく call delay20ms ; 20ms待って btfsc PORTB, 0 ; 押されていることを確認する goto lp1 ; 押されていなければ再度スリープ ; LED を消灯する movlw B'00000000' movwf PORTC ; スイッチ 0 が離される(PORTB<0>が1になる)まで待つ ; ここで待たずにスリープに入るとチャタリングでスリープから復帰する可能性がある lp2 btfss PORTB, 0 goto $-1 call delay20ms ; 20ms待って btfss PORTB, 0 ; 再度確認する goto lp2 ; スイッチ 0 が押される(PORTB<0>が0になる)まで待つ lp3 bcf INTCON, INTF ; RB0/INT フラグをクリア sleep ; INT0 の割り込み待ち nop ; 割り込みルーチンへジャンプするときのために nop を入れておく call delay20ms ; 20ms待って btfsc PORTB, 0 ; 押されていることを確認する goto lp3 ; 押されていなければ再度スリープ ; LED を点灯する movlw B'00000001' movwf PORTC ; スイッチ 0 が離される(PORTB<0>が1になる)まで待つ ; ここで待たずにスリープに入るとチャタリングでスリープから復帰する可能性がある lp4 btfss PORTB, 0 goto $-1 call delay20ms ; 20ms待って btfss PORTB, 0 ; 再度確認する goto lp4 goto loop ;; ----- メインループはここまで -------- ;; ;; 以下は時間待ちサブルーチン (10[us]/1[ms]/20[ms]) ;; FOSC を変更した場合には適宜変更すること ;; ;; 10[us] 待ちサブルーチン delay10us: goto $+1 ; 2 goto $+1 ; 2 goto $+1 ; 2 goto $+1 ; 2 goto $+1 ; 2 goto $+1 ; 2 goto $+1 ; 2 goto $+1 ; 2 goto $+1 ; 2 goto $+1 ; 2 nop ; 1 return ; 2 ;; 1[ms] 待ちサブルーチン delay1ms: movlw D'89' ; 1 movwf CT_DELAY1MS ; 1 delay1msl1: call delay10us ; 25 decfsz CT_DELAY1MS, f ; 1(次の行を実行)、2(次の行はとばす) goto delay1msl1 ; 2 nop ; 1 goto $+1 ; 2 return ; 2 ;; 20[ms] 待ちサブルーチン delay20ms movlw D'20' movwf CT_DELAY20MS delay20msl1: call delay1ms decfsz CT_DELAY20MS, f goto delay20msl1 return end