;_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
;　茹沙都子タイマ　0～10000カウント　＋　赤くなる
;　内部クロック（4MHz）使用
;				Ver　01.00.00
;				Jan./28/2006
;				by. すきやき工房
;_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
	list      p=16f628A
	#include <p16F628A.inc>
	errorlevel  -302              ; リストファイルからの　message 302 を抑制する
	__CONFIG _INTOSC_OSC_NOCLKOUT & _BODEN_OFF & _CP_OFF & _DATA_CP_OFF  & _LVP_OFF & _WDT_OFF & _MCLRE_OFF
;********　変数定義
w_temp        EQU     0x71        ; コンテキスト保存用
status_temp   EQU     0x72        ; コンテキスト保存用
CNT1	EQU	0x022		;カウンタ
TMP	EQU	0x023
CNT2	EQU	0x024
SEG0	EQU	0x025		;7セグ0桁目の値
SEG1	EQU	0x026		;7セグ1桁目の値：０なら非表示、0xAなら0を表示。さいごは1、0xB、0xCでニヤリ
SEG2	EQU	0x027		;7セグ2桁目の値
SEG3	EQU	0x028		;7セグ3桁目の値
SEG4	EQU	0x029		;7セグ4桁目の値
SEG5	EQU	0x030		;7セグ5桁目の値
SEG70	EQU	0x031		
SEG71	EQU	0x032		;“１”表示用データ格納用
SEG72	EQU	0x033		;“2”表示用データ格納用
SEG73	EQU	0x034		;“3”表示用データ格納用
SEG74	EQU	0x035		;“4”表示用データ格納用
SEG75	EQU	0x036		;“5”表示用データ格納用
SEG76	EQU	0x037		;“6”表示用データ格納用
SEG77	EQU	0x038		;“7”表示用データ格納用
SEG78	EQU	0x039		;“8”表示用データ格納用
SEG79	EQU	0x03A		;“9”表示用データ格納用
SEG7A	EQU	0x03B		;“0”表示用データ格納用
SEG7B	EQU	0x03C		;“=”表示用データ格納用
SEG7C	EQU	0x03D		;“-”表示用データ格納用
DNUM	EQU	0x03F		;表示用サブルーチンへの値受け渡し用
COLM	EQU	0x040		;表示対象の桁(ニットで指定)	
TENTO	EQU	0x041		;点灯保持時間	
SHOUT	EQU	0x042		;消灯（フェードアウト用）
FEDOC	EQU	0x043		;
STRED	EQU	0x044		;赤くするためのカウンタ40カウント周期で、デューティー値カウントアップさせる
NINIF	EQU	0x045		;フラグ用
DIPSW	EQU	0x046
SEC_C	EQU	0x050		;1秒カウント用
CNT3	EQU	0x051
;********　割り込みベクタ
	ORG	0
	goto	main

	ORG	4
;********　割り込み処理
	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
	bcf		PIR1,TMR1IF		;割り込みフラグクリア

	movlw	0xFD			;カウント初期値設定     0x0BDC
	movwf	TMR1H			;((1/(4*10^6))　*　4　*　8　*　(65536-0xFD8F))=0.005sec
	movlw	0x8F			;１サイクル＝４クロック：プリスケーラ8
	movwf	TMR1L
	decfsz	SEC_C,f			;２00回の割り込みで１秒
	goto	rtn

	movlw	D'200'
	btfss	PORTA,4		;dip1
	movlw	D'2'
	movwf	SEC_C

	btfss	NINIF,2		;ボードチェック用フラグ
	goto	ramen
	movlw	D'100'
	movwf	SEC_C
	call	count_chk
	goto	rtn

ramen
	btfss	NINIF,3		;180秒用フラグ
	goto	satoko_red
	movlw	D'200'
	movwf	SEC_C
	call	count_dou
	goto	rtn

