PIC16F648でタイマ機能を使うときに参考になるサイト

・電力線通信技術
家庭用PLC機器製品として2万円台で登場しているという
のを以前WEBニュースで見たことがありました。
LANケーブルや無線LANアンテナを別途に設置する必要がなく、
一般の人も知っている電源コンセントでインターネット
利用できるこの技術は、まだセキュリティになどの問題を残すと言われて
いても注目されているブースと感じました。
会場では、すでに大規模ビル設備のネット装置として紹介している
製品などもありました。今後、さまざまな分野で応用が期待される
技術と感じました。







・PICのタイマなどのモジュールに関する説明
http://www.picfun.com/module00.html


・PIC16F648データシート
http://ww1.microchip.com/downloads/en/DeviceDoc/40044F.pdf


・RETFIEというアセンブラ命令
http://cai.cs.shinshu-u.ac.jp/susi/Lecture/microcomp/d_03-02-12.html

	LIST	P=PIC16F84  ;CPUの指定
	INCLUDE  "P16F84.INC" ;定数ラベルファイル
	ORG	0	   ;RESETの入口
	GOTO	MAIN	  ;メインルーチンへ
	ORG	4	   ;割込みの入口
	GOTO	INTR	  ;割込み処理ルーチンへ
MAIN
	BSF		STATUS,RP0  ;ページ1に切替え
	MOVLW   087H	  ;256カウントモード指定
	MOVWF   OPTION_REG   ;プリセットカウンタへ出力
	BCF		STATUS,RP0  ;ページ0に切替え
	MOVLW   03CH	  ;カウント値ロード
	MOVWF   TMR0	  ;TMR0へ出力
	BSF		INTCON,T0IE  ;タイマ割込み許可
	BSF		INTCON,GIE   ;全体割込み許可
IDLE
	 NOP
	(他の処理)
	GOTO	IDLE	  ;割込み待ちループ
INTR
	 BCF	INTCON,T0I  ;割込みフラグクリア
	MOVLW   03CH	  ;カウント値ロード
	MOVWF   TMR0	  ;TMR0へ出力 (他の処理)
	RETFIE		  ;割込み許可リター


http://homepage1.nifty.com/rikiya/software/314.TIMER1.htm



	list      p=16F648A             ; list directive to define processor
	#include <P16F648A.INC>         ; processor specific variable definitions

	__CONFIG   _CP_OFF & _WDT_OFF & _PWRTE_ON & _XT_OSC

;***** VARIABLE DEFINITIONS
w_temp02        EQU     0x0C        ; variable used for context saving 

cnt_data		EQU		0x26
CE_data			EQU		0x27
w_temp			EQU		0x28			; variable used for context saving
w_PORTA_temp	EQU		0x29			;PORTAの入力値の一時保管
cnt_data02		EQU		0x2A
w_PORTA_temp02	EQU		0x2B
CNT2			EQU		0x2C
OUT_SIG1		EQU		0x2D
CNT1			EQU		0x2E
count			EQU		0x2F
CNT3			EQU		0x30


time3		EQU	0FFh		;LED time3


sound1_val		EQU	B'00000000'
sound2_val		EQU	B'00001101'
sound3_val		EQU	B'00011010'
					

;**********************************************************************
		ORG     0x000             ; processor reset vector
  		goto    main_setting              ; go to beginning of program


	org     0x04		; 割り込みアドレス
	btfsc	PIE1,TMR1IE	;タイマー1の割り込み?
	goto	INT_TMR1	; カウントを開始へジャンプ
	btfsc	PIE1,TMR2IE	;タイマー2の割り込み?
	goto    INT_TMR2	;カウント設定へジャンプ
         btfsc    INTCON,T0IF        ;タイマー0の割り込み?
         goto		INT_TMR3
	retfie			; 別の割り込みなら戻る










;

main_setting
		bsf     STATUS,RP0			;メモリーバンクを1にセット
		movlw	007h
		movwf	TRISA				;ポートAをすべて入力に設定
;
		movlw	000h
		movwf	TRISB				;ポートBをすべて出力に設定
;
;
		bsf		PCON,3				;内部クロックを4MHzに設定
		bcf		OPTION_REG,5		;ICの14pinをCLKOUTに設定
		bcf		RCSTA,7				;RCSTAレジスタの7ビット目(RB1ポート)のシリアル通信を無効にする。

       movlw   000H            ;Wレジスタに80Hをセット
       movwf   OPTION_REG      ;OPTION_REGに80Hをセット PORT-B PULL UPなし
       bcf     STATUS,RP0      ;メモリーバンクを0にセット

		movlw	B'00000111'
		movwf	CMCON				;PORTAI/Oピンに設定する。

		movlw	020h
		movwf	PORTB				;ポートBを全OFF状態にする。
		bsf		PORTB,5
		bsf		w_temp,5
		bsf		CE_data,5

		bsf		T1CON,TMR1ON		;タイマ1ON

