目次>6章 第3ステップ(実用品)>PICテストボード(スイッチ,LED)>ソース
PICテストボード(スイッチ,LED)(ソース)
更新日2006.10.21
以下のソースを取り込んで、アセンブル→PIC書き込み→実行して下さい。
; ========================== ここから ==============================
; CLOCK 20MHz
; PORTA RA2〜4:プッシュボタンスイッチ
; PORTB RB0〜7:LED赤
;
;
;
LIST P=PIC16F84A ; LIST宣言で、使用するPICをPIC16F84Aと定義する
INCLUDE P16F84A.INC ; 設定ファイルp16f84a.incを読み込む
__CONFIG _HS_OSC & _WDT_OFF & _PWRTE_ON & _CP_OFF
save_w EQU 0Ch ; W save
save_st EQU 0Dh ; STATUS save
t_add EQU 0Eh ; t_widthを可変にする時、t_widthに加算する数(+−)
t_width EQU 0Fh ; PWMの幅(0〜63 ×4)
t_count EQU 010h ; 0.1mS毎のカウンタ(0〜63 4ずつ加算,0になったら1サイクル)
tc1 EQU 011h ; 1mSカウンタ(10)
tc10 EQU 012h ; 10mSカウンタ(98)
tc100_1 EQU 013h ; 100mSカウンタ1(122)
tc100_2 EQU 014h ; 100mSカウンタ2(8)
tc500_2 EQU 015h ; 500mSカウンタ2(40)
timer EQU 016h ; タイマ割込みフラグ
tm01 EQU 01h ;0.1mS
tm1 EQU 02h ;1mS
tm10 EQU 03h ;10mS
tm100 EQU 04h ;100mS
tm500 EQU 05h ;500mS
mode1 EQU 017h
; mode1 処理
; 0 なにもしない(LEDの表示は直前のまま)。
; 1 初期状態。RB0を0.5秒毎に点滅,RB7を点灯。
; 2 RA2SWが押された。RA2SWを押す毎にLEDを1つ点灯移動。
; 4 RA3SWが押された。8個のLEDを2進数として100mS毎に+1した結果を表示する。
; RA3SWもう一度押すと全てのLEDを消灯する。
; 8 RA4SWが押された。LED1つを100ms毎に点灯移動する。
; 16 RA4SWをもう1回押すと、その時ONだったLEDを徐々に暗くし徐々に明るくを繰り返す。
RA2stat EQU 018h
RA3stat EQU 019h
RA4stat EQU 01Ah
; RA*のスイッチ状態(チャタリングキャンセル用)
; 00000000 初期状態(スイッチは押されていない)
; 00000001 スイッチが押された(チャタリングキャンセル開始)
; 00000010 スイッチが押された後、10mS割込み1回経過(チャタリングキャンセル待ち)
; 10000010 スイッチが押された後、10mS割込み2回経過(確定)
; 11000010 スイッチON処理済み
PBwork EQU 01Bh
; ============= 処理開始 =======================================
ORG 0 ; リセットベクタ(0番地)を指定する。
GOTO INIT ; 初期処理に行く
; ============= TMR0割込み処理 =================================
ORG 4 ; 割込みベクタ(4番地)を指定する。
BCF INTCON,T0IF ; 割込みフラグクリア
MOVWF save_w ; W-regセーブ
SWAPF STATUS,W
MOVWF save_st ; STATUSレジスタセーブ
BSF timer,tm01 ; 0.1mSフラグセット
DECFSZ tc1,F
GOTO T0_10
BSF timer,tm1 ; 1mSフラグセット
MOVLW d'10'
MOVWF tc1 ; 1mSカウンタ(10)
T0_10
DECFSZ tc10,F
GOTO T0_100
BSF timer,tm10 ; 10mSフラグセット
MOVLW d'98'
MOVWF tc10 ; 10mSカウンタ(98)
T0_100
DECFSZ tc100_1,F
GOTO T0EXIT
MOVLW d'122'
MOVWF tc100_1 ; 100mSカウンタ1(122)
DECFSZ tc100_2,F
GOTO T0_500
BSF timer,tm100 ; 100mSフラグセット
MOVLW d'8'
MOVWF tc100_2 ; 100mSカウンタ2(8)
T0_500
DECFSZ tc500_2,F
GOTO T0EXIT
MOVLW d'40'
MOVWF tc500_2 ; 500mSカウンタ2(40)
BSF timer,tm500 ; 500mSフラグセット
T0EXIT
SWAPF save_st,W
MOVWF STATUS ; STATUSレジスタロード
SWAPF save_w,F
SWAPF save_w,W ; W-regロード
RETFIE ; 割込み許可にしてリターン
; ここまでTMR0割込み処理
; ============= 初期処理 =================================
INIT
; << ポートの初期化 >>
BSF STATUS,RP0 ; ■バンク1
MOVLW 0FFh
MOVWF TRISA ; PORTAは全て入力
CLRF TRISB ; PORTBは全て出力
BCF STATUS,RP0 ; ■バンク0
; << TMR0割込みの初期化 >>
BSF STATUS,RP0 ; ■バンク1
MOVLW 080h ; OPTIONレジスタの設定
MOVWF OPTION_REG ; PORTBプルアップなし ,TMR0クロック:内部 ,プリスケーラ:TMR0で2
BCF STATUS,RP0 ; ■バンク0
MOVLW 0A0h ; INTCONの設定
MOVWF INTCON ; GIE:1 ,T0IE:1
CLRF TMR0 ; TMR0をクリア
; << カウンタの初期化 >>
CLRF PORTB ; RB0-7:OFF
CLRF t_width
CLRF t_count
MOVLW d'10'
MOVWF tc1 ; 1mSカウンタ(10)
MOVLW d'98'
MOVWF tc10 ; 10mSカウンタ(98)
MOVLW d'122'
MOVWF tc100_1 ; 100mSカウンタ1(122)
MOVLW d'8'
MOVWF tc100_2 ; 100mSカウンタ2(8)
MOVLW d'40'
MOVWF tc500_2 ; 500mSカウンタ2(40)
; << 初期動作設定 >>
MOVLW 01h
MOVWF mode1 ; RB0のLEDを0.5秒毎に点滅
BSF PORTB,7 ; RB7のLEDを点灯
; ============= メイン処理 =================================
LOOP
BTFSC timer,tm01
CALL St01 ; 0.1mS経過処理
BTFSC timer,tm1
CALL St1 ; 1mS経過処理
BTFSC timer,tm10
CALL St10 ; 10mS経過処理
BTFSC timer,tm100
CALL St100 ; 100mS経過処理
BTFSC timer,tm500
CALL St500 ; 500mS経過処理
BTFSS PORTA,2
CALL RA2on ; RA2 ON処理
BTFSS PORTA,3
CALL RA3on ; RA3 ON処理
BTFSS PORTA,4
CALL RA4on ; RA4 ON処理
GOTO LOOP
; ============= 0.1mS割込み処理 =================================
St01
BCF timer,tm01
BTFSS mode1,4 ; mode1=16?
GOTO St01_20 ; No
MOVLW 04h
ADDWF t_count,F
BTFSS STATUS,Z ; 1サイクル終了?
GOTO St01_10 ; No
; Yes
MOVF PBwork,W
MOVWF PORTB
MOVF t_add,W
ADDWF t_width,F ; パルス幅にt_add(+-あり)を加算
BTFSS STATUS,Z ; パルス幅0?
GOTO St01_10 ; No
; t_addの+-反転
MOVLW 0FFh
XORWF t_add,F
INCF t_add,F
St01_10
MOVF t_count,W
SUBWF t_width,W
BTFSS STATUS,Z ; t_count = t_width ?
GOTO St01_20 ; No
MOVF PBwork,W
XORWF PORTB,F
St01_20
RETURN
; ============= 1mS割込み処理 =================================
St1
BCF timer,tm1
RETURN
; ============= 10mS割込み処理 =================================
St10
BCF timer,tm10
; <RA2のチャタリングキャンセル処理>
MOVF RA2stat,W ; RA2statは
BTFSC STATUS,Z ; 0?
GOTO St10RA3 ; Yes
BTFSS RA2stat,0 ; チャタリングキャンセル開始?
GOTO St10RA2_1 ; No
MOVLW 02h ; RA2statを、b'00000010'にする
MOVWF RA2stat ; (チャタリングキャンセル待ち)
GOTO St10RA3
St10RA2_1
BTFSS RA2stat,1 ; チャタリングキャンセル待ち?
GOTO St10RA3 ; No
BTFSS PORTA,2 ; RA2 on?
GOTO St10RA2_2 ; Yes
CLRF RA2stat
GOTO St10RA3
St10RA2_2
BSF RA2stat,7 ; RA2 on 確定
St10RA3
; <RA3のチャタリングキャンセル処理>
MOVF RA3stat,W ; RA3statは
BTFSC STATUS,Z ; 0?
GOTO St10RA4 ; Yes
BTFSS RA3stat,0 ; チャタリングキャンセル開始?
GOTO St10RA3_1 ; No
MOVLW 02h ; RA3statを、b'00000010'にする
MOVWF RA3stat ; (チャタリングキャンセル待ち)
GOTO St10RA4
St10RA3_1
BTFSS RA3stat,1 ; チャタリングキャンセル待ち?
GOTO St10RA4 ; No
BTFSS PORTA,3 ; RA3 on?
GOTO St10RA3_2 ; Yes
CLRF RA3stat
GOTO St10RA4
St10RA3_2
BSF RA3stat,7 ; RA3 on 確定
St10RA4
; <RA4のチャタリングキャンセル処理>
MOVF RA4stat,W ; RA4statは
BTFSC STATUS,Z ; 0?
GOTO St10_10 ; Yes
BTFSS RA4stat,0 ; チャタリングキャンセル開始?
GOTO St10RA4_1 ; No
MOVLW 02h ; RA4statを、b'00000010'にする
MOVWF RA4stat ; (チャタリングキャンセル待ち)
GOTO St10_10
St10RA4_1
BTFSS RA4stat,1 ; チャタリングキャンセル待ち?
GOTO St10_10 ; No
BTFSS PORTA,4 ; RA4 on?
GOTO St10RA4_2 ; Yes
CLRF RA4stat
GOTO St10_10
St10RA4_2
BSF RA4stat,7 ; RA4 on 確定
St10_10
RETURN
; ============= 100mS割込み処理 =================================
St100
BCF timer,tm100
BTFSS mode1,2 ; mode1=4?
GOTO St100_10 ; No
INCF PBwork,F
MOVF PBwork,W
MOVWF PORTB
GOTO St100_exit
St100_10
BTFSS mode1,3 ; mode1=8?
GOTO St100_20 ; No
BCF STATUS,C
RLF PBwork,F
BTFSS STATUS,C
GOTO St100_11
MOVLW 01h
MOVWF PBwork
St100_11
MOVF PBwork,W
MOVWF PORTB
GOTO St100_exit
St100_20
St100_exit
RETURN
; ============= 500mS割込み処理 =================================
St500
BCF timer,tm500
BTFSS mode1,0 ; mode1=1?
GOTO St500E ; No
MOVLW 01h
XORWF PORTB,F ; RB0の出力を反転
St500E
RETURN
; ============= RA2 on処理 =================================
RA2on
MOVF RA2stat,W ; RA2statは
BTFSS STATUS,Z ; 0?
GOTO RA2on_1 ; No
BSF RA2stat,0 ; チャタリングキャンセル開始
GOTO RA2on_exit
RA2on_1
BTFSS RA2stat,7 ; スイッチ押下確定?
GOTO RA2on_exit ; No
BTFSC RA2stat,6 ; スイッチ押下処理済み?
GOTO RA2on_exit ; Yes
BSF RA2stat,6 ; スイッチ押下処理済みセット
BTFSC mode1,1 ; mode1=2?
GOTO RA2on_10 ; Yes
MOVLW 02h
MOVWF mode1 ; mode1=2
MOVLW 080h
MOVWF PBwork
RA2on_10
BCF STATUS,C
RLF PBwork,F
BTFSC STATUS,C
BSF PBwork,0
MOVF PBwork,W
MOVWF PORTB
RA2on_exit
RETURN
; ============= RA3 on処理 =================================
RA3on
MOVF RA3stat,W ; RA3statは
BTFSS STATUS,Z ; 0?
GOTO RA3on_1 ; No
BSF RA3stat,0 ; チャタリングキャンセル開始
GOTO RA3on_exit
RA3on_1
BTFSS RA3stat,7 ; スイッチ押下確定?
GOTO RA3on_exit ; No
BTFSC RA3stat,6 ; スイッチ押下処理済み?
GOTO RA3on_exit ; Yes
BSF RA3stat,6 ; スイッチ押下処理済みセット
BTFSS mode1,2 ; mode1=4?
GOTO RA3on_10 ; No
CLRF mode1
CLRF PORTB
GOTO RA3on_exit
RA3on_10
MOVLW 04h ; mode1=4
MOVWF mode1
CLRF PBwork
RA3on_exit
RETURN
; ============= RA4 on処理 =================================
RA4on
MOVF RA4stat,W ; RA4statは
BTFSS STATUS,Z ; 0?
GOTO RA4on_1 ; No
BSF RA4stat,0 ; チャタリングキャンセル開始
GOTO RA4on_exit
RA4on_1
BTFSS RA4stat,7 ; スイッチ押下確定?
GOTO RA4on_exit ; No
BTFSC RA4stat,6 ; スイッチ押下処理済み?
GOTO RA4on_exit ; Yes
BSF RA4stat,6 ; スイッチ押下処理済みセット
BTFSS mode1,3 ; mode1=8?
GOTO RA4on_10 ; No
BTFSS mode1,4 ; mode1=16?
GOTO RA4on_20 ; No
CLRF mode1
CLRF PORTB
GOTO RA4on_exit
RA4on_10
MOVLW 08h ; mode1=8
MOVWF mode1
MOVLW 01h
MOVWF PBwork
GOTO RA4on_exit
RA4on_20
MOVLW 010h ; mode1=16
MOVWF mode1
MOVLW 0FCh
MOVWF t_add
MOVWF t_width
CLRF t_count
GOTO RA4on_exit
RA4on_exit
RETURN
END
; =========================== ここまで ===============================