目次>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
; =========================== ここまで ===============================