;******************************************************************************************
;  4桁カウンタサンプル(周波数カウンタ)
;   Project      :
;   Program Name : 
;   Programer    :
;   Create date  :  Version 1.0    H18.05.01
;   History      :
;******************************************************************************************
;  (1)Descript I/O 
;      GP0 : 周波数カウンタ入力 
;      GP4 : Input (RS)
;      GP5 : Output(TX)
;
;******************************************************************************************
	LIST	P=PIC12F683,ST=OFF,R=DEC
	INCLUDE	"P12F683.inc"	;標準ヘッダ定義ファイル
	__CONFIG _INTRC_OSC_NOCLKOUT & _WDT_OFF & _PWRTE_OFF & _MCLRE_OFF & _CP_OFF & _CPD_OFF & _BOD_OFF & _IESO_OFF & _FCMEN_OFF 
;
IODAT	EQU	20H
SENDLP	EQU	21H
SENDWAT	EQU	22H
RECLP	EQU	23H
RECWAT	EQU	24H
MSGCNT	EQU	25H
CNT	EQU	26H
CNT0	EQU	27H
CNT1	EQU	28H
CNT2	EQU	29H
DAT0	EQU	2AH
DAT1	EQU	2BH
DAT2	EQU	2CH
DAT3	EQU	2DH
COU0	EQU	2EH
COU1	EQU	2FH
COU2	EQU	30H
COU3	EQU	31H
OVER	EQU	32H
INTWRG	EQU	33H
INTSTS	EQU	34H
ITRCOU	EQU	35H

	ORG	0		; プログラムスタート
	GOTO	START
	ORG	4		; 割込み処理
	MOVWF	INTWRG		; W-REGの値を保存
	SWAPF	STATUS,W	; STATUSレジスタの値を保存
	MOVWF	INTSTS		; STATUSレジスタの値を保存
;
	MOVLW	H'9E'		; *TMR1
	MOVWF	TMR1H		; *TMR1
	MOVLW	H'58'		; *TMR1
	MOVWF	TMR1L		; *TMR1
;
;
	CALL	CNTITR
;
;
	SWAPF	INTSTS,W	; STATUSレジスタの値を復元
	MOVWF	STATUS		; STATUSレジスタの値を復元
	MOVFW	INTWRG		; W-REGレジスタの値を復元
	BCF	PIR1,TMR1IF	; *割込みフラグをリセット
	RETFIE
;
START
;  1.特殊レジスタの設定
;  (1)内部OSCの設定
	BSF	STATUS,RP0	; BANK1を選択
	BSF	OSCCON,6	; 8MHzを設定
	BSF	OSCCON,5	; 8MHzを設定
	BSF	OSCCON,4	; 8MHzを設定
;  (2)ポートの設定
	BCF	STATUS,RP0	; BANK0を選択
	MOVLW	07H		; BANK0でデジタルIO設定
	MOVWF	CMCON0		; BANK0でデジタルIO設定
	CLRF	GPIO		; BANK0でポート初期化
	BSF	STATUS,RP0	; BANK1を選択
	CLRF	ANSEL		; BANK1でデジタルIO初期化
	MOVLW	B'010001'	; BANK1でPORT設定
	MOVWF	TRISIO		; BANK1でPORT設定
;
	BCF	STATUS,RP0	; BANK0を選択
; 2.変数初期設定
;   (1)送信フラグを送信しないに初期設定
	BSF	GPIO,5	
;   (2)16F88の準備ができるまで少し待つ	
	CALL	TIM05S
;   (3)カウンタを初期化
	CALL	INITCOU
	CLRF	ITRCOU		;
;   (4)デモを表示
	CALL	DEMO1
;
;  2.割込みタイマーを設定
	CALL	SETTIM
;
;  3.処理本体
MAIN
; (1)Hを待つ
MAIN1
	BTFSS	GPIO,0	; ビットデータがLの時	
	GOTO	MAIN1
; (2)Lを待つ
MAIN2
	BTFSC	GPIO,0	; ビットデータがHの時	
	GOTO	MAIN2
; (3)カウントアップ
	CALL	CNTDEC
;
	GOTO	MAIN