start

	bsf		INTCON,T0IE			;タイマ0の割り込みを許可する。
	bcf		INTCON,GIE			; 全体の割り込みを禁止する
	bcf		INTCON,RBIE	; ポートBの割り込みを禁止する
	bcf		INTCON,RBIF	; ポートBの割り込みを削除する
	bcf		INTCON,INTE	; RB0 の割り込みを禁止する




	bsf		STATUS,RP0	; レジスタバンク1を選択	
	BSF	PIE1,TMR1IE	;TMR1オーバーフロー割り込み許可
	bsf		OPTION_REG,INTEDG	; 立ち上がりで割り込みが反応する
	bcf		OPTION_REG,NOT_RBPU	; ポートBのプルアップを有効にする
	movlw   B'11111111'	; 
	movwf   TRISB		; ポートBを全部入力用にする
	movlw   B'00000'	;
	movwf   TRISA		; ポートAを全部出力用にする
	bcf     STATUS,RP0	; レジスタバンク0を選択


	MOVLW	30H			;Wレジスタに30Hをセット
	MOVWF	T1CON		;T1CONレジスタ プリスケーラ1:8 停止




	MOVLW	00H			;Wレジスタに00Hをセット
	MOVWF	TMR1L		;TMR1Lに下位8ビットデータをセット
	MOVLW	00H			;Wレジスタに00Hをセット
	MOVWF	TMR1H		;TMR1Hに上位8ビットデータをセット
	CLRF	CNT1		;CNT1変数を00Hにクリア

	bsf		INTCON,PEIE			;タイマ1、タイマ2の割り込みを許可する。

	bcf		PORTA,4		; 赤いLEDを消す
	bsf		INTCON,GIE	; 全体の割り込みを許可する
	BSF		T1CON,TMR1ON	;TMR1TMR1ONビットをセット カウント開始


wait
	goto	wait		; 割り込みを待つ

setcount
	movf	PORTB,0		; PORTB -> W
	andlw	B'11110000'	; 下位 4 ビットを 0 にする
	movwf	count		; W -> count
	swapf	count,1		; 上位 4 ビットと下位 4 ビットを入れ替える
	movf	count,0		; count -> W
	movwf	PORTA		; W -> PORTA
	bcf	INTCON,RBIF	; 割り込みをリセット
	retfie			; 割り込み処理から復帰

count_begin
	clrw			; 0 -> W
	movwf	PORTA		; LEDを消す
	bsf	PORTA,4		; 赤いLEDを点灯
	goto	wait		; 割り込みを無効にしたまま待つ

INT_TMR1
		MOVLW   00H                        ;Wレジスタに00Hをセット
		MOVWF   TMR1L                    ;TMR1Lに下位8ビットデータをセット
		MOVLW   00H                        ;Wレジスタに00Hをセット
		MOVWF   TMR1H                    ;TMR1Hに上位8ビットデータをセット 

		BCF		PIR1,TMR1IF                ;オーバーフローフラグのクリア
		BSF		STATUS,RP0                ;メモリーバンクを1にセット
		BSF		PIE1,TMR1IE                 ;オーバーフロー割り込み許可
		BCF		STATUS,RP0                ;メモリーバンクを0にセット

		INCF	CNT1,F                        ;変数CNT1に+1する。
		MOVF	CNT1,W                        ;WレジスタにCNT1の値をセット
		MOVWF	PORTB                        ;PORTBCNT1の値を出力


;[ if _DATA1 < _DATA2 then goto Xxx ]
		movf	CNT1,W
		subwf	0xFF,W
		btfss	STATUS,C
		goto	Xxx
		RETFIE

Xxx
	COMF	OUT_SIG1
	RETFIE                                      ;割り込みを許可してリターン


INT_TMR2
;        MOVLW	00H                        ;Wレジスタに00Hをセット
;       MOVWF	TMR2L                    ;TMR1Lに下位8ビットデータをセット
;        MOVLW	00H                        ;Wレジスタに00Hをセット
;        MOVWF	TMR2H                    ;TMR1Hに上位8ビットデータをセット 

		BCF		PIR1,TMR2IF             ;オーバーフローフラグのクリア
		BSF		STATUS,RP0                ;メモリーバンクを1にセット
		BSF		PIE1,TMR2IE              ;オーバーフロー割り込み許可
		BCF		STATUS,RP0                ;メモリーバンクを0にセット

		INCF	CNT2,F                        ;変数CNT1に+1する。
		MOVF	CNT2,W                        ;WレジスタにCNT1の値をセット
		MOVWF	PORTB                        ;PORTBCNT1の値を出力

		RETFIE                                      ;割り込みを許可してリターン


