;******************************************************************************************
;  ADコンバータサンプル
;   Program Name : 
;   Programer    :
;   Create date  :  Version 1.0    H17.07.08
;   History      :
;******************************************************************************************
;    サンプルボード仕様
;      GP0:Input AD(0)
;      GP1:Input AD(1)　
;      GP2:Input AD(2)
;      GP3:RS232C
;      GP4:Input AD(3)
;      GP5:RS232C
;====================== 以下はPIC12F683用の記述 ======================
	LIST	P=PIC12F683,ST=OFF,R=DEC
	INCLUDE	"P12F683.inc"	;標準ヘッダ定義ファイル
	__CONFIG _MCLRE_OFF & _INTRC_OSC_NOCLKOUT & _WDT_OFF
IODAT	EQU	20H
SENDLP	EQU	21H
SENDWAT	EQU	22H
CNT	EQU	23H
CNT1	EQU	24H
CNT2	EQU	25H
CNT3	EQU	26H
CNT4	EQU	27H
CNT5	EQU	28H
INBIN	EQU	29H
OUTCHR1	EQU	2AH
OUTCHR2	EQU	2BH
ADANSL	EQU	2CH
ADANSR	EQU	2DH
DADANSL	EQU	2EH
DADANSR	EQU	2FH
DECTMP	EQU	30H
POTNO	EQU	31H
DECCOU0	EQU	32H
DECCOU1	EQU	33H
DECCOU2	EQU	34H
DECCOU3	EQU	35H
WAT1	EQU	36H
WAT2	EQU	37H

	ORG	0
	GOTO	START
	ORG	4
	GOTO	START
START
	BCF	STATUS,RP0	; BANK0を指定
	CLRF	GPIO		; ポートを初期化
	BSF	GPIO,5		; シリアル通信ポートを初期化
	BSF	STATUS,RP0	; BANK1を指定
	MOVLW	B'00011111'	; Bit7:0, Bit6-4:ADC Clock, Bit3-0:Select Degital or Analog
	MOVWF	ANSEL		; Bit3-0:全てアナログ,Bit6-4:1/8（中ぐらいの速さ）を指定
	MOVLW	B'011111'	; GP5以外は全て入力に設定
	MOVWF	TRISIO		; BANK1でPORT設定
	BCF	STATUS,RP0	; BANK0を指定
	MOVLW	B'10000001'	; GP7:Fmt, GP6:VRef, GP5,4:None, GP3,2:Sel Bit, GP1:Start, GP0:ADC On 
	MOVWF	ADCON0		; 結果を右詰,基準は電源電圧,Port 0指定,測定準備,ADC ONを指定
	CALL	ADCTM		; 
;=====================================================================
MAIN
;  1.ポート0番のデータ収集
	MOVLW	'0'
	MOVWF	POTNO
	BCF	STATUS,RP0	; BANK0を指定
	BCF	ADCON0,3	; ADN0を選択
	BCF	ADCON0,2	; ADN0を選択
	CALL	ADMAIN

;  1.ポート1番のデータ収集
	MOVLW	'1'
	MOVWF	POTNO
	BCF	STATUS,RP0	; BANK0を指定
	BCF	ADCON0,3	; ADN1を選択
	BSF	ADCON0,2	; ADN1を選択
	CALL	ADMAIN

;  1.ポート2番のデータ収集
	MOVLW	'2'
	MOVWF	POTNO
	BCF	STATUS,RP0	; BANK0を指定
	BSF	ADCON0,3	; ADN2を選択
	BCF	ADCON0,2	; ADN2を選択
	CALL	ADMAIN

;  1.ポート4番のデータ収集
	MOVLW	'4'
	MOVWF	POTNO
	BCF	STATUS,RP0	; BANK0を指定
	BSF	ADCON0,3	; ADN4を選択
	BSF	ADCON0,2	; ADN4を選択
	CALL	ADMAIN

	CALL	SAMPTM
	GOTO	MAIN

;******************************************************************************************
;   Function Name : ADMAIN
;   Disctiption   : ADCからのデータ収集・出力関数
;   Input         : 事前にADCON0でポート番号を指定しておく
;                   POTNO:ポート番号(パソコンに書き出す時の見出しで使用する)
;   Output        : なし
;******************************************************************************************
ADMAIN
; 1.ADN(0)からデータ収集
;   (1)データ収集 
	CALL	GETADC

;   (2)データを補正する
	CALL	HEXDEC

;   (3)キャラクターコードに変換してパソコンに送信する
;    3-0)見出しを出力
	MOVLW	' '
	MOVWF	IODAT
	CALL	SEND
	CALL	WAT
;
	MOVLW	'P'
	MOVWF	IODAT
	CALL	SEND
	CALL	WAT
