; 16F88_OscilloScope.asm

; RA7 RSW 1-1	input			RB7 RSW 2-1	input
; RA6 RSW 1-2	input			RB6 RSW 2-2	input
; RA5 MCLR	input			RB5 TX		output
; RA4 RSW 1-3	input			RB4 RSW 2-3	input
; RA3 RSW 1-3	input			RB3 RSW 2-4	input
; RA2 LED	output			RB2 RX		input
; RA1 AN1	analogVolt CH1(0-127)	RB1 not use	output
; RA0 AN0	analogVolt CH2(0-127)	RB0 Calibrator	output
; TRISA		b'11111011'		TRISB		b'11011100'

; 電圧セレクタ 入力電圧   送信コマンド
;   RSW1(2)-1   ±0.5V   　0B1H  0C1H
;   RSW1(2)-2   ±2.5V     0B2H  0C2H
;   RSW1(2)-3   ±5V    　 0B3H  0C3H
;   RSW1(2)-4   ±10V  　  0B4H  0C4H
;   RSW1(2)-OFF ±25V  　  0B5H  0C5H
;   ストレージ継続コマンド 0D1H


; 受信コマンド	測定開始     41H(A)
;		測定停止     42H(B)
;		電圧レンジ   43H(C)
;		ストレージ   44H(D)

	list		p=PIC16F88
	#include	<P16F88.INC>

;Program Configuration Register 1
	__CONFIG	_CONFIG1, _CP_OFF & _CCP1_RB0 & _DEBUG_OFF & _WRT_PROTECT_OFF & _CPD_OFF & _LVP_OFF & _BODEN_OFF & _MCLR_ON & _PWRTE_ON & _WDT_OFF & _INTRC_IO

;Program Configuration Register 2
	__CONFIG	_CONFIG2, _IESO_OFF & _FCMEN_OFF

	CBLOCK	20H
	MEASURE			; 受信コマンド
	PORT_AB
	CH1			; AN0 電圧レンジ
	CH1_Buff
	CH2			; AN1 電圧レンジ
	CH2_Buff
	ADBUF1			; AN0 AD変換値
	ADBUF2			; AN1 AD変換値
	CNT1
	CNT2
	CNT3
	w_temp
	status_temp
	pclath_temp
	ENDC

#define	LED_out		PORTA,2			;LED出力
#define Sel_Bank0	bcf     STATUS,RP0
#define Sel_Bank1	bsf     STATUS,RP0

	org	0
	Sel_Bank1
	movlw	b'01110000'
	movwf	OSCCON		; 8MHz
	goto	START

	org	4
	movwf   w_temp		; save W
	movf	STATUS,W
	movwf	status_temp	; save STATUS
	movf	PCLATH,W
	movwf	pclath_temp	; save PCLATH

; isr code can go here or be located as a call subroutine elsewhere

	movf	pclath_temp,W
	movwf	PCLATH		; restore PCLATH
	movf	status_temp,W
	movwf	STATUS		; restore STATUS
	swapf	w_temp,F
	swapf	w_temp,W	; restore W
	retfie

START	movlw	b'11111011
	movwf	TRISA		; RA2 output
	movlw	b'01111111'	; pullup on
	movwf	OPTION_REG
	movlw	b'11011100'	; RB5 RB1 RB0 output
	movwf	TRISB
	movlw	b'00000011'	; AN1 AN0
	movwf	ANSEL
	movlw	b'01000000'	; 左詰め Fosc/2 Vdd Vss
	movwf	ADCON1
	movlw	d'249'		; 周期=(249+1)*4Tosc*16(TMR2のプリスケール値)
	movwf	PR2		;  2000usec(500Hz)
	Sel_Bank0
	movlw	b'01000000'	; Fosc/(8*(ADSC2=1))=Fosc/16 Turn off AD
	movwf	ADCON0
	movlw	3CH		; PWMモード設定
	movwf	CCP1CON
	Sel_Bank1
	movlw	b'00100100'	; 許可 非同期 高速
	movwf	TXSTA
	movlw	d'24'		; 8MHz 24 at 20000bps
	movwf	SPBRG		; サンプリングタイムを1msecにするため
	Sel_Bank0
	movlw	b'10010000'	; シリアル 連続
	movwf	RCSTA
	movlw	d'125'		; Duty 50%
	movwf	CCPR1L
	movlw	b'00000111'	; TIMER2 on prescale=16
	movwf	T2CON		; TIMER2スタート
	call	LED1ON		; LED 1secon
	clrf	MEASURE		; 停止中
	clrf	CH1
	clrf	CH2
