;******************************************************************************************
;   Project      :
;   Program Name : 
;   Programer    :
;   Create date  :  Version 1.0    H20.01.06
;   History      :
;   Description  :  
;******************************************************************************************
;   Define I/O
;     GP1:Input RMT-Senser
;     GP4:Serial Comunication Port(TX)
;     GP5:Serial Comunication Port(RX)
;******************************************************************************************
; 1.Define Parameter 
#DEFINE	PI_RDRTIM_NUM	H'01'
#DEFINE	PI_MEMORY_AREA	H'40'
; 2.Condition Code
#DEFINE	PI_NORMAL	H'00'
#DEFINE	PI_FAILER	H'01'
#DEFINE	PI_RDR_ERR	H'10'
#DEFINE	PI_ANL_ERR	H'11'
;
	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
RECWAT	EQU	21H
RECLP	EQU	22H
SENDWAT	EQU	23H
SENDLP	EQU	24H
CNT	EQU	25H
CNT1	EQU	26H
CNT2	EQU	27H
MSGCNT	EQU	28H
TMPCNT	EQU	29H
TMP0	EQU	2AH
TMP1	EQU	2BH
TMP2	EQU	2CH
TMP2B	EQU	2DH
RDRLP0	EQU	2EH
RDRLP1	EQU	2FH
RDRLP2	EQU	30H
DATCNT	EQU	31H
ERRFLG	EQU	32H
HEXDATA EQU	33H
DECCOU0	EQU	34H
DECCOU1	EQU	35H
DECCOU2	EQU	36H
HEXCNT0	EQU	37H
OUTLP	EQU	38H
ANALLP	EQU	39H
DATSEP	EQU	3AH
CNVCHR	EQU	3BH
;
DATAREA	EQU	40H	;これ以降のメモリーは配列として使用しているので使用不可
;
	ORG	0
	GOTO	START
	ORG	4
	GOTO	START
START
	BSF	STATUS,RP0	; BANK1を選択
	BSF	OSCCON,6	; 8MHzを設定
	BSF	OSCCON,5	; 8MHzを設定
	BSF	OSCCON,4	; 8MHzを設定
	NOP
	NOP
	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'101111'	; BANK1でPORT設定
	MOVWF	TRISIO		; BANK1でPORT設定
	BCF	STATUS,RP0	; BANK0を選択
;
; ****************************
;   0.プログラム初期化
; ****************************
	BSF	GPIO,4		; 通信ポート(TX)の初期化
	CALL	DEMO01		; 接続完了メッセージを表示
MAIN
; ****************************
;   1.初期化
; ****************************
	CALL	DEMO02		; 入力要求メッセージを表示

; ****************************
;   2.リモコンの入力を待つ
; ****************************
	BTFSC	GPIO,1
	GOTO	$-1

; ****************************
;   3.データを入力する
; ****************************
	CALL	GETDAT

; ****************************
;   4.データを分析する
; ****************************
	CALL	ANLDAT

; ****************************
;   5.データを出力する
; ****************************
	CALL	DATOUT

	GOTO	MAIN


;******************************************************************************************
;   Function Name : DEMO01
;   Title         : 接続メッセージを表示
;   Input         : 
;   Output        : 
;******************************************************************************************
DEMO01
	MOVLW	H'1B'
	MOVWF	MSGCNT
DEMO1A
	MOVFW	MSGCNT
	CALL	DEMO1TBL
	CALL	SEND
	DECFSZ	MSGCNT,F
	GOTO	DEMO1A
	RETURN
DEMO1TBL
	ADDWF	PCL,F
	RETLW	' '
	RETLW	'>'
	RETLW	'K'
	RETLW	'O'
	RETLW	' '
	RETLW	'3'
	RETLW	'8'
	RETLW	'6'
	RETLW	'F'
	RETLW	'2'
	RETLW	'1'
	RETLW	'C'
	RETLW	'I'
	RETLW	'P'
	RETLW	' '
	RETLW	'd'
	RETLW	'e'
	RETLW	't'
	RETLW	'c'
	RETLW	'e'
	RETLW	'n'
	RETLW	'n'
	RETLW	'o'
	RETLW	'C'
	RETLW	' '
	RETLW	' '
	RETLW	' '
	RETLW	' '