;
	MOVFW	POTNO
	MOVWF	IODAT
	CALL	SEND
	CALL	WAT
;
	MOVLW	')'
	MOVWF	IODAT
	CALL	SEND
	CALL	WAT

;    3-1)上位2ビットを出力
;     a)数字型キャラクターコードに変換する
	MOVFW	DADANSL
	MOVWF	INBIN
	CALL	CNVCHR	
;     b)RS232Cでデータ送信する
	MOVFW	OUTCHR1
	MOVWF	IODAT
	CALL	SEND
	CALL	WAT

;     c)RS232Cでデータ送信する
	MOVFW	OUTCHR2
	MOVWF	IODAT
	CALL	SEND
	CALL	WAT

;    3-2)下位8ビットを出力
;     a)数字型キャラクターコードに変換する
	MOVFW	DADANSR
	MOVWF	INBIN
	CALL	CNVCHR	
;     b)RS232Cでデータ送信する
	MOVFW	OUTCHR1
	MOVWF	IODAT
	CALL	SEND
	CALL	WAT

;     c)RS232Cでデータ送信する
	MOVFW	OUTCHR2
	MOVWF	IODAT
	CALL	SEND
	CALL	WAT

	RETURN

;******************************************************************************************
;   Function Name : HEXDEC
;   Disctiption   : 16進数 => 10進数変換関数
;   Input         :  ADANSL,   ADANSR
;   Output        : DADANSL,  DADANSR
;******************************************************************************************
; (1)16進数を10進数に変換する
HEXDEC
	CLRF	DECCOU0
	CLRF	DECCOU1
	CLRF	DECCOU2
	CLRF	DECCOU3
	MOVFW	ADANSL
	XORLW	H'00'
	BTFSC	STATUS,Z
	GOTO	HEXDEE
;
	MOVFW	ADANSL
	MOVWF	CNT2
HEXDEC2
	MOVLW	H'FF'
	MOVWF	CNT1
	CALL	CNTDEC
HEXDEC1
	CALL	CNTDEC
	DECFSZ	CNT1,F
	GOTO	HEXDEC1 
	DECFSZ	CNT2,F
	GOTO	HEXDEC2
;
HEXDEE
	MOVFW	ADANSR
	XORLW	H'00'
	BTFSC	STATUS,Z
	GOTO	HEXFMT

	MOVFW	ADANSR
	MOVWF	CNT1
HEXDEE1
	CALL	CNTDEC
	DECFSZ	CNT1,F
	GOTO	HEXDEE1 

; (2)フォーマット変換する
;  a)左変数
HEXFMT
	MOVFW	DECCOU2
	MOVWF	DADANSL
	MOVLW	H'04'
	MOVWF	CNT1
HEXFMT1
	RLF	DECCOU3,F
	DECFSZ	CNT1,F
	GOTO	HEXFMT1 
	MOVFW	DECCOU3
	ANDLW	B'11110000'
	IORWF	DADANSL,F
;  b)右変数
	MOVFW	DECCOU0
	MOVWF	DADANSR
	MOVLW	H'04'
	MOVWF	CNT1
HEXFMT2
	RLF	DECCOU1,F
	DECFSZ	CNT1,F
	GOTO	HEXFMT2 
	MOVFW	DECCOU1
	ANDLW	B'11110000'
	IORWF	DADANSR,F

	RETURN

;******************************************************************************************
;   Function Name : CNTDEC
;   Disctiption   : 10進カウンタ
;   Input         : 
;   Output        : 
;******************************************************************************************
CNTDEC
	MOVLW	H'01'
	ADDWF	DECCOU0,F	; 1桁目（１分）は10進カウンタ(0aで桁上げ)
	MOVFW	DECCOU0
	XORLW	H'0A'
	BTFSS	STATUS,Z
	RETLW	0
;
	CLRF	DECCOU0
	MOVLW	H'01'
	ADDWF	DECCOU1,F	; 2桁目10進カウンタ(0aで桁上げ)
	MOVFW	DECCOU1
	XORLW	H'0A'
	BTFSS	STATUS,Z
	RETLW	0
;
	CLRF	DECCOU1
	MOVLW	H'01'
	ADDWF	DECCOU2,F	; 3桁目10進カウンタ(0aで桁上げ)
	MOVFW	DECCOU2
	XORLW	H'0A'
	BTFSS	STATUS,Z
	RETLW	0
;
	CLRF	DECCOU2
	MOVLW	H'01'
	ADDWF	DECCOU3,F	; 4桁目10進カウンタ(0aで桁上げ)
	MOVFW	DECCOU3
	XORLW	H'0A'
	BTFSS	STATUS,Z
	RETLW	0
;
	CLRF	DECCOU3

	RETURN