Main	btfsc	PIR1,RCIF	; USART 受信割り込みフラグビットチェック
	goto	Chk_RX
	movlw	41H
	subwf	MEASURE,W
	btfss	STATUS,Z	; 測定中チェック
	goto	CHK_RSW
	call	AD_CONV
	movf	ADBUF1,W
	call	TXD
	movlw	b'00000100'
	xorwf	PORTA,F		; LED on or off
	movf	ADBUF2,W
	call	TXD

CHK_RSW	call	RSWIN		; RSW入力
	goto	Main

Chk_RX	btfsc	RCSTA,FERR	; フレーミングエラーのチェック（1:エラー,0:正常）
	goto	FRAME
	btfsc	RCSTA,OERR	; オーバーランエラーのチェック（1:エラー,0:正常）
	goto	OVER
	movf	RCREG,W		; RCREGレジスタから受信データを読み込む
	movwf	MEASURE
	movlw	41H
	subwf	MEASURE,W
	btfsc	STATUS,Z
	goto	Main		; 測定開始コマンドなら、何もしない
	movlw	42H
	subwf	MEASURE,W
	btfss	STATUS,Z
	goto	Chk_RX1
	bcf	LED_out		; 測定停止コマンドなら、LED off
	goto	Main

Chk_RX1	movlw	43H
	subwf	MEASURE,W
	btfss	STATUS,Z
	goto	Chk_RX2
	movf	CH1,W		; 電圧レンジコマンドなら、
	call	TXD		;   CH1、CH2を送信
	movf	CH2,W
	call	TXD
	movlw	42H
	movwf	MEASURE
	goto	Main

Chk_RX2	movlw	44H
	subwf	MEASURE,W
	btfss	STATUS,Z	; ストレージ
	goto	Main
	bsf	LED_out		; LED on
	bsf	STATUS,IRP	; Bank2,3
	movlw	90H
	movwf	FSR		; Bank3 190H
Strg	call	AD_CONV
	bcf	FSR,7		; Bank2 11xH
	movf	ADBUF1,W
	movwf	INDF
	bsf	FSR,7		; Bank3 19xH
	movf	ADBUF2,W
	movwf	INDF
	incf	FSR,F
	movf	FSR,W
	sublw	0F0H
	btfss	STATUS,Z	; 96Byte終了?
	goto	Strg
	movlw	0A0H
	movwf	FSR		; Bank1 0A0H
Strg1	call	AD_CONV
	bcf	STATUS,IRP	; Bank0,1
	movf	ADBUF1,W
	movwf	INDF
	incf	FSR,F
	movf	ADBUF2,W
	movwf	INDF
	incf	FSR,F
	movf	FSR,W
	sublw	0H
	btfss	STATUS,Z	; 96Byte終了?
	goto	Strg1

	bsf	STATUS,IRP	; Bank2,3
	movlw	90H
	movwf	FSR		; Bank3 190H
Strg2	bcf	FSR,7		; Bank2 11xH
	movf	INDF,W
	call	TXD
	bsf	FSR,7		; Bank3 19xH
	movf	INDF,W
	call	TXD
	incf	FSR,F
	movf	FSR,W
	sublw	0F0H
	btfss	STATUS,Z	; 96Byte終了?
	goto	Strg2
	bcf	STATUS,IRP	; Bank0,1
	movlw	0A0H
	movwf	FSR		; Bank1 0A0H
Strg3	movf	INDF,W
	call	TXD
	incf	FSR,F
	movf	INDF,W
	call	TXD
	incf	FSR,F
	movf	FSR,W
	sublw	0H
	btfss	STATUS,Z	; 96Byte終了?
	goto	Strg4
	call	Wait10		; 10msec wait
	movlw	0D1H
	call	TXD		; ストレージ継続コマンド送信
	call	Wait10		; 10msec wait
	goto	Chk_RX2

Strg4	btfss	PIR1,RCIF	; USART 受信割り込みフラグビットチェック
	goto	Strg3
	movf	RCREG,W		; RCREGレジスタから受信データを読み込む
	movwf	MEASURE
	movlw	42H
	subwf	MEASURE,W
	btfss	STATUS,Z	; 測定停止
	goto	Strg3
strg5	bcf	LED_out		; LED off
	movlw	42H
	movwf	MEASURE
	goto	Main