satoko_red
	decfsz	STRED,f			;40回の割り込みで1段階赤くする
	goto	seg1_co
	incf		CCPR1L,f			;デューティー値+1
	movlw	D'40'
	movwf	STRED	

seg1_co						;***  ７ｓｅｇ１桁目カウントアップ
	movf	SEG1,w	
	xorlw	0x0a
	btfss	STATUS,Z		;現在の表示は、0xAか？
	goto	seg1_9			;異なれば、0x９かどうかのチェックへ
	movlw	0x01
	movwf	SEG1
	goto	rtn
seg1_9
	movf	SEG1,w	
	xorlw	0x09
	btfss	STATUS,Z		;現在の表示は、0x9か？
	goto	cup1
	incf		SEG1,f
	goto	seg2_co
cup1
	incf		SEG1,f
	goto	rtn

seg2_co						;***  ７ｓｅｇ2桁目カウントアップ
	movf	SEG2,w	
	xorlw	0x0a
	btfss	STATUS,Z		;現在の表示は、0xAか？
	goto	seg2_9			;異なれば、0x９かどうかのチェックへ
	movlw	0x01
	movwf	SEG2
	goto	rtn

seg2_9
	movf	SEG2,w	
	xorlw	0x09
	btfss	STATUS,Z		;現在の表示は、0x9か？
	goto	cup2
	incf		SEG2,f
	goto	seg3_co

cup2
	incf		SEG2,f
	goto	rtn

seg3_co						;***  ７ｓｅｇ3桁目カウントアップ
	movf	SEG3,w	
	xorlw	0x0a
	btfss	STATUS,Z		;現在の表示は、0xAか？
	goto	seg3_9			;異なれば、0x９かどうかのチェックへ
	movlw	0x01
	movwf	SEG3
	goto	rtn
seg3_9
	movf	SEG3,w	
	xorlw	0x09
	btfss	STATUS,Z		;現在の表示は、0x9か？
	goto	cup3
	incf		SEG3,f
	goto	seg4_co
cup3
	incf		SEG3,f
	goto	rtn

seg4_co						;*** ７ｓｅｇ4桁目カウントアップ
	movf	SEG4,w	
	xorlw	0x0a
	btfss	STATUS,Z		;現在の表示は、0xAか？
	goto	seg4_9			;異なれば、0x９かどうかのチェックへ
	movlw	0x01
	movwf	SEG4
	goto	rtn
seg4_9
	movf	SEG4,w	
	xorlw	0x09
	btfss	STATUS,Z		;現在の表示は、0x9か？
	goto	cup4
	incf		SEG4,f
	goto	seg5_co

cup4
	incf		SEG4,f
	goto	rtn

seg5_co						;*** ７ｓｅｇ5桁目
	incf		SEG5,f
	bcf		PIE1,TMR1IE		;タイマ1割り込み禁止
	bcf		T1CON,TMR1ON		;タイマ1停止

	movlw	0xFF
	movwf	CCPR1L			;デューティー値0xFF

	bsf		NINIF,0			;カウントエンドフラグ

rtn							;出口
	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
