目次>6章 第3ステップ(実用品)>夜、人の動きを検知したら明かりを点ける>ソース

夜、人の動きを検知したら明かりを点ける(ソース)

更新日2006.12.16

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

; ========================== ここから ==============================
;
;	PIC12F683
;	clock:INTOSCIO 8MHz
;	電源:単三乾電池三本(4.5V)
;
;	内部クロック8MHz
;	全てのピン(6ピン)をデジタルIOで使用
;	GP0: 未使用
;	GP1: 高輝度LED(出力)
;	GP2: NaPiOn(GP2/INT)
;	GP3: Cds
;	GP4: 高輝度LED(出力)
;	GP5: 高輝度LED(出力)
;
;	NaPiOnによりGP2/INT割込みを発生させ、高輝度LEDを5秒間点灯させる
;	Cdsにより、暗い時のみ動作
;	時間待ちは、TMR0割込みを使用
;	人の動きを検出していない時は、SLEEP状態(省電力待機)にする
;
;
	LIST	P=12f683
	#INCLUDE <p12f683.inc>

	__CONFIG _CP_OFF & _CPD_OFF & _WDT_OFF & _BOD_OFF & _IESO_OFF& _PWRTE_ON & _INTOSCIO & _MCLRE_OFF

	CBLOCK	020h
	save_st		; STATUSのセーブ領域
	save_w		; W-regのセーブ領域
	CNT19		; TMR0割り込みを19回カウントするカウンタ
	napion		; NaPiOn状態フラグ
	timer		; タイマー(bit0:5秒)
	C25mS		; 25mSカウンタ(128uS×195)
	C5S		; 5Sカウンタ(128uS×195×200)
	ENDC

t128uS	EQU	0
t25mS	EQU	1
t5S	EQU	5

	ORG	0
	GOTO	INIT	; 初期処理に行く


; ======================== 割込み処理 ========================
	ORG	4		; 割込みベクタ(4番地)を指定する。
	MOVWF	save_w		; W-regセーブ
	SWAPF	STATUS,W
	MOVWF	save_st		; STATUSレジスタセーブ

	BTFSC	INTCON,T0IF	; TMR0割込み?
	GOTO	T0INT		;  Yes
	BTFSC	INTCON,INTF	; GP2/INT割込み?
	GOTO	GP2INT		;  Yes
	GOTO	INTEXIT		;  No


T0INT       ; << TMR0割込み処理 >>
	BCF	INTCON,T0IF	; 割込みフラグクリア

	BSF	timer,t128uS	; 128μ秒経過フラグをON

	DECFSZ	C25mS,F		; 25mS経過?
	GOTO	INTEXIT		;  No
	BSF	timer,t25mS
	MOVLW	d'195'
	MOVWF	C25mS		; 25mSカウンタ(128uS×195)

	DECFSZ	C5S,F		; 5S経過?
	GOTO	INTEXIT		;  No
	BSF	timer,t5S	; 5秒経過フラグをON
	MOVLW	d'200'
	MOVWF	C5S		; 5Sカウンタ(25mS×200)
	GOTO	INTEXIT

GP2INT      ; << GP2/INT割込み処理 >>
	BCF	INTCON,INTF ; 割込みフラグクリア
	MOVLW	d'1'
	MOVWF	napion		; 1→NaPiOn状態

INTEXIT
	SWAPF	save_st,W
	MOVWF	STATUS		; STATUSレジスタロード
	SWAPF	save_w,F
	SWAPF	save_w,W	; W-regロード
	RETFIE			; 割込み許可にしてリターン
    ; ここまで割込み処理


; ================= PICの初期化 =========================
INIT
	MOVLW	07h
	MOVWF	CMCON0		;GP2-0はデジタルIO  

	BSF	STATUS,RP0	;■バンク1に切替え
	MOVLW	0Dh
	MOVWF	TRISIO		; GP0,2,3は入力,GP1,4,5は出力
	MOVLW	088h		; OPTIONレジスタの設定
	MOVWF	OPTION_REG	; ^RBPU:1 ,INTEDG:0 ,T0CS:0 ,PSA:1 ,PS2-PS0:000
	MOVLW	070h		; CLOCK=8MHz
	MOVWF	OSCCON
	CLRF	ANSEL		;デジタルIO(AN機能を使用しない)
	BCF	STATUS,RP0	;■バンク0に切替え


	CLRF	GPIO		; GPIOをクリア
	CLRF	TMR0		; TMR0をクリア
	MOVLW	0A0h		; INTCONの設定
	MOVWF	INTCON		; GIE:1 ,T0IE:1(TMR0割り込み許可)

	MOVLW	d'195'
	MOVWF	C25mS		; 25mSカウンタ(128uS×195)
	MOVLW	d'200'
	MOVWF	C5S		; 5Sカウンタ(25mS×200)

	CLRF    timer
	CLRF    napion


	; 電源ON後、NaPiOnの回路が安定するまで5秒待つ
	BSF	GPIO,5		; 電源ON後NaPiOnが安定するまで高輝度LED一つを点灯
WAIT5S
	BTFSS	timer,t5S	; 5秒経過フラグON?
	GOTO	WAIT5S		;  No
	BCF	GPIO,5		; 高輝度LED消灯

	BSF	INTCON,INTE	; RB0/INT割込み許可


; ================= メイン処理 =========================
MAIN
	BTFSS	napion,0	; NaPiOn状態は1?
	GOTO	NAPI2		;  No

NAPI1
    ; << NaPiOn状態が1の時(GP2/INT割込み発生) >>
	CLRF	TMR0		; TMR0クリア

	BCF	timer,t5S	; 5秒経過フラグクリア
	MOVLW	d'200'
	MOVWF	C5S		; 5Sカウンタ(25mS×200)

	MOVLW	d'2'
	MOVWF	napion		; NaPiOn状態を2にする

	GOTO	MAIN

    ; << NaPiOn状態が1で無い時 >>
NAPI2
	BTFSS	GPIO,3		; 暗い?
	GOTO	SLEEPMODE	;  No

	BTFSS	napion,1	; NaPiOn状態は2?
	GOTO	MAIN		;  No

	BSF	GPIO,1		; GP1をONにする
	BSF	GPIO,4		; GP4をONにする
	BSF	GPIO,5		; GP5をONにする

	BTFSS	timer,t5S	; 5秒経過フラグ=1?
	GOTO	MAIN		;  No

SLEEPMODE
	BCF	GPIO,1		; GP1をOFFにする
	BCF	GPIO,4		; GP4をOFFにする
	BCF	GPIO,5		; GP5をOFFにする
	CLRF	napion		; NaPiOn状態を0にする

	SLEEP			; 省電力モードで待機(GP2/INT割込み待ち)

	MOVLW	d'1'
	MOVWF	napion		; NaPiOn状態を1にする

	GOTO	MAIN


	END
; =========================== ここまで ===============================