FRAME	movf	RCREG,W
	call	LED1ON		; LED 1secon
	call	LED1ON		; LED 1secon
	btfss	RCSTA,OERR
	goto	Main

OVER	movf	RCREG,W
	bcf	RCSTA,CREN
	bsf	RCSTA,CREN
	call	LED1ON		; LED 1secon
	call	LED1ON		; LED 1secon
	call	LED1ON		; LED 1secon
	goto	Main

; -------------------------------SUB ROUTINE--------------------------------
; AD変換

AD_CONV	movlw	b'01001001'	; Select AN1
	movwf	ADCON0
	call	Wait2u		; 20μsec Wait
	bsf	ADCON0,GO	; AD start
ADLOP1	btfsc	ADCON0,GO	; AD Done?
	goto	ADLOP1
	rrf	ADRESH,W	; Get A/D data
	andlw	7FH
	movwf	ADBUF1		; AD -> ADBUF1

	movlw	b'01000001'	; Select AN0
	movwf	ADCON0
	call	Wait2u		; 20μsec Wait
	bsf	ADCON0,GO	; AD start
ADLOP2	btfsc	ADCON0,GO	; AD Done?
	goto	ADLOP2
	rrf	ADRESH,W	; Get A/D data
	andlw	7FH
	movwf	ADBUF2		; AD -> ADBUF2
	return

; 電圧セレクタ入力

RSWIN	movf	PORTB,W
	movwf	PORT_AB
	movlw	0C0H
	btfss	PORT_AB,7
	goto	RSW21
	btfss	PORT_AB,6
	goto	RSW22
	btfss	PORT_AB,4
	goto	RSW23
	btfss	PORT_AB,3
	goto	RSW24
	addlw	d'1'		; RSW2-OFF C5H
RSW24	addlw	d'1'		; RSW2-4   C4H
RSW23	addlw	d'1'		; RSW2-3   C3H
RSW22	addlw	d'1'		; RSW2-2   C2H
RSW21	addlw	d'1'		; RSW2-1   C1H
	movwf	CH2_Buff
	subwf	CH2,W
	btfsc	STATUS,Z	; 変化有？
	goto	RSW1
	movf	CH2_Buff,W
	movwf	CH2		; 新データ保存
	call	TXD

RSW1	movf	PORTA,W
	movwf	PORT_AB
	movlw	0B0H
	btfss	PORT_AB,7
	goto	RSW11
	btfss	PORT_AB,6
	goto	RSW12
	btfss	PORT_AB,4
	goto	RSW13
	btfss	PORT_AB,3
	goto	RSW14
	addlw	d'1'		; RSW1-OFF B5H
RSW14	addlw	d'1'		; RSW1-4   B4H
RSW13	addlw	d'1'		; RSW1-3   B3H
RSW12	addlw	d'1'		; RSW1-2   B2H
RSW11	addlw	d'1'		; RSW1-1   B1H
	movwf	CH1_Buff
	subwf	CH1,W
	btfsc	STATUS,Z
	return
	movf	CH1_Buff,W
	movwf	CH1		; 新データ保存
	call	TXD
	return

TXD	Sel_Bank1
TXD1	btfss	TXSTA,TRMT
	goto	TXD1
	Sel_Bank0
	movwf	TXREG
	return

; LED 1sec間点灯

LED1ON	bsf	LED_out		; LED on
	movlw	d'100'
	call	Waitx		; 10msec*100=1sec
	bcf	LED_out		; LED off
	movlw	d'100'
	call	Waitx		; 10msec*100=1sec
	return

Waitx	movwf	CNT3		; 10ms*CNT3 最大10*256=2.56sec
Wloopx	call	Wait10		; 9.999msec+0.5μ*2=10msec Wait
	decfsz	CNT3,F
	goto	Wloopx
	return

Wait10	movlw	d'241'		; (84n+6)*1サイクル時間(4/Fosc)
	movwf	CNT2		;	9.999msec
Wloop1	call	Wait2u		; 19μsec+0.5μ*2=20μsec Wait
	call	Wait2u		; 19μsec+0.5μ*2=20μsec Wait
	nop
	decfsz	CNT2,F
	goto	Wloop1
	nop
	nop
	return

Wait2u	movlw	d'8'		; (4n+6)*1サイクル時間(4/Fosc)
	movwf	CNT1		;	8MHz 4/8=0.5μsec
Wloop2	nop			;	19μsec
	decfsz	CNT1,F
	goto	Wloop2
	nop
	nop
	return

	end