;********　メインプログラム
main
	;ポートの初期設定
	bsf		STATUS,RP0		;バンク１に切り替え
	bsf		PCON,OSCF		;4M
	movlw	b'00110000'
	movwf	TRISA			;RA0～3,6,7 出力：4,5 入力
	clrf		TRISB			;RB0～7 全出力
	bcf		STATUS,RP0		;バンク0に切り替え
	;ｃｃｐ１初期設定
	movlw	0x0F			;PWMモードに設定
	movwf	CCP1CON
	clrf		CCPR1L			;デューティ0に設定
	;タイマー2の初期設定
	movlw	0x04			;タイマ２イネーブル
	movwf	T2CON
	bsf		STATUS,RP0		;バンク１に切り替え
	movlw	0xFF			;周波数設定
	movwf	PR2

	bsf		PIE1,TMR1IE		;タイマ1割り込み許可

	bcf		STATUS,RP0		;バンク0に切り替え

	;タイマー1の初期設定
	movlw	b'00110001'		;プリスケーラ8；内部クロック
	movwf	T1CON	;プリセットカウンタへ出力
	movlw	0x0B			;カウント初期値設定     0x0BDC
	movwf	TMR1H			;((1/(4*10^6))　*　4　*　8　*　(65536-0x0BDC))=0.5sec
	movlw	0xDC			;１サイクル＝４クロック：プリスケーラ8
	movwf	TMR1L
	bsf		INTCON,PEIE		;周辺割り込み許可
	bsf		INTCON,GIE		;全体割り込み許可
	;変数値の初期設定
	clrf		SEG0
	clrf		SEG1
	clrf		SEG2
	clrf		SEG3
	clrf		SEG4
	clrf		SEG5
	clrf		DIPSW

	movlw	b'00000000'			;表示用データ格納
	movwf	SEG70
	movlw	b'00000101'
	movwf	SEG71
	movlw	b'10110011'
	movwf	SEG72
	movlw	b'10010111'
	movwf	SEG73
	movlw	b'01010101'
	movwf	SEG74
	movlw	b'11010110'
	movwf	SEG75
	movlw	b'11110110'
	movwf	SEG76
	movlw	b'10000101'
	movwf	SEG77
	movlw	b'11110111'
	movwf	SEG78
	movlw	b'11010101'
	movwf	SEG79
	movlw	b'11100111'
	movwf	SEG7A
	movlw	b'00010010'
	movwf	SEG7B
	movlw	b'00010000'
	movwf	SEG7C
	movlw	b'00000010'
	movwf	COLM

;	movlw	0x00
;	movwf	SEG0
;	movlw	0x0a
;	movwf	SEG1
;	movlw	0x08
;	movwf	SEG2
;	movlw	0x09
;	movwf	SEG3
;	movlw	0x08
;	movwf	SEG4
;	movlw	0x00
;	movwf	SEG5


	movlw	0x0a
	movwf	TENTO	
	clrf		SHOUT
	movlw	0xFF
	movwf	FEDOC	

	movlw	D'40'
	movwf	STRED	

	clrf		NINIF		;

;*************************************ディップスイッチチェック
	btfss	PORTA,4		;dip1
	bsf		DIPSW,0
	btfss	PORTA,5		;dip2
	bsf		DIPSW,1
	movf	DIPSW,w	
	xorlw	b'00000011'
	btfsc	STATUS,Z
	bsf	NINIF,2		;ボードチェック用フラグ
	movf	DIPSW,w	
	xorlw	b'00000010'
	btfsc	STATUS,Z
	bsf	NINIF,3		;

	btfss	NINIF,3		;dip2
	goto	dip_ex
	movlw	0x0a
	movwf	SEG1
	movlw	0x08
	movwf	SEG2
	movlw	0x01
	movwf	SEG3
dip_ex

	movlw	D'200'
	btfss	PORTA,4		;dip1
	movlw	D'2'
	btfsc	NINIF,2		;ボードチェック用フラグ
	movlw	D'100'
	movwf	SEC_C

;**************************************
main_loop
	btfsc	NINIF,0		;カウントエンドフラグ
	call	count_end
	btfsc	NINIF,1		;ににフラグ
	call	count_nini
;↓ボードチェック用
;	movlw	0x0a
;	btfsc	PORTA,4		;1
;	movlw	0x01
;	btfsc	PORTA,5		;1
;	movlw	0x02
;	movwf	SEG0
;	movlw	0xf0
;	movwf	CCPR1L
;↑
	movlw	b'01000000'		;桁０～5までを順に表示
	movwf	COLM
	call		disp_7seg
	movlw	b'10000000'
	movwf	COLM
	call		disp_7seg
	movlw	b'00000001'
	movwf	COLM
	call		disp_7seg
	movlw	b'00000010'
	movwf	COLM
	call		disp_7seg
	movlw	b'00000100'
	movwf	COLM
	call		disp_7seg
	movlw	b'00001000'
	movwf	COLM
	call		disp_7seg