;******************************************************************************************
;   Function Name : SETTIM
;   Title         : 割込みタイマーを設定
;   Input         : 
;   Output        : 
;******************************************************************************************
SETTIM
	BCF	STATUS,RP0	; BANK0を選択
	MOVLW	B'00110001'	; ×Bit7(0):Timer1 gate is not inverted
				; *Bit6(0):Timer1 is on
				; *Bit5,4(11):1:8 Prescale Value
				; *Bit3(0)LP osc is enabled for Timer1 colck
				; *Bit2(0):This bit is ignored (<==Bit1)
				; *Bit1(0):Internal clock(Fosc/4) 
				; *Bit0(1):Enable Timer1
	MOVWF	T1CON
	BCF	CMCON1,T1GSS	; *Not use
	MOVLW	H'9E'		; *TMR1
	MOVWF	TMR1H		; *TMR1
	MOVLW	H'58'		; *TMR1
	MOVWF	TMR1L		; *TMR1
	CLRF	ITRCOU		;
	BCF	PIR1,TMR1IF	; *割込みフラグをリセット
	BSF	INTCON,GIE	; *Grobal Interrupt Enable (->1)      ※Total
	BSF	INTCON,PEIE	; *Peripheral Interrupt Enable (->1)  ※Timer etc.
	BSF	STATUS,RP0	; BANK1を選択
	BSF	PIE1,TMR1IE	; *Timer1 Interrupt Enable (->1)      ※Timer1
	BCF	STATUS,RP0	; BANK0を選択
	RETURN

;******************************************************************************************
;   Function Name : CNTITR
;   Title         : 割込みタイマー分周用10進カウンタ
;                   １秒毎に処理を行なう
;   Input         : 
;   Output        : 
;******************************************************************************************
CNTITR
; (1)タイマー割込み処理
	MOVLW	H'01'
	ADDWF	ITRCOU,F	; 0桁目10進カウンタ(0aで桁上げ)
	MOVFW	ITRCOU
	XORLW	H'0A'		; 0A
	BTFSS	STATUS,Z
	RETURN			; １０でないなら何もしない	
; (2)１秒毎に次の処理を行なう
	BSF	GPIO,1
	CALL	SETDN
	CALL	DATOUT
	CALL	INITCOU
	BCF	GPIO,1	
; (3)割込み設定
	CLRF	ITRCOU	
	MOVLW	H'9E'		; *TMR1
	MOVWF	TMR1H		; *TMR1
	MOVLW	H'58'		; *TMR1
	MOVWF	TMR1L		; *TMR1
	RETURN

;******************************************************************************************
;   Function Name : SETDN
;   Title         : カウンタ変数の代入
;   Input         : 
;   Output        : 
;******************************************************************************************
SETDN
	MOVFW	OVER
	XORLW	H'00'
	BTFSS	STATUS,Z
	GOTO	SETDN1
;
	MOVFW	COU0
	MOVWF	DAT0
	MOVFW	COU1
	MOVWF	DAT1
	MOVFW	COU2
	MOVWF	DAT2
	MOVFW	COU3
	MOVWF	DAT3
	RETURN
SETDN1
	MOVLW	H'0E'	; E
	MOVWF	DAT3
	MOVLW	H'1B'	; r
	MOVWF	DAT2
	MOVLW	H'1B'	; r
	MOVWF	DAT1
	MOVLW	H'01'	; 1
	MOVWF	DAT0
	RETURN
;******************************************************************************************
;   Function Name : CNTDEC
;   Title         : 10進(4桁)アップカウンタ
;   Input         : COU0,COU1,COU2,COU3
;   Output        : COU0,COU1,COU2,COU3
;******************************************************************************************
CNTDEC
	MOVLW	H'01'
	ADDWF	COU0,F	; 0桁目10進カウンタ(0aで桁上げ)
	MOVFW	COU0
	XORLW	H'0A'
	BTFSS	STATUS,Z
	RETURN
;
	CLRF	COU0
	MOVLW	H'01'
	ADDWF	COU1,F	; 1桁目10進カウンタ(0aで桁上げ)
	MOVFW	COU1
	XORLW	H'0A'
	BTFSS	STATUS,Z
	RETURN
;
	CLRF	COU1
	MOVLW	H'01'
	ADDWF	COU2,F	; 2桁目10進カウンタ(0aで桁上げ)
	MOVFW	COU2
	XORLW	H'0A'
	BTFSS	STATUS,Z
	RETURN
;
	CLRF	COU2
	MOVLW	H'01'
	ADDWF	COU3,F	; 3桁目10進カウンタ(0aで桁上げ)
	MOVFW	COU3
	XORLW	H'0A'
	BTFSS	STATUS,Z
	RETURN
;
	CALL	INITCOU
	MOVLW	H'01'
	MOVWF	OVER
	RETURN

;******************************************************************************************
;   Function Name : INITCOU
;   Title         : カウンタの初期化
;   Input         : COU0,COU1,COU2,COU3
;   Output        : COU0,COU1,COU2,COU3
;******************************************************************************************
INITCOU
	CLRF	COU0
	CLRF	COU1
	CLRF	COU2
	CLRF	COU3
	CLRF	OVER
	RETURN
;******************************************************************************************
;   Function Name : DEMO1
;   Title         : デモ(16F88と正常に通信がされると、F683と表示される)
;   Input         : 
;   Output        :
;******************************************************************************************
DEMO1
	MOVLW	H'0F'
	MOVWF	DAT3
	MOVLW	H'06'
	MOVWF	DAT2
	MOVLW	H'08'
	MOVWF	DAT1
	MOVLW	H'03'
	MOVWF	DAT0
	CALL	DATOUT
	CALL	TIM1S
	RETURN