;******************************************************************************************
;   Function Name : DEMO02
;   Title         : 入力待ちメッセージを表示
;   Input         : 
;   Output        : 
;******************************************************************************************
DEMO02
	MOVLW	' '
	CALL	SEND
	MOVLW	'P'
	CALL	SEND
	MOVLW	'u'
	CALL	SEND
	MOVLW	's'
	CALL	SEND
	MOVLW	'h'
	CALL	SEND
	MOVLW	' '
	CALL	SEND
	MOVLW	'A'
	CALL	SEND
	MOVLW	'n'
	CALL	SEND
	MOVLW	'y'
	CALL	SEND
	MOVLW	' '
	CALL	SEND
	MOVLW	'K'
	CALL	SEND
	MOVLW	'E'
	CALL	SEND
	MOVLW	'Y'
	CALL	SEND
	MOVLW	'!'
	CALL	SEND

	RETURN
;******************************************************************************************
;   Function Name : GETDAT
;   Title         : データを入力する
;   Input         : 
;   Output        : 
;******************************************************************************************
GETDAT
; ****************************
;   1.初期化
; ****************************
;  (0)メモリの初期化
	MOVLW	PI_MEMORY_AREA
	MOVWF	FSR
;  (1)初期化
	CLRF	DATCNT
	CLRF	ERRFLG
;  (2)ヘッダーを読み飛ばす
	BTFSS	GPIO,1
	GOTO	$-1
	BTFSC	GPIO,1
	GOTO	$-1
;
; ****************************
;   2.データを入力する
; ****************************
;  (1)データを待つ
GETDAT2
;   a)データを待つ
GETDAT2A
	BTFSS	GPIO,1
	GOTO	$-1
; (2)データを読む
GETDAT3
;   a)初期化
	CLRF	TMPCNT	
;   b)データを読む
GETDAT3A
	BTFSS	GPIO,1
	GOTO	GETDAT4
	MOVFW	TMPCNT
	XORLW	H'FF'
	BTFSC	STATUS,Z
	GOTO	GETDAT9
	MOVLW	H'01'
	ADDWF	TMPCNT,F
	CALL	RDRWAT
	GOTO	GETDAT3A
;
; (3)データを代入する
GETDAT4
;   a)データをメモリーに代入
	MOVFW	TMPCNT
	MOVWF	INDF
	INCF	FSR,F
;   b)データ数をカウントする
	MOVLW	H'01'
	ADDWF	DATCNT,F
	GOTO	GETDAT2

; ****************************
;   9.データ入力の完了
; ****************************
GETDAT9
	RETURN


;******************************************************************************************
;   Function Name : ANLDAT
;   Title         : データを分析する
;   Input         : 
;   Output        : 
;   Description   : 
;******************************************************************************************
ANLDAT

	CLRF	DATSEP
;
;   1.メモリーの先頭アドレスをFSRレジスタに設定
;
	MOVLW	PI_MEMORY_AREA
	MOVWF	FSR
;
;   2.INDFレジスタからデータを取り出す
;
;    (1)比較基準データの２倍、1/2倍をセット
;
	MOVFW	INDF
;
	MOVWF	TMP1
	MOVWF	TMP2
;
	RRF	TMP1,F	;1/2
	RLF	TMP2,F	;*2
;
;    (2)データ分析
;
	MOVFW	DATCNT
	MOVWF	ANALLP
	DECF	ANALLP,F
	INCF	FSR,F
ANLDAT1
;
;   (1)条件1(TMP2 < Data)の場合
	MOVFW	INDF
	MOVWF	TMP0
	MOVFW	TMP2
	MOVWF	TMP2B
;
	MOVFW	TMP0	; 
	SUBWF	TMP2B,F
	BTFSC	STATUS,C
	GOTO	ANLDAT2