;******************************************************************************************
;   Function Name : GETADC
;   Disctiption   : ADCからのデータ収集関数
;   Input         : 事前にADCON0でポート番号を指定しておく
;   Output        : ADANSL   :  上位２ビット
;                   ADANSR   :  下位８ビット
;******************************************************************************************
GETADC
	BCF	STATUS,RP0	; BANK0を指定
	BSF	ADCON0,GO	; ADCの開始フラグを立てる
	BTFSC	ADCON0,GO	; ADCの開始フラグが完了するまで待つ
	GOTO	$-1		; ADCの開始フラグが完了するまで待つ
	MOVFW	ADRESH		; 上位２ビットデータ収集
	MOVWF	ADANSL		; 上位２ビットデータ代入
        BSF	STATUS,RP0	; BANK1を指定
	MOVFW	ADRESL		; 下位８ビットデータ収集
	BCF	STATUS,RP0	; BANK0を指定
	MOVWF	ADANSR		; 下位８ビットデータ代入

	RETURN

;******************************************************************************************
;   Function Name : CNVCHR
;   Disctiption   : キャラクターコード(数字型)へ変換
;   Input         : 
;   Output        : OUTCHR1  :  上位４ビット
;                   OUTCHR2  :  下位４ビット
;******************************************************************************************
CNVCHR
; 1.上位ビット設定
	MOVFW	INBIN
	MOVWF	OUTCHR1
	MOVLW	H'04'
	MOVWF	CNT
CNVCHR1
	RRF	OUTCHR1,F
	DECFSZ	CNT,F
	GOTO	CNVCHR1
	MOVFW	OUTCHR1
	ANDLW	B'00001111'
	IORLW	B'00110000'
	MOVWF	OUTCHR1

;２．下位ビット設定
	MOVFW	INBIN
	ANDLW	B'00001111'
	IORLW	B'00110000'
	MOVWF	OUTCHR2
	RETURN

;******************************************************************************************
;   Function Name : ADCTM
;   Disctiption   : TIMER関数(サンプル収集間隔の設定タイマー)
;   Input         : 
;   Output        : 
;******************************************************************************************
ADCTM
	MOVLW	H'FF'
	MOVWF	CNT1
ADCTM1
	MOVLW	H'3F'
	MOVWF	CNT
ADCTM2
	DECFSZ	CNT,F
	GOTO	ADCTM2 
	DECFSZ	CNT1,F
	GOTO	ADCTM1
	RETURN

;******************************************************************************************
;   Function Name : SAMPTM
;   Disctiption   : サンプル収集間隔の設定タイマー
;   Input         : 
;   Output        :
;******************************************************************************************
SAMPTM
	MOVLW	H'2'
	MOVWF	CNT4
SAMPT4				; 1Hz/2で0.5Hz(2秒) 
	MOVLW	H'64'
	MOVWF	CNT3
SAMPT3				; 400STEP*100(回)*100(回)+50000(Step)+1000で100Hz => 1Hz
	MOVLW	H'64'
	MOVWF	CNT2
SAMPT2				; 400STEP*100(回)+500(Step)で10KHz => 100Hz
	MOVLW	H'64'
	MOVWF	CNT1
SAMPT1				; 400STEP:100(回)*4(Step)で4MHz => 10KHz	
	NOP
	NOP
	DECFSZ	CNT1,F
	GOTO	SAMPT1 
	DECFSZ	CNT2,F
	GOTO	SAMPT2
	DECFSZ	CNT3,F
	GOTO	SAMPT3
	DECFSZ	CNT4,F
	GOTO	SAMPT4
	RETURN

;******************************************************************************************
;   Function Name : WAT
;   Disctiption   : タイマー
;   Input         : 
;   Output        :
;******************************************************************************************
WAT
	MOVLW	H'0A'
	MOVWF	WAT2
WATB
	MOVLW	H'64'
	MOVWF	WAT1
WATA
	DECFSZ	WAT1,F
	GOTO	WATA
	DECFSZ	WAT2,F
	GOTO	WATB
	RETURN

;******************************************************************************************
;   Function Name : SEND
;   Disctiption   : ＲＳ２３２Ｃ送信サブルーチン(GPIO,5)
;   Input         : 
;   Output        :
;******************************************************************************************
; (1)送信開始
SEND	BCF	GPIO,5	; 送信開始
	MOVLW	H'1F'
	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,5
	BTFSC	STATUS,C ; ビットデータが1の時, 1を立てる
	BSF	GPIO,5

	MOVLW	H'1F'	; パルス(9600BPS)
	MOVWF	SENDWAT
SEND3	DECFSZ	SENDWAT,F
	GOTO	SEND3

	DECFSZ	SENDLP,F
	GOTO	SEND2
; (3)終了
	BSF	GPIO,5	; フラグを戻す
	RETURN
;
	END