;	incf		CCPR1L,F
;	movlw	0x03			
;	movwf	PORTA
;	movlw	0xFF			
;	movwf	CCPR1L
;	bsf		CCPR1L,7
	goto	main_loop
;*************
count_chk

	movf	SEG4,w
	movwf	SEG5
	movf	SEG3,w
	movwf	SEG4
	movf	SEG2,w
	movwf	SEG3
	movf	SEG1,w
	movwf	SEG2
	movf	SEG0,w
	movwf	SEG1

	incf		SEG0,f
	movf	SEG0,w	
	xorlw	0x0b
	movlw	0x01
	btfsc	STATUS,Z
	movwf	SEG0


	movlw	b'11111111'
	xorwf	CCPR1L,f			;

	return
;*************
count_dou
seg1_du						;７ｓｅｇ１桁目カウントダウン
	movf	SEG1,w	
	xorlw	0x01
	btfss	STATUS,Z		;現在の表示は、0x1か？
	goto	seg1_0			;異なれば、0xaかどうかのチェックへ
	movlw	0x0a
	movwf	SEG1

	movf	SEG2,w	
	xorlw	0x00
	btfsc	STATUS,Z		;seg2の表示は、なしか？
	goto	codou_end

	goto	rtn

seg1_0
	movf	SEG1,w	
	xorlw	0x0a
	btfss	STATUS,Z		;現在の表示は、0xaか？
	goto	cdu1


	decf	SEG1,f
	goto	seg2_du
cdu1
	decf	SEG1,f
	goto	rtn

seg2_du						;７ｓｅｇ2桁目カウントアップ
	movf	SEG2,w	
	xorlw	0x01
	btfss	STATUS,Z		;現在の表示は、0x1か？
	goto	seg2_0			;異なれば、0xaかどうかのチェックへ

	movf	SEG3,w	
	xorlw	0x00
	movlw	0x0a
	btfsc	STATUS,Z		;seg3の表示は、なしか？
	movlw	0x00

	movwf	SEG2
	goto	du_ex

seg2_0
	movf	SEG2,w	
	xorlw	0x0a
	btfsc	STATUS,Z		;現在の表示は、0xaか？
	decf	SEG3,f

	decf	SEG2,f
	goto	du_ex

codou_end
	bcf		PIE1,TMR1IE		;タイマ1割り込み禁止
	bcf		T1CON,TMR1ON		;タイマ1停止

	movlw	0xFF
	movwf	CCPR1L			;デューティー値0xFF

du_ex
	return


;*************
count_end
	btfsc	NINIF,1		;ににフラグ１なら、スキップ
	goto	co_ex
	decfsz	FEDOC,f
	goto	co_ex

	bsf		NINIF,7
	incf		SHOUT,f
	decfsz	TENTO,f	
	goto	co_ex1
	clrf		SEG1
	clrf		SEG2
	clrf		SEG3
	clrf		SEG4
	clrf		SEG5
	bsf		NINIF,1
;	movlw	0x0a
;	movwf	FEDOC
;	goto	co_ex
	movlw	0x01
	movwf	TENTO	
;	clrf		SHOUT

	movlw	0xff
	movwf	CNT3
LOOP4
	call		TIM1m	
	call		TIM1m	
	call		TIM1m	
	call		TIM1m	
	call		TIM1m	
	call		TIM1m	
	call		TIM1m	
	call		TIM1m	
	DECFSZ	CNT3,F
	GOTO	LOOP4


co_ex1