;
	MOVFW	TMP2
	MOVWF	DATSEP
	RETURN
ANLDAT2
;
;   (1)条件2(Data < TMP1)の場合
	MOVFW	INDF
	MOVWF	TMP0
;
	MOVFW	TMP1
	SUBWF	TMP0,F
	BTFSC	STATUS,C
	GOTO	ANLDAT3
;
	MOVFW	TMP1
	MOVWF	DATSEP
	RETURN
;
ANLDAT3
;
	INCF	FSR,F
	DECFSZ	ANALLP,F
	GOTO	ANLDAT1 

	MOVLW	PI_ANL_ERR
	MOVWF	ERRFLG

	RETURN

;******************************************************************************************
;   Function Name : RDRWAT
;   Title         : 読み込みタイマー
;   Input         : 
;   Output        : 
;   Description   : 8/4MHz ==(100)==> 20KHz
;******************************************************************************************
RDRWAT
	MOVLW	PI_RDRTIM_NUM
	MOVWF	RDRLP1
RDRWAT1
	MOVLW	H'0A'
	MOVWF	RDRLP0
RDRWAT0
	NOP
	NOP
	NOP
	NOP
	NOP
	NOP
	NOP
	DECFSZ	RDRLP0,F
	GOTO	RDRWAT0 
	DECFSZ	RDRLP1,F
	GOTO	RDRWAT1 

	RETURN


;******************************************************************************************
;   Function Name : DATOUT
;   Title         : 結果を出力する
;   Input         : 
;   Output        : 
;******************************************************************************************
DATOUT
; ****************************
;   0.エラーの場合を出力する
; ****************************
	CLRF	ERRFLG
	MOVFW	ERRFLG
	XORLW	H'00'
	BTFSC	STATUS,Z
	GOTO	DATOUT2
;
	MOVLW	' '
	CALL	SEND
	MOVLW	'['
	CALL	SEND
	MOVLW	'E'
	CALL	SEND
	MOVLW	'R'
	CALL	SEND
	MOVLW	'R'
	CALL	SEND
	MOVLW	'O'
	CALL	SEND
	MOVLW	'R'
	CALL	SEND
	MOVLW	'-'
	CALL	SEND
	MOVFW	ERRFLG
	CALL	PRTDEC
	MOVLW	']'
	CALL	SEND
	RETURN

; ****************************
;   1.ヘッダーを出力する
; ****************************
DATOUT2
;
;   (1)データ数を表示する
;
;	CALL	DEBNUM0
;
;   (2)読み込んだデータを表示(デバッグ用)
;
;	CALL	DEBNUM1
;
;   (3)セパレータの値を表示(デバッグ用)
;
;	CALL	DEBNUM2
;
;   (4)データを表示('1'/'0'表示用)
;
	CALL	DEBNUM3
;
;   (5)データを表示(１６進キャラクタ表示用)
;
;	CALL	DEBNUM4
;
	RETURN

;******************************************************************************************
;   Function Name : DEBNUM0
;   Title         : デバッガ(データ数を表示する)
;   Input         : 
;   Output        : 
;******************************************************************************************
DEBNUM0
	MOVLW	' '
	CALL	SEND
	MOVLW	'D'
	CALL	SEND
	MOVLW	'a'
	CALL	SEND
	MOVLW	't'
	CALL	SEND
	MOVLW	'a'
	CALL	SEND
	MOVLW	':'
	CALL	SEND
;
	MOVFW	DATCNT
	CALL	PRTDEC
	MOVLW	' '
	CALL	SEND

	RETURN
;******************************************************************************************
;   Function Name : DEBNUM1
;   Title         : デバッガ(読み込んだデータを表示する)
;   Input         : 
;   Output        : 
;******************************************************************************************
DEBNUM1
;
;   1.メモリーの先頭アドレスをFSRレジスタに設定
;
	MOVLW	PI_MEMORY_AREA
	MOVWF	FSR
;
;   2.INDFレジスタからデータを取り出して表示する
;
	MOVFW	DATCNT
	MOVWF	OUTLP