INT_TMR3
		BCF		INTCON,T0IF              ;オーバーフローフラグのクリア
		BSF		STATUS,RP0                ;メモリーバンクを1にセット
		BSF		INTCON,T0IE              ;オーバーフロー割り込み許可
		BCF		STATUS,RP0                ;メモリーバンクを0にセット

		INCF	CNT3,F                        ;変数CNT1に+1する。
		MOVF	CNT3,W                        ;WレジスタにCNT1の値をセット
		MOVWF	PORTB                        ;PORTBCNT1の値を出力

		RETFIE      


END

;**********************************************************************
;    Filename:	    miracle.asm                                       *
;    Date:          2001/3/26                                        *
;    File Version:                                                    *
;**********************************************************************

	list      p=16F648A             ; list directive to define processor
	#include <P16F648A.INC>         ; processor specific variable definitions

	__CONFIG   _CP_OFF & _WDT_OFF & _PWRTE_ON & _XT_OSC

;***** VARIABLE DEFINITIONS
w_temp02        EQU     0x0C        ; variable used for context saving 

cnt_data		EQU		0x26
CE_data			EQU		0x27
w_temp			EQU		0x28			; variable used for context saving
w_PORTA_temp	EQU		0x29			;PORTAの入力値の一時保管
cnt_data02		EQU		0x2A
w_PORTA_temp02	EQU		0x2B
CNT2			EQU		0x2C
OUT_SIG1		EQU		0x2D
CNT1			EQU		0x2E
count			EQU		0x2F
CNT3			EQU		0x30
CNT5			EQU		0x31
CNT6			EQU		0x32
CNT7			EQU		0x33
SW_CNT			EQU		0x34
OSC_001_WAVE	EQU		0x35
OSC_002_WAVE	EQU		0x36
OSC_003_WAVE	EQU		0x37
DATA2			EQU		0x38
CNT8			EQU		0x39
OSC_004_WAVE	EQU		0x3A
DATA4			EQU		0x3B
DATA5			EQU		0x3C
DATA1			EQU		0x3D
DATA3			EQU		0x3E

time3		EQU	0FFh		;LED time3


sound1_val		EQU	B'00000000'
sound2_val		EQU	B'00001101'
sound3_val		EQU	B'00011010'
					

;**********************************************************************
		ORG     0x000             ; processor reset vector
  		goto    main_setting              ; go to beginning of program


		org     0x04		; 割り込みアドレス
		btfsc	PIE1,TMR1IE	;タイマー1の割り込み?
		goto	INT_TMR1	; カウントを開始へジャンプ
		btfsc	PIE1,TMR2IE	;タイマー2の割り込み?
		goto    INT_TMR2	;カウント設定へジャンプ
		btfsc	INTCON,T0IF	;タイマー0の割り込み?
		goto	INT_TMR3
		retfie				; 別の割り込みなら戻る

;

main_setting
		bsf     STATUS,RP0			;メモリーバンクを1にセット
		movlw	007h
		movwf	TRISA				;ポートAをすべて入力に設定
;
		movlw	000h
		movwf	TRISB				;ポートBをすべて出力に設定
;
;
		bsf		PCON,3				;内部クロックを4MHzに設定
		bcf		OPTION_REG,5		;ICの14pinをCLKOUTに設定
		bcf		RCSTA,7				;RCSTAレジスタの7ビット目(RB1ポート)のシリアル通信を無効にする。
		
		movlw   000H            ;Wレジスタに80Hをセット
		movwf   OPTION_REG      ;OPTION_REGに80Hをセット PORT-B PULL UPなし
		bcf     STATUS,RP0      ;メモリーバンクを0にセット

		movlw	B'00000111'
		movwf	CMCON				;PORTAI/Oピンに設定する。

		movlw	020h
		movwf	PORTB				;ポートBを全OFF状態にする。
		bsf		PORTB,5
		bsf		w_temp,5
		bsf		CE_data,5

		bsf		T1CON,TMR1ON		;タイマ1ON