;	movlw	15h
;	MOVWF	CNT1
;	call		TIM10				;待ち時間(あとで変更するよ＊＊＊＊＊＊
	movlw	0x04
	movwf	FEDOC
co_ex
	return
;*************
count_nini
	btfss	NINIF,7		;ににフラグ１なら、スキップ
	goto	co_exn
	decfsz	FEDOC,f
	goto	co_exn
;	bsf		NINIF,1

	movlw	0x0c
	movwf	SEG0
	movlw	0x0b
	movwf	SEG1
	movlw	0x01
	movwf	SEG2
	movlw	0x0c
	movwf	SEG3
	movlw	0x0b
	movwf	SEG4
	movlw	0x01
	movwf	SEG5
	incf		TENTO,f
	decfsz	SHOUT,f	
	goto	co_exn1
;	incf		TENTO,f
;	bcf		NINIF,0
;	movlw	0x0E
;	movwf	TENTO	
;	clrf		SHOUT
	bcf		NINIF,7
	goto	co_exn
co_exn1
;	incf		SHOUT,f
;	bcf		NINIF,7
;	movlw	15h
;	MOVWF	CNT1
;	call		TIM10				;待ち時間(あとで変更するよ＊＊＊＊＊＊
	movlw	0x08
	movwf	FEDOC
co_exn
	return
;*************
;表示する７セグを指定
;選択されている７セグに数字を表示する
disp_7seg
	movf	COLM,w
	movwf   PORTA				;カラム選択

	btfsc	COLM,6				;桁0か？
	movf	SEG0,w				;
	btfsc	COLM,7				;桁1か？
	movf	SEG1,w				;カレントのカラムに表示するデータ
	btfsc	COLM,0				;桁2か？
	movf	SEG2,w				;
	btfsc	COLM,1				;桁3か？
	movf	SEG3,w				;
	btfsc	COLM,2				;桁4か？
	movf	SEG4,w				;
	btfsc	COLM,3				;桁5か？
	movf	SEG5,w				;

	addlw	SEG70				;7セグ 表示パターン格納トップアドレス
	movwf	FSR					;間接アドレッシング：アドレスの指定
	movf	INDF,w				;間接アドレッシング：→Ｗレジスタへ値を格納
	movwf	PORTB				;出力

	xorlw	0x00
	btfsc	STATUS,Z		;カラムの表示は、か？
	goto	no_disp			;表示が無ければ表示なし（ちらつき低減）

	movf	TENTO,w			;フェードアウト処理用点灯時間：通常10msec
	MOVWF	CNT1
	call		TIMW				;待ち時間(あとで変更するよ＊＊＊＊＊＊
	movlw	0x00
	movwf	PORTB				;消灯
no_disp

	btfss	NINIF,7				;フェードアウトか？
	goto	DS_EX
;	INCF	SHOUT
;	DECFSZ	SHOUT,f
;	GOTO	shoutou
;	GOTO NO_DIS
shoutou
	movf	SHOUT,w			;フェードアウト処理用消灯時間：通常0
	MOVWF	CNT1
	call		TIMW				;待ち時間2(あとで変更するよ＊＊＊＊＊＊10000表示用
DS_EX
	return
;*************
;ウェイトサブルーチン
;4クロックで１サイクル、4MHz では 1cycleで、1usec
TIMW
LOOP1
	call		TIM500u	
	DECFSZ	CNT1,F
	GOTO	LOOP1
	RETURN

;ウェイトサブルーチン(約1ミリ秒)
;4クロックで１サイクル、4MHz では 1cycleで、1usec
TIM1m
	movlw	0xf9
	movwf	CNT2
LOOP2
	nop			;4*0xf9-1=995	cycle	
	decfsz	CNT2,F
	goto	LOOP2
	return			;2+ 995 +2=999 cycle

;ウェイトサブルーチン(約1ミリ秒)
;4クロックで１サイクル、4MHz では 1cycleで、1usec
TIM500u
	movlw	0x7c
	movwf	CNT2
LOOP3
	nop			;4*0x7c-1=495	cycle	
	decfsz	CNT2,F
	goto	LOOP3
	return			;2+ 19 +2=499 cycle

	end       