DEBNUM1A
	MOVLW	'['
	CALL	SEND
	MOVFW	INDF
	CALL	PRTDEC
	INCF	FSR,F
	MOVLW	']'
	CALL	SEND
	DECFSZ	OUTLP,F
	GOTO	DEBNUM1A 

	RETURN


;******************************************************************************************
;   Function Name : DEBNUM2
;   Title         : デバッガ(セパレータを表示する)
;   Input         : 
;   Output        : 
;******************************************************************************************
DEBNUM2
	MOVLW	'['
	CALL	SEND
	MOVLW	'S'
	CALL	SEND
	MOVLW	'e'
	CALL	SEND
	MOVLW	'p'
	CALL	SEND
	MOVLW	':'
	CALL	SEND
	MOVFW	DATSEP
	CALL	PRTDEC
	INCF	FSR,F
	MOVLW	']'
	CALL	SEND

	RETURN


;******************************************************************************************
;   Function Name : DEBNUM3
;   Title         : デバッガ('1'/'0'表示用)
;   Input         : 
;   Output        : 
;******************************************************************************************
DEBNUM3
;
;   1.メモリーの先頭アドレスをFSRレジスタに設定
;
	MOVLW	PI_MEMORY_AREA
	MOVWF	FSR
;
;   2.INDFレジスタからデータを取り出して表示する
;
	MOVLW	'['
	CALL	SEND
;
	MOVFW	DATCNT
	MOVWF	OUTLP
DEBNUM3A
	MOVFW	INDF
	MOVWF	TMP0
;
	MOVFW	DATSEP
	SUBWF	TMP0,F
	BTFSC	STATUS,C
	GOTO	DEBNUM3B
;
	MOVLW	'0'
	CALL	SEND
	GOTO	DEBNUM3C
DEBNUM3B
	MOVLW	'1'
	CALL	SEND
DEBNUM3C
	INCF	FSR,F
	DECFSZ	OUTLP,F
	GOTO	DEBNUM3A 
;
	MOVLW	']'
	CALL	SEND
;
	RETURN



;******************************************************************************************
;   Function Name : DEBNUM4
;   Title         : デバッガ(１６進キャラクタ表示用)
;   Input         : 
;   Output        : 
;   Description   :
;        TMP0: Input Data
;        TMP1: Output Data
;        TMP2: Data Number
;******************************************************************************************
DEBNUM4
; =====================================================　
;   1.メモリーの先頭アドレスをFSRレジスタに設定
; =====================================================
	MOVLW	PI_MEMORY_AREA
	MOVWF	FSR

; =====================================================
;   2.INDFレジスタからデータを取り出して表示する
; =====================================================
;   (1)ヘッダーを表示する
	MOVLW	'['
	CALL	SEND
;
;   (2)データを表示する
;
	CLRF	TMP1
	CLRF	TMP2
;
	MOVFW	DATCNT
	MOVWF	OUTLP
DEBNUM4A
;    2-1)データが、1か0かを判定する
	MOVFW	INDF
	MOVWF	TMP0
;
	MOVFW	DATSEP
	SUBWF	TMP0,F
	BTFSC	STATUS,C
	GOTO	DEBNUM4B
;    2-1-a)Data=0の時
	BCF	TMP1,0	
	GOTO	DEBNUM4C
;    2-1-b)Data=1の時
DEBNUM4B
	BSF	TMP1,0
;    2-2)4ビット設定されているか判断
DEBNUM4C
	MOVFW	TMP2
	XORLW	H'03'
	BTFSS	STATUS,Z
	GOTO	DEBNUM4D
;    2-2-a)4ビット目の時の処理
;    2-2-a-0)ビット数を初期化
	CLRF	TMP2
;    2-2-a-1)キャラクタに変換
	MOVFW	TMP1
	CALL	CNVCHAR
;    2-2-a-3)データを表示
	CALL	SEND
;    2-2-a-4)表示データを初期化
	CLRF	TMP1
	GOTO	DEBNUM4E 	