start
		bsf		INTCON,T0IE			;タイマ0の割り込みを許可する。
		bcf		INTCON,GIE			; 全体の割り込みを禁止する
		bcf		INTCON,RBIE	; ポートBの割り込みを禁止する
		bcf		INTCON,RBIF	; ポートBの割り込みを削除する
		bcf		INTCON,INTE	; RB0 の割り込みを禁止する




		bsf		STATUS,RP0	; レジスタバンク1を選択	
		BSF		PIE1,TMR1IE	;TMR1オーバーフロー割り込み許可
		bsf		OPTION_REG,INTEDG	; 立ち上がりで割り込みが反応する
		bcf		OPTION_REG,NOT_RBPU	; ポートBのプルアップを有効にする
		movlw   B'00000000'	; 
		movwf   TRISB		; ポートBを全部入力用にする
		movlw   B'00000'	;
		movwf   TRISA		; ポートAを全部出力用にする
		bcf     STATUS,RP0	; レジスタバンク0を選択


		MOVLW	30H			;Wレジスタに30Hをセット
		MOVWF	T1CON		;T1CONレジスタ プリスケーラ1:8 停止




		MOVLW	00H			;Wレジスタに00Hをセット
		MOVWF	TMR1L		;TMR1Lに下位8ビットデータをセット
		MOVLW	00H			;Wレジスタに00Hをセット
		MOVWF	TMR1H		;TMR1Hに上位8ビットデータをセット
		CLRF	CNT1		;CNT1変数を00Hにクリア

		bsf		INTCON,PEIE			;タイマ1、タイマ2の割り込みを許可する。

		bcf		PORTA,4		; 赤いLEDを消す
		bsf		INTCON,GIE	; 全体の割り込みを許可する
		BSF		T1CON,TMR1ON	;TMR1TMR1ONビットをセット カウント開始
		movlw	0x00
		movwf	CNT1
		movwf	CNT2
		movwf	CNT3
		movwf	OSC_001_WAVE
		movwf	OSC_002_WAVE
		movwf	OSC_003_WAVE
		movwf	SW_CNT
		movwf	OSC_004_WAVE

wait
		goto	wait		; 割り込みを待つ

setcount
		movf	PORTB,0		; PORTB -> W
		andlw	B'11110000'	; 下位 4 ビットを 0 にする
		movwf	count		; W -> count
		swapf	count,1		; 上位 4 ビットと下位 4 ビットを入れ替える
		movf	count,0		; count -> W
		movwf	PORTA		; W -> PORTA
		bcf	INTCON,RBIF	; 割り込みをリセット
		retfie			; 割り込み処理から復帰

count_begin
		clrw			; 0 -> W
		movwf	PORTA		; LEDを消す
		bsf	PORTA,4		; 赤いLEDを点灯
		goto	wait		; 割り込みを無効にしたまま待つ

INT_TMR1
		bcf		INTCON,GIE				; 全体の割り込みを禁止する
		MOVLW   00H						;Wレジスタに00Hをセット
		MOVWF   TMR1L					;TMR1Lに下位8ビットデータをセット
		MOVLW   00H						;Wレジスタに00Hをセット
		MOVWF   TMR1H					;TMR1Hに上位8ビットデータをセット 

		BCF		PIR1,TMR1IF                ;オーバーフローフラグのクリア
		BSF		STATUS,RP0                ;メモリーバンクを1にセット
		BSF		PIE1,TMR1IE                 ;オーバーフロー割り込み許可
		BCF		STATUS,RP0                ;メモリーバンクを0にセット

		INCF	CNT1,F                        ;変数CNT1に+1する。
		MOVF	CNT1,W                        ;WレジスタにCNT1の値をセット
		MOVWF	PORTB                        ;PORTBCNT1の値を出力


;[ if _DATA1 < _DATA2 then goto Xxx ]
		;movf	CNT1,W
		;subwf	0xFF,W
		;btfss	STATUS,C
		;goto	Xxx
		RETFIE

Xxx
		COMF	OUT_SIG1
		RETFIE                                      ;割り込みを許可してリターン


INT_TMR2
;        MOVLW	00H                        ;Wレジスタに00Hをセット
;       MOVWF	TMR2L                    ;TMR1Lに下位8ビットデータをセット
;        MOVLW	00H                        ;Wレジスタに00Hをセット
;        MOVWF	TMR2H                    ;TMR1Hに上位8ビットデータをセット 
		bcf		INTCON,GIE			; 全体の割り込みを禁止する
		BCF		PIR1,TMR2IF             ;オーバーフローフラグのクリア
		BSF		STATUS,RP0                ;メモリーバンクを1にセット
		BSF		PIE1,TMR2IE              ;オーバーフロー割り込み許可
		BCF		STATUS,RP0                ;メモリーバンクを0にセット

		INCF	CNT2,F                        ;変数CNT1に+1する。
		MOVF	CNT2,W                        ;WレジスタにCNT1の値をセット
		MOVWF	PORTB                        ;PORTBCNT1の値を出力

		RETFIE                                      ;割り込みを許可してリターン


