;******************************************************************************************
;  周波数カウンタサンプル
;   Project      :
;   Program Name : 
;   Programer    :
;   Create date  :  Version 1.0    H18.05.01
;   History      :
;******************************************************************************************
;  (1)Descript I/O 
;      GP0 : 周波数カウンタ入力 
;      GP1 : Input (RS)
;      GP2 : Output(TX)
;  (2)Range
;      8MHz内部OSCの場合、測定可能な周波数は、デューティー50%の方形波で最大でも100KHz程度
;
;******************************************************************************************
	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
DAT4	EQU	2EH
DAT5	EQU	2FH
COU0	EQU	30H
COU1	EQU	31H
COU2	EQU	32H
COU3	EQU	33H
COU4	EQU	34H
COU5	EQU	35H
OVER	EQU	36H
INTWRG	EQU	37H
INTSTS	EQU	38H

	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'110011'	; BANK1でPORT設定
	MOVWF	TRISIO		; BANK1でPORT設定
;
	BCF	STATUS,RP0	; BANK0を選択
; 2.変数初期設定
;   (1)送信フラグを初期設定
	BSF	GPIO,2	
;   (2)少し待つ	
	CALL	TIM05S
;   (3)カウンタを初期化
	CALL	INITCOU
;   (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'00001111'	; ×Bit7(0):Timer1 gate is not inverted
				; *Bit6(0):Timer1 is on
				; *Bit5,4(00):1:1 Prescale Value
				; *Bit3(1)LP osc is enabled 
				; *Bit2(1):Asynchro
				; *Bit1(1):External clock 
				; *Bit0(1):Enable Timer1
	MOVWF	T1CON
	BCF	CMCON1,T1GSS	; *Not use
	MOVLW	H'80'		; *TMR1
	MOVWF	TMR1H		; *TMR1
	MOVLW	H'01'		; *TMR1
	MOVWF	TMR1L		; *TMR1
	BCF	PIR1,TMR1IF	; *割込みフラグをリセット
	BSF	INTCON,GIE	; *Grobal Interrupt Ebable (->1)      ※Total
	BSF	INTCON,PEIE	; *Peripheral Interrupt Ebable (->1)  ※Timer etc.
	BSF	STATUS,RP0	; BANK1を選択
	BSF	PIE1,TMR1IE	; *Timer1 Interrupt Ebable (->1)      ※Timer1
	BCF	STATUS,RP0	; BANK0を選択
	RETURN

;******************************************************************************************
;   Function Name : CNTITR
;   Title         : 割込み処理(１秒毎に処理を行なう)
;   Input         : 
;   Output        : 
;******************************************************************************************
CNTITR
; (1)１秒毎に次の処理を行なう
	CALL	REC
	CALL	TIM05S
	CALL	SETDN
	CALL	DATOUT
	CALL	INITCOU
; (2)割込み設定
	MOVLW	H'80'		; *TMR1
	MOVWF	TMR1H		; *TMR1
	MOVLW	H'01'		; *TMR1
	MOVWF	TMR1L		; *TMR1
	RETURN

;******************************************************************************************
;   Function Name : SETDN
;   Title         : カウンタ変数の代入
;   Input         : 
;   Output        : 
;******************************************************************************************
SETDN
	MOVFW	OVER
	XORLW	H'00'
	BTFSS	STATUS,Z
	GOTO	SETDN1
;
	MOVFW	COU0
	IORLW	H'30'
	MOVWF	DAT0
	MOVFW	COU1
	IORLW	H'30'
	MOVWF	DAT1
	MOVFW	COU2
	IORLW	H'30'
	MOVWF	DAT2
	MOVFW	COU3
	IORLW	H'30'
	MOVWF	DAT3
	MOVFW	COU4
	IORLW	H'30'
	MOVWF	DAT4
	MOVFW	COU5
	IORLW	H'30'
	MOVWF	DAT5
	RETURN
SETDN1
	MOVLW	'*'	; *
	MOVWF	DAT5
	MOVLW	'*'	; *
	MOVWF	DAT4
	MOVLW	'*'	; *
	MOVWF	DAT3
	MOVLW	'*'	; *
	MOVWF	DAT2
	MOVLW	'*'	; *
	MOVWF	DAT1
	MOVLW	'*'	; *
	MOVWF	DAT0
	RETURN
;******************************************************************************************
;   Function Name : CNTDEC
;   Title         : 10進(6桁)アップカウンタ
;   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
;
	CLRF	COU3
	MOVLW	H'01'
	ADDWF	COU4,F	; 4桁目10進カウンタ(0aで桁上げ)
	MOVFW	COU4
	XORLW	H'0A'
	BTFSS	STATUS,Z
	RETURN
;
;	CLRF	COU4
;	MOVLW	H'01'
;	ADDWF	COU5,F	; 5桁目10進カウンタ(0aで桁上げ)
;	MOVFW	COU5
;	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	COU4
	CLRF	COU5
	CLRF	OVER
	RETURN
;******************************************************************************************
;   Function Name : DEMO1
;   Title         : デモ
;   Input         : 
;   Output        :
;******************************************************************************************
DEMO1
	MOVLW	' '
	CALL	PSEND
	MOVLW	'C'
	CALL	PSEND
	MOVLW	'o'
	CALL	PSEND
	MOVLW	'n'
	CALL	PSEND
	MOVLW	'n'
	CALL	PSEND
	MOVLW	'e'
	CALL	PSEND
	MOVLW	'c'
	CALL	PSEND
	MOVLW	't'
	CALL	PSEND
	MOVLW	'e'
	CALL	PSEND
	MOVLW	'd'
	CALL	PSEND
	MOVLW	' '
	CALL	PSEND
	MOVLW	'P'
	CALL	PSEND
	MOVLW	'I'
	CALL	PSEND
	MOVLW	'C'
	CALL	PSEND
	MOVLW	'1'
	CALL	PSEND
	MOVLW	'2'
	CALL	PSEND
	MOVLW	'F'
	CALL	PSEND
	MOVLW	'6'
	CALL	PSEND
	MOVLW	'8'
	CALL	PSEND
	MOVLW	'3'
	CALL	PSEND
	MOVLW	' '
	CALL	PSEND
	MOVLW	'O'
	CALL	PSEND
	MOVLW	'K'
	CALL	PSEND
	MOVLW	'>'
	CALL	PSEND
	MOVLW	' '
	CALL	PSEND

	RETURN

;******************************************************************************************
;   Function Name : DATOUT
;   Title         : データを出力
;   Input         : 
;   Output        :
;******************************************************************************************
DATOUT	
; 1.送信開始
;
	MOVLW	' '
	CALL	PSEND
;
;	MOVFW	DAT5
;	CALL	PSEND
;
	MOVFW	DAT4
	CALL	PSEND
;
	MOVFW	DAT3
	CALL	PSEND
;
	MOVFW	DAT2
	CALL	PSEND
;
	MOVFW	DAT1
	CALL	PSEND
;
	MOVFW	DAT0
	CALL	PSEND
;
	MOVLW	'H'
	CALL	PSEND
;
	MOVLW	'z'
	CALL	PSEND
;
	RETURN
;******************************************************************************************
;   Function Name : PSEND
;   Title         : 送信サブルーチン(GPIO,2)
;                   9600BPS OSC;8.000MHz仕様
;   Input         : 
;   Output        :
;******************************************************************************************
PSEND
	MOVWF	IODAT
; (1)送信開始
	BCF	GPIO,2	; 送信開始
	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,2
	BTFSC	STATUS,C ; ビットデータが1の時, 1を立てる
	BSF	GPIO,2

	MOVLW	H'42'	; パルス(9600BPS,OSC;8MHz)
	MOVWF	SENDWAT
PSEND3	DECFSZ	SENDWAT,F
	GOTO	PSEND3

	DECFSZ	SENDLP,F
	GOTO	PSEND2
; (3)終了
	BSF	GPIO,2	; フラグを戻す
; (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 : REC
;   Title         : ＲＳ２３２Ｃ受信サブルーチン(GP1)
;                   9600BPS OSC;8.000MHz仕様
;   Input         : 
;   Output        :
;******************************************************************************************
REC
; (0)変数初期化
	CLRF	IODAT
; (1)受信データを待つ
REC0	BTFSC	GPIO,1
	GOTO	REC0
; (2)1/2ビット分待つ
	MOVLW	H'21'	; 9600BPS OSC;8.000MHz仕様
	MOVWF   RECWAT
REC1	DECFSZ	RECWAT,F
	GOTO	REC1
; (3)データ受信(8ビット分)
	MOVLW	8
	MOVWF	RECLP
	NOP
REC2	MOVLW	H'42'	; 9600BPS OSC;8.000MHz仕様
	MOVWF	RECWAT
REC3	DECFSZ	RECWAT,F
	GOTO	REC3
	NOP
	BTFSS	GPIO,1	; ビットデータが0の時, 0を立てる
	BCF	STATUS,C
	BTFSC	GPIO,1	; ビットデータが1の時, 1を立てる
	BSF	STATUS,C
	RRF	IODAT,F	; 変数内でビットをシフトする
	DECFSZ	RECLP,F
	GOTO	REC2
	NOP
	NOP
;
	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