;
;    2-2-b)4ビット目でない時の処理
DEBNUM4D
	RLF	TMP1,F
	MOVLW	H'01'
	ADDWF	TMP2,F
	GOTO	DEBNUM4E

;    2-3)次のデータを設定
DEBNUM4E
	INCF	FSR,F
	DECFSZ	OUTLP,F
	GOTO	DEBNUM4A 
;
;   (3)ラストのデータを表示する
	MOVFW	TMP2
	XORLW	H'03'
	BTFSS	STATUS,Z
	GOTO	DEBNUM4P
;
;    2-2-a-1)キャラクタに変換
	MOVFW	TMP1
	CALL	CNVCHAR
;    2-2-a-3)データを表示
	CALL	SEND
;
DEBNUM4P
;   (4)トレーダを表示する
	MOVLW	']'
	CALL	SEND
;
	RETURN

;******************************************************************************************
;   Function Name : CNVCHAR
;   Title         : ４ビット数字を１６進文字に変換
;   Input         : W-reg
;   Output        : 
;******************************************************************************************
CNVCHAR
	MOVWF	CNVCHR

;  1.文字型に変換
	MOVLW	B'00110000'
	IORWF	CNVCHR,F

;  2.0Aを補正
	MOVFW	CNVCHR
	XORLW	H'3A'
	BTFSC	STATUS,Z
	RETLW	'A'

;  3.0Bを補正
	MOVFW	CNVCHR
	XORLW	H'3B'
	BTFSC	STATUS,Z
	RETLW	'B'

;  4.0Cを補正
	MOVFW	CNVCHR
	XORLW	H'3C'
	BTFSC	STATUS,Z
	RETLW	'C'

;  5.0Dを補正
	MOVFW	CNVCHR
	XORLW	H'3D'
	BTFSC	STATUS,Z
	RETLW	'D'
;

;  6.0Eを補正
	MOVFW	CNVCHR
	XORLW	H'3E'
	BTFSC	STATUS,Z
	RETLW	'E'

;  7.0Fを補正
	MOVFW	CNVCHR
	XORLW	H'3F'
	BTFSC	STATUS,Z
	RETLW	'F'

;  8.補正なし
	MOVFW	CNVCHR

	RETURN
	
;******************************************************************************************
;   Function Name : PRTDEC
;   Title         : 10進キャラクタをシリアルで表示する
;   Input         : W-reg
;   Output        : 
;******************************************************************************************
PRTDEC
	MOVWF	HEXDATA
	CALL	HEXDEC
;
	MOVFW	DECCOU2
	CALL	SEND
	MOVFW	DECCOU1
	CALL	SEND
	MOVFW	DECCOU0
	CALL	SEND
;
	RETURN

;******************************************************************************************
;   Function Name : HEXDEC
;   Title         : 数字(16進数)->文字変換(10進数)
;   Input         : HEXDATA
;   Output        : DECCOU2,DECCOU1,DECCOU0
;******************************************************************************************
; (1)16進数を10進数に変換する
HEXDEC
	CLRF	DECCOU0
	CLRF	DECCOU1
	CLRF	DECCOU2
;
	MOVFW	HEXDATA
	XORLW	H'00'
	BTFSC	STATUS,Z
	GOTO	HEXFMT

	MOVFW	HEXDATA
	MOVWF	HEXCNT0
HEXDEE1
	CALL	CNTDEC
	DECFSZ	HEXCNT0,F
	GOTO	HEXDEE1 

HEXFMT
; (2)10進数を文字に変換する
	MOVLW	B'00110000'
	IORWF	DECCOU0,F

	MOVLW	B'00110000'
	IORWF	DECCOU1,F

	MOVLW	B'00110000'
	IORWF	DECCOU2,F

	RETURN

;******************************************************************************************
;   Function Name : CNTDEC
;   Title         : 10進カウンタ
;   Input         : 
;   Output        : 
;******************************************************************************************
CNTDEC
	MOVLW	H'01'
	ADDWF	DECCOU0,F	; 1桁目（１分）は10進カウンタ(0aで桁上げ)
	MOVFW	DECCOU0
	XORLW	H'0A'
	BTFSS	STATUS,Z
	RETURN