;******************************************************************************************
;   Function Name : DATOUT
;   Title         : 16F88へデータを出力
;   Input         : 
;   Output        :
;******************************************************************************************
DATOUT	
; 1.送信開始ステータスにする
	BCF	GPIO,5
; 2.16F88が受信準備ができるまで待つ
DATOUT1
	BTFSC	GPIO,4
	GOTO	DATOUT1
; 3.送信開始
;
	MOVFW	DAT3
	CALL	PSEND
;
	MOVFW	DAT2
	CALL	PSEND
;
	MOVFW	DAT1
	CALL	PSEND
;
	MOVFW	DAT0
	CALL	PSEND
;
	RETURN
;******************************************************************************************
;   Function Name : PSEND
;   Title         : 16F88への送信サブルーチン(GPIO,5)
;                   9600BPS OSC;8.000MHz仕様
;   Input         : 
;   Output        :
;******************************************************************************************
PSEND
	MOVWF	IODAT
; (1)送信開始
	BCF	GPIO,5	; 送信開始
	MOVLW	H'42'	; 9600BPS,OSC;8MHz
	MOVWF	SENDWAT
PSEND1	DECFSZ	SENDWAT,F
	GOTO	PSEND1
;
; (2)データ送信(8ビット)
	MOVLW	8	; 8ビットデータ分、送信する
	MOVWF	SENDLP
	NOP
PSEND2	RRF	IODAT,F
	NOP
	BTFSS	STATUS,C ; ビットデータが0の時, 0を立てる	
	BCF	GPIO,5
	BTFSC	STATUS,C ; ビットデータが1の時, 1を立てる
	BSF	GPIO,5

	MOVLW	H'42'	; パルス(9600BPS,OSC;8MHz)
	MOVWF	SENDWAT
PSEND3	DECFSZ	SENDWAT,F
	GOTO	PSEND3

	DECFSZ	SENDLP,F
	GOTO	PSEND2
; (3)終了
	BSF	GPIO,5	; フラグを戻す
; (4)送信後、少し待つ
;	CALL	TIMER
;	CALL	TIMER
;	CALL	TIMER
;    ※注）12F683のスタックがオーバーフローする可能性があるので、TIMER関数は展開した
;
	MOVLW	H'4E'
	MOVWF	CNT1
STIMER1
	MOVLW	H'64'
	MOVWF	CNT
STIMER2
	DECFSZ	CNT,F
	GOTO	STIMER2 
	DECFSZ	CNT1,F
	GOTO	STIMER1
	RETURN
;
;******************************************************************************************
;   Function Name : TIMER
;   Title         : タイマー(1000回ループ)
;   Input         : 
;   Output        :
;******************************************************************************************
TIMER
	MOVLW	H'1A'
	MOVWF	CNT1
TIMER1
	MOVLW	H'64'
	MOVWF	CNT
TIMER2
	DECFSZ	CNT,F
	GOTO	TIMER2 
	DECFSZ	CNT1,F
	GOTO	TIMER1

	RETURN

;******************************************************************************************
;   Function Name : TIM05S
;   Title         : タイマー(約0.1秒)
;   Input         : 
;   Output        :
;   Description   : 8/4MHz =(200)=> 10KHz =(100)=> 100Hz =(100)=> 1Hz  
;******************************************************************************************
TIM05S
	MOVLW	H'0A'
	MOVWF	CNT2
TIM05S2
	MOVLW	H'64'
	MOVWF	CNT1
TIM05S1
	MOVLW	H'64'
	MOVWF	CNT0
TIM05S0
	DECFSZ	CNT0,F
	GOTO	TIM05S0 
	DECFSZ	CNT1,F
	GOTO	TIM05S1
	DECFSZ	CNT2,F
	GOTO	TIM05S2
	RETURN

;******************************************************************************************
;   Function Name : TIM1S
;   Title         : タイマー(約1秒)
;   Input         : 
;   Output        :
;   Description   : 8/4MHz =(200)=> 10KHz =(100)=> 100Hz =(100)=> 1Hz  
;******************************************************************************************
TIM1S
	MOVLW	H'64'
	MOVWF	CNT2
TIM1S2
	MOVLW	H'64'
	MOVWF	CNT1
TIM1S1
	MOVLW	H'64'
	MOVWF	CNT0
TIM1S0
	DECFSZ	CNT0,F
	GOTO	TIM1S0 
	DECFSZ	CNT1,F
	GOTO	TIM1S1
	DECFSZ	CNT2,F
	GOTO	TIM1S2
	RETURN
;
	END

