PICを使った防犯ベル用自動再セットタイマープログラム

PIC12F629を使って防犯ベル用自動再セットタイマーを作りました。そのアセンブラープログラムを紹介します。防犯ベルが動作してから一定時間後に停止するようにします。更に停止した後も何度でも動作するように防犯ベルを自動再設定するようにしています。

PIC12F629を使った防犯ベル用自動再セットタイマー

防犯ベル用自動再セットタイマーの回路図

防犯ベルは泥棒が入ろうとした時ベルが鳴りますが、一般的にはベルは鳴り続けます。

これでは周りに迷惑を掛けて不便なので一定時間後に停止するようにしました。

更に停止した後も何度でも動作するように防犯ベルを自動で再設定するようにしました。

しかし製作当時はタイマーの適当なのが見つからなかったので、ナショナルのマルチ レンジタイマー楽天 ATC12112をONモードの5分にして使っていました。

その後、 PICマイコンが使えるようになったので、このATC12112のタイマーをPIC12F629に置き換えてみました。回路やプログラムが簡単にうまくできましたので紹介します。

回路は簡単ですが、プログラムを作らないと動作しません。プログラムは全てアセンブラーで書いています。アセンブラーは一見すると難しそうですが、使えるようになると、細かい動作を簡単に記述できるようになります。

PIC12F629を使ったアセンブラープログラム

; Filename:	bell_timer.asm
; Date:		2007.08.03
; File Version:	1.0
; Bell Timer 3sec. 5min
; Author:		D.Ishikawa
;**********************************************************************
; Files required:
;**********************************************************************
;PICは12F629
;GPIO,2	タイマー出力ポート
;GPIO,3	タイマーの時間を決める入力ポート
;GPIO,3がLの時テスト用3秒タイマーとなります。
;GPIO,3がHの時5分タイマーとなります。
;**********************************************************************

	list	p=12f629		;list directive to define processor
	#include	<p12f629.inc>	;processor specific variable definitions

	errorlevel	-302	; suppress message 302 from list file

	__CONFIG _CP_ON & _CPD_ON & _BODEN_ON & _MCLRE_OFF & _WDT_OFF & _PWRTE_ON & _INTRC_OSC_NOCLKOUT 

#define	OUT_TMR	GPIO,2	;タイマー出力ポート
#define	IN_P	GPIO,3	;入力ポート

;***** VARIABLE DEFINITIONS
w_temp		EQU	0x20	;variable used for context saving 
status_temp	EQU	0x21	;variable used for context saving

TMP_CNT1		EQU 0x22
TMP_CNT2		EQU 0x23
TMP_CNT3		EQU 0x24
TMP_CNT4		EQU 0x25
;**********************************************************************
	ORG	0x000	;processor reset vector
	goto	main	;go to beginning of program

	ORG	0x004	;interrupt vector location
	movwf	w_temp	;save off current W register contents
	movf	STATUS,w	;move status register into W register
	movwf	status_temp	;save off contents of STATUS register

;isr code can go here or be located as a call subroutine elsewhere

	movf	status_temp,w	;retrieve copy of STATUS register
	movwf	STATUS		;restore pre-isr STATUS register contents
	swapf	w_temp,f
	swapf	w_temp,w		;restore pre-isr W register contents
	retfie	;return from interrupt

;these first 4 instructions are not required if the internal oscillator is not used

main
	call	0x3FF		;retrieve factory calibration value
	bsf	STATUS,RP0	;set file register bank to 1 
	movwf	OSCCAL		;update register with factory cal value 
	bcf	STATUS,RP0	;set file register bank to 0

;remaining code goes here

	bcf	STATUS,RP0	;set file register bank to 0
	bcf	STATUS,RP1	;set file register bank to 0

	clrf	INTCON		;割り込み禁止

	clrf	GPIO		;GPIO初期化

	bsf	STATUS,RP0	;バンク1に切替
	clrf	TRISIO		;GPIOを出力に設定
	bsf	TRISIO,3		;GP3を入力に設定

	clrf	IOC		;I/O状態変化チェック解除
	movlw	b'10000000'	;プルアップ無し、エッジ割り込み無し、タイマー0は内部クロック
	movwf	OPTION_REG	;

	bcf	STATUS,RP0	;バンク0に

	bcf	OUT_TMR		;OUT_TMRを0に

	btfsc	IN_P		;入力ポートチェック
	goto	_5MIN		;Hなら _5MIN へ

_3SEC
	call	DLY_500
	call	DLY_500
	call	DLY_500
	call	DLY_500
	call	DLY_500
	call	DLY_500
SET3	bsf	OUT_TMR	;OUT_TMRを1に
	goto	SET3

_5MIN
	call	DLY_5MIN
SET5	bsf	OUT_TMR	;OUT_TMRを1に
	goto	SET5

;Delay Routine

DLY_5MIN			;5分
	movlw	d'5'		;1*5=5min
	movwf	TMP_CNT4
DLY_4			;60S
	movlw	d'120'		;0.5*120=60S
	movwf	TMP_CNT3
DLY_3
	call	DLY_500
	decfsz	TMP_CNT3,f
	goto	DLY_3
	decfsz	TMP_CNT4,f
	goto	DLY_4
	return

DLY_500			;500mS
	movlw	d'250'		;2mS*250=500mS
	movwf	TMP_CNT2
DLY_2			;2mS	;    DLY_2 loop	DLY_2 を一巡する時間は 6 + 8*249 + 2 = 2000μS
	movlw	d'249'		;	(1)		1cycle=1μS
	movwf	TMP_CNT1		;	(1)
	nop			;	(1)
	nop			;	(1)
	nop			;	(1)
	nop			;	(1)
DLY_1			;  DLY_1 loop
	nop			;1	 1
	nop			;1	 1
	nop			;1	 1
	nop			;1	 1
	nop			;1	 1
	decfsz	TMP_CNT1,f	;1	 2	(TMP_CNT1が0になると2サイクル)
	goto	DLY_1		;2		(12F629の goto は2サイクル)
	decfsz	TMP_CNT2,f	;	 1
	goto	DLY_2		;	(2)
	return

;initialize eeprom locations

	ORG	0x2100
	DE	0x00, 0x01, 0x02, 0x03

	END			;directive 'end of program'

アセンブラープログラムの使い方

ファイル名をbell_timer.asm等にして保存して使ってください。