;
	CLRF	DECCOU0
	MOVLW	H'01'
	ADDWF	DECCOU1,F	; 2桁目10進カウンタ(0aで桁上げ)
	MOVFW	DECCOU1
	XORLW	H'0A'
	BTFSS	STATUS,Z
	RETURN
;
	CLRF	DECCOU1
	MOVLW	H'01'
	ADDWF	DECCOU2,F	; 3桁目10進カウンタ(0aで桁上げ)
	MOVFW	DECCOU2
	XORLW	H'0A'
	BTFSS	STATUS,Z
	RETURN
;
	CLRF	DECCOU2

	RETURN


;******************************************************************************************
;   Function Name : REC
;   Title         : ＲＳ２３２Ｃ受信サブルーチン(GPIO,5)
;                   9600BPS OSC;8.000MHz仕様
;   Input         : 
;   Output        : W-register
;******************************************************************************************
REC
; (0)変数初期化
	CLRF	IODAT
; (1)受信データを待つ
	BTFSC	GPIO,5
	GOTO	REC
; (2)1/2ビット分待つ
	MOVLW	H'21'	; 9600BPS,OSC;8MHz
	MOVWF   RECWAT
REC1	DECFSZ	RECWAT,F
	GOTO	REC1
; (3)データ受信(8ビット分)
	MOVLW	8
	MOVWF	RECLP
	NOP
REC2	MOVLW	H'42'	; 9600BPS,OSC;8MHz
	MOVWF	RECWAT
REC3	DECFSZ	RECWAT,F
	GOTO	REC3
	NOP
	BTFSS	GPIO,5	; ビットデータが0の時, 0を立てる
	BCF	STATUS,C
	BTFSC	GPIO,5	; ビットデータが1の時, 1を立てる
	BSF	STATUS,C
	RRF	IODAT,F	; 変数内でビットをシフトする
	DECFSZ	RECLP,F
	GOTO	REC2
	NOP
	NOP
	MOVFW	IODAT
;
	RETURN

;******************************************************************************************
;   Function Name : SEND
;   Title         : ＲＳ２３２Ｃ送信サブルーチン(GPIO,4)
;                   9600BPS OSC;8.000MHz仕様
;   Input         : W-register
;   Output        :
;******************************************************************************************
; (1)送信開始
SEND	
	MOVWF	IODAT
	BCF	GPIO,4	; 送信開始
	MOVLW	H'42'	; 9600BPS,OSC;8MHz
	MOVWF	SENDWAT
SEND1	DECFSZ	SENDWAT,F
	GOTO	SEND1
;
; (2)データ送信(8ビット)
	MOVLW	8	; 8ビットデータ分、送信する
	MOVWF	SENDLP
	NOP
SEND2	RRF	IODAT,F
	NOP
	BTFSS	STATUS,C ; ビットデータが0の時, 0を立てる	
	BCF	GPIO,4
	BTFSC	STATUS,C ; ビットデータが1の時, 1を立てる
	BSF	GPIO,4

	MOVLW	H'42'	; パルス(9600BPS,OSC;8MHz)
	MOVWF	SENDWAT
SEND3	DECFSZ	SENDWAT,F
	GOTO	SEND3

	DECFSZ	SENDLP,F
	GOTO	SEND2
; (3)終了
	BSF	GPIO,4	; フラグを戻す
; (4)送信後、少し待つ
	CALL	TIMER

	RETURN


;******************************************************************************************
;   Function Name : TIMER
;   Title         : タイマー(1000回ループ)
;   Input         : 
;   Output        :
;******************************************************************************************
TIMER
	MOVLW	H'0A'
	MOVWF	CNT1
TIMER1
	MOVLW	H'64'
	MOVWF	CNT
TIMER2
	DECFSZ	CNT,F
	GOTO	TIMER2 
	DECFSZ	CNT1,F
	GOTO	TIMER1

	RETURN




	END