INT_TMR3
		bcf		INTCON,GIE				; 全体の割り込みを禁止する
		BCF		INTCON,T0IF				;オーバーフローフラグのクリア
		BSF		STATUS,RP0				;メモリーバンクを1にセット
		BSF		INTCON,T0IE				;オーバーフロー割り込み許可
		BCF		STATUS,RP0				;メモリーバンクを0にセット

		INCF	CNT3,F					;変数CNT1に+1する。



; _DATA1 の bit 3 を _DATA2 の bit 7 にコピー
;
		btfss	OSC_001_WAVE,0
		bcf		PORTB,0
		btfsc	OSC_001_WAVE,0
		bsf		PORTB,0

; _DATA1 の bit 3 を _DATA2 の bit 7 にコピー
;
		btfss	OSC_002_WAVE,0
		bcf		PORTB,1
		btfsc	OSC_002_WAVE,0
		bsf		PORTB,1

; _DATA1 の bit 3 を _DATA2 の bit 7 にコピー
;
		btfss	OSC_003_WAVE,0
		bcf		PORTB,2
		btfsc	OSC_003_WAVE,0
		bsf		PORTB,2

; _DATA1 の bit 3 を _DATA2 の bit 7 にコピー
;
		btfss	OSC_004_WAVE,0
		bcf		PORTB,3
		btfsc	OSC_004_WAVE,0
		bsf		PORTB,3


		INCF	SW_CNT,F
;[ if _DATA1 = _DATA2 then goto Xxx ]
		movlw	0x01
		xorwf	SW_CNT,W
		btfsc	STATUS,Z
		goto	OSC_001


;[ if _DATA1 = _DATA2 then goto Xxx ]
		movlw	0x02
		xorwf	SW_CNT,W
		btfsc	STATUS,Z
		goto	OSC_002

;[ if _DATA1 = _DATA2 then goto Xxx ]
		movlw	0x03
		xorwf	SW_CNT,W
		btfsc	STATUS,Z
		goto	OSC_003

;[ if _DATA1 = _DATA2 then goto Xxx ]
		movlw	0x04
		xorwf	SW_CNT,W
		btfsc	STATUS,Z
		goto	OSC_004




;[ if _DATA1 < _DATA2 then goto Xxx ]
		movlw	0x03
		movwf	DATA2
		movf	SW_CNT,W
		subwf	DATA2,W
		btfss	STATUS,C
		goto	CLR_SW

		RETFIE      					;割り込みを許可してリターン

CLR_SW
		movlw	0x00
		movwf	SW_CNT
		RETFIE


OSC_001
		movlw	0x03
		movwf	DATA1
		INCF	CNT5,F
;[ if _DATA1 < _DATA2 then goto Xxx ]
		movf	CNT5,W
		subwf	DATA1,W
		btfss	STATUS,C
		goto	OSC_001_02
		RETFIE	
OSC_001_02
		COMF	OSC_001_WAVE
		movlw	0x00
		movwf	CNT5
		RETFIE


OSC_002
		movlw	0xAA
		movwf	DATA3
		INCF	CNT6,F
;[ if _DATA1 < _DATA2 then goto Xxx ]
		movf	CNT6,W
		subwf	DATA3,W
		btfss	STATUS,C
		goto	OSC_002_02
		RETFIE	
OSC_002_02
		COMF	OSC_002_WAVE
		movlw	0x00
		movwf	CNT6
		RETFIE



OSC_003
		movlw	0x55
		movwf	DATA4
		INCF	CNT7,F
;[ if _DATA1 < _DATA2 then goto Xxx ]
		movf	CNT7,W
		subwf	DATA4,W
		btfss	STATUS,C
		goto	OSC_003_02
		RETFIE	
OSC_003_02
		COMF	OSC_003_WAVE
		movlw	0x00
		movwf	CNT7
		RETFIE


OSC_004
		movlw	0x33
		movwf	DATA5
		INCF	CNT8,F
;[ if _DATA1 < _DATA2 then goto Xxx ]
		movf	CNT8,W
		subwf	DATA5,W
		btfss	STATUS,C
		goto	OSC_004_02
		RETFIE	
OSC_004_02
		COMF	OSC_004_WAVE
		movlw	0x00
		movwf	CNT8
		RETFIE



END