;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
;		オーディオジェネレータ　Ver０．１	ＪＡ０ＱＯＮ
;
;		内蔵ＤＡＣによる低周波信号発生プログラム
;		実験回路２　コントロール部
;		PIC12F1823 32MHZ（内部オシレータ）
;
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;



		LIST	P=PIC16F1823
		INCLUDE	P16F1823.INC

;		
;CONFIGURATION WORD 1(ADDRESS:8007H)マニュアル50ページ
;					設定
;bit13		FCMEN	0	Fail-Safe Clock Monitor
;						1=有効,0=無効
;bit12		IESO	0	内部･外部切替スイッチモード
;			________	1=有効,0=無効
;bit11		CLKOUTEN 1	クロック出力イネーブルビット
;						1=無効　RA4I/O使用可
;						0=有効　クロックがCLKPUTピンに出力される
;bit10-9	BOREN	00	ブラウンアウト設定
;						11=有効
;						10=スリープ時以外有効
;			___			00=無効
;bit8		CPD		1	データメモリプロテクション
;			__			1=無効,0=有効
;bit7		CP		1	プログラムメモリプロテクション　
;						1=無効,0=有効
;bit6		MCLRE	0	RA3/MCLRピン選択ビット
;			_____		1=MCLR有効,0=RA3有効(Digital input)
;bit5		PWRTE	0	power_up timer　使います。
;						1=無効,0=有効
;bit4-3		WDTE	00	Watchdog Timer
;						11=有効
;						10=ランニング中に有効、スリープ中は無効
;						01=レジスタによるコントロール
;						00=無効
;bit2-0		FOSC	100	発振器選択ビット
;						111=ECH:外部クロック入力（4-32MHZ)、RA4I/O可
;						110=ECM:外部クロック入力（0.5-4MHZ)、RA4I/O可
;						101=ECL:外部クロック入力（0-0.5MHZ)、RA4I/O可
;						100=INTOSC:内部発振、RA4-RA5I/O可
;						011=EXTRC:外部RC発振、RA4I/O可、RA5不可
;						010=HS：外部発振子、I/O不可
;						001=XT：　〃
;						000=LP：　〃
;
;bit	15 14 13 12 11 10 09 08 07 06 05 04 03 02 01 00
;data    0  0  0  0  1  0  0  1  1  0  0  0  0  １  0  0
;
;
	__CONFIG _CONFIG1,	B'0000100110000100'
;
;CONFIGURATION WORD 2(ADDRESS:8008H)マニュアル52ページ
;					設定
;bit13		LVP		0	低電圧プログラミング設定
;						1=有効
;			_____		0=無効、高電圧必要
;bit12		DEBUG	1	インサーキット･デバッガ モード設定
;						1=無効
;						0=有効、RA0-1をデバッガに使用
;bit11					Unimplemented
;bit10		BORV	0	ブラウンアウト･リセット電圧選択ビット（Vbor参照)
;						1=低電圧で動作
;						0=高電圧で動作
;bit9		STVREN	0	スタック･オーバーフロー･リセット設定
;						1=有効
;						0=無効
;bit8		PLLEN	0	PLL設定
;						1=4xPLL有効
;						0=4xPLL無効
;bit7-5					Unimplemented
;bit4					Reserved
;bit3-2					Unimplemented
;bit1-0		WRT		11	フラッシュメモリ プロテクション設定（EECONレジスタ参照)
;						11=無効
;						10=0h-1FFh有効
;						01=0h-3FFh有効
;						00=0h-7FFh有効
;
;bit	15 14 13 12 11 10 09 08 07 06 05 04 03 02 01 00
;data    0  0  0  1  0  0  0  0  0  0  0  0  0  0  1  1
;
;
	__CONFIG _CONFIG2,	B'0001000000000011'

;	PIC16F688からの重要変更点
;
;	STATUSレジスタの各フラグビット（マニュアルP24)
;
;bit7-5					unimplemented
;			__
;bit4		TO			タイムアウトビット
;						1=電源起動後、CLRWDT命令実行後、SLEEP命令実行後
;			__			0=WDTタイムアウト発生
;bit3		PD			パワーダウンビット
;						1=電源起動後、CLRW命令実行後
;						0=SLEEP命令実行
;bit2		Z			ゼロビット
;						1=演算結果がゼロ
;						0=演算結果がゼロ以外
;						          ____________
;bit1		DC			Ｄｉｇｉｔ Carry/Digit Borrow
;						1=キャリー発生、ボロー無
;						0=キャリー無、ボロー発生
;						　　　　　　______
;bit0		C			Carry/Borrow
;						1=キャリー発生、ボロー無
;						0=キャリー無、ボロー発生
;
;	SFRレジスタ アクセス方法
;
;	BSRレジスタ　xx08h
;	このレジスタの0-4ビットにバンクアドレス(0-1Fh)をセット
;	これが直接アドレッシングの7-11ビット(0-31バンク）に相当する
;	直接アドレッシングの下位0-6ビット(0-7Fh)はオペコードで指定
;
;
;	PORTへの入出力
;
;	PORT入出力方法は基本的には変わりません。
;	TRISA(C)で機能指定
;	PORTA(C)で入出力
;	以上で問題ありません。
;	しかし、PIC12F1822（16F1823)ではLATA(C)レジスタが見えるようになりました。
;	書き込み方法は2種類となり、どちらも結果は、ほぼ同じです。
;	PORTAへ書き込む
;	LATAへ書き込む
;
;	PORTの読込
;	PORTAからの読込はPORTピンの状態を表現しています。
;	LATAからの読込はその時点でのPORTピンの状態を表現してはいません。
;	PORTA(C)とLATA(C)との詳細な違いはマニュアルを読んでください。


;		ワークエリア定義
;
;		BANK0	20h-7Fh
;
;		使用していないのもあります
;

hex0		equ		020h		;取得HEXデータ
hex1		equ		021h		;
hex2		equ		022h
hex3		equ		023h
cnt0		equ		024h		;時間待ちルーチン用
cnt1		equ		025h
cnt2		equ		026h
cnt3		equ		027h
tmp0		equ		028h		;雑用
tmp1		equ		029h
flg			equ		02ah		;エラー＆設定フラグ
mode		equ		02bh		;実行モード設定
TMC			equ		02ch		;タイマオーバーフローカウンタ
wrk0		equ		02dh		;雑用
wrk1		equ		02eh		;
DCO			equ		02fh		;DAC逐次設定データ
IDC			equ		030h		;
FRQ0		equ		031h		;周波数設定データ
FRQ1		equ		032h
;

			ORG		0h
			goto	init
			ORG		04h
			goto	init

			org		05h
			


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
;			PIC16F1823　イニシャライズ
;
;		OSCCON(BANK1　099H) マニュアル69ページ
;			bit7	SPLLEN	ソフトウエアPLL設定ビット
;							1 = 4xPLL有効
;							0 = 4xPLL無効(リセット後)
;			＊コンフィグレーションワードPLLEN=1の時、この設定は無視される。
;			bit6-3	IRCF	内部発振器クロック選択ビット
;							000x = 31KHZ LF
;							0010 = 31.25KHZ MF
;							0011 = 31.25KHZ HF
;							0100 = 62.5KHZ MF
;							0101 = 125KHZ MF
;							0110 = 250KHZ MF
;							0111 = 500KHZ MF（デフォルト）
;							1000 = 125kHZ HF
;							1001 = 250kHZ HF
;							1010 = 500kHZ HF
;							1011 = 1MHZ HF
;							1100 = 2MHZ HF
;							1101 = 4MHZ HF
;							1110 = 8MHZ or 32MHZ HF
;							1111 = 16MHZ HF
;			bit2			Unimplemented
;			bit1-0	SCS		システムクロック選択ビット
;							1x = 内部発振器
;							01 = タイマ1発振器
;							00 = FOSCで指定された発振器(リセット後)
;			(注)詳細はマニュアルあるいは当局HP内解説を参照
;							HF=HFINTOSC（16MHZ)
;							MF=MFINTOSC(500KHZ)
;							LF=LFINTOSC(32KHZ)
;
;
;			32MHZ内部発振設定
;		コンフィグレーションワード1		FOSC=100
;		OSCCON				SCS=00
;		OSCCON				IRCF=1110
;		OSCCON				SPLLEN=1(#1)
;		コンフィグレーションワード2		PLLEN=1(#1)
;						(#1)設定はどちらかでOKだが、PLLEN=1とすると、
;							OSCCONのSPLLEN=0の設定は無効となる。
;							また、8MHZのHFINTOSCは選択の余地が無い。
;
;		PORTA(BANK0　00CH）　マニュアル126ページ
;			bit7-6	Unimplemented(read=0)
;			bit5-4	RA5-4	デジタルI/O、アナログ入力
;			bit3	RA3		デジタルInputのみ
;			bit2	RA2-1	デジタルI/O、アナログ入力
;			bit0	RA0		デジタル･アナログI/O,DAコンバータ出力
;
;		PORTC(BANK0　00EH）　マニュアル130ページ
;			bit7-6	Unimplemented(read=0)
;			bit5-4	RC5-4	デジタルI/O
;			bit3	RC3-0	デジタルI/O、アナログ入力
;
;		TRISA(BANK1　08CH)　マニュアル126ページ
;			bit7-6	Unimplemented(read=0)
;			bit5-4	RA5-4	1=入力、0=出力
;			bit3	RA3		常に1
;			bit2	RA2-0	1=入力、0=出力
;
;		TRISC(BANK1　08EH)　マニュアル130ページ
;			bit7-6	Unimplemented(read=0)
;			bit5-4	RA5-0	1=入力、0=出力
;
;		LATA(BANK2　10CH)　データラッチﾚｼﾞｽﾀ　マニュアル127ページ
;			bit7-6	Unimplemented(read=0)
;			bit5-4	RA5-4	出力データ保持
;			bit3	Unimplemented(read=0)
;			bit2	RA2-0	出力データ保持
;							（このラッチデータはTRISAレジスタ設定で各ピンに反映される）
;
;		LATC(BANK2　10EH)　データラッチﾚｼﾞｽﾀ　マニュアル130ページ
;			bit7-6	Unimplemented(read=0)
;			bit5-0	RA5-4	出力データ保持
;							（このラッチデータはTRISCレジスタ設定で各ピンに反映される）
;
;
;		ANSELA(BANK3　18CH)　マニュアル127ページ
;			bit7-5	Unimplemented(read=0)
;			bit4	ANSA3/RA4	アナログ/デジタル選択ビット
;								1=アナログ入力
;								0=デジタルI/O
;			bit3	Unimplemented(read=0)
;			bit2-0	ANA2-0/RA2-0アナログ/デジタル選択ビット
;								1=アナログ入力
;								0=デジタルI/O
;			＊デフォルトでは、すべて1(アナログ入力)となっている
;
;		ANSELC(BANK3　18EH)　マニュアル131ページ
;			bit7-4	Unimplemented(read=0)
;			bit3-0	ANSC3-0/RC3-0　アナログ/デジタル選択ビット
;								1=アナログ入力
;								0=デジタルI/O
;			＊デフォルトではアナログ入力となっている
;
;		WPUA(BANK4　20CH)　ポートAプルアップ設定ビット
;			bit7-6	Unimplemented(read=0)
;			bit5-0			1=PORTA各ビットプルアップ有効
;					 _____	0=PORTA各ビットプルアップ無効
;					*WPUENビットが有効の時のみ、設定有効となる。
;
;		WPUC(BANK4　20EH)　ポートCプルアップ設定ビット
;			bit7-6	Unimplemented(read=0)
;			bit5-0			1=PORTC各ビットプルアップ有効
;					 _____	0=PORTC各ビットプルアップ無効
;					*WPUENビットが有効の時のみ、設定有効となる。
;
;
;		ADCON1レジスタ(BANK1　09EH)マニュアル
;		bit7	ADFM	変換結果格納指定
;						1=右詰
;						0=左詰め
;		bit6-4	ADCS	A/D変換クロック選択ビット
;						000	= Fosc/2
;						001 = Fosc/8
;						010 = Fosc/32
;						011 = Frc
;						100 = Fosc/4
;						101 = Fosc/16
;						110 = Fosc/64
;						111 = Frc
;		bit3-2	Unimplemented(read=0)
;		bit1-0	ADPREF	参照正電圧指定
;						00 = VDD
;						01 = Reserved
;						10 = 外部VREF+ (RA1)
;						11 = 内部FVRモジュール
;
;
;		OPTION_REG(BANK1　095H)　マニュアル177ページ
;					_____
;			bit7=1	WPUEN	プルアップ グローバル設定ビット
;							0=有効,1=無効
;			bit6=0	INTEDG	INTピン割り込み信号エッジ↑
;							1=↑
;							0=↓
;			bit5=0	TMR0CS	TMR0クロックソース選択ビット
;							1=外部入力RA2/T0CKI
;							0=内部システムクロック(Fosc/4)
;			bit4=1	TMR0SE	TMR0ソースエッジ選択ビット
;							1=RA4/T0CKIピンが↑の時インクリメント
;							0=RA4/T0CKIピンが↓の時インクリメント
;			bit3=0	PSA		プリスケーラ割当ビット
;							1=WDT
;							0=TMR0
;			bit2-0	PS		プリスケーラ分周比	000 1/2
;										001	1/4
;										010	1/8
;										011	1/16
;										100	1/32
;										101	1/64
;										110	1/128
;										111	1/256
;
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
	
init
;			各レジスタ初期設定

			;クロック設定
			movlb	01h			;BANK１に切替
			movlw	0f0h		;1111000B
			movwf	OSCCON		;内部発振器は8MHZに設定
								;4xPLL=ON
			;I/Oポート初期化
			movlb	0h			;BANK0
			clrf	PORTA		;Init PORT
			clrf	PORTC
			movlb	02h			;BANK2
			clrf	LATA		;出力ラッチﾚｼﾞｽﾀ
			clrf	LATC
			movlb	03h			;BANK3
			movlw	01h			;00000001B
			movwf	ANSELA		;RA0,アナログ
								;RA1-5,デジタルI/O
			clrf	ANSELC		;RC0-5,デジタルI/O
			movlb	01h			;BANK1
			movlw	0ffh
			movwf	TRISA		;すべて入力
			clrf	TRISC		;すべて出力

			;TMR0およびプルアップ設定
			movlb	01h			;BANK1
			movlw	090H		;10010000b
			movwf	OPTION_REG	;プルアップOFF
								;割込みエッジ↓
								;クロックソース内部（Fosc/4）
								;TMR0カウントエッジ↑
								;プリスケーラ割当→TMR0
								;プリスケーラ分周1/2にセット

			;ADC
			movlb	01h			;BANK1
			movlw	030h		;0011000B
			movwf	ADCON1		;左詰め、基準電圧VDD
								;ADCクロック　Fosc/64=2us(32MHZ)
			
;			初期値セット
;
;		スタートアップ シーケンス
;		制御側PIC			生成側PIC
;		初期化中			初期化中
;		出力ポート初期設定	100msウエイト
;		100msウエイト		入力ポート準備OK
;		100msウエイト		データ入力待ち		
;		データ転送開始		データ受信
;
			clrf	BSR
			movlw	030h
			movwf	PORTC		;INT=H,LED_ON
			call	wait100m
			call	wait100m	;
			bcf		PORTC,5		;LED_OFF
        	clrf	flg
;        	goto	coldst
;			goto	debug10

;		初期生成周波数設定値
;		周波数	1KHZ
;		TMR0=87H
;		PS=1/2
;

coldst
			movlw	087h		;初期値設定
			movwf	hex0		;ADC出力データ
			movwf	FRQ0		;1KHZ生成指令
			movlw	09h			;PS=1/2
			movwf	FRQ1
			movlw	01h
			movwf	hex1		;DIP_SWデータ
			call	put_data
			call	wait100m
mloop
			call	get_mode	;W=0の時VRモード
			iorlw	0h			;W=1の時プリセットモード
			btfss	STATUS,Z
			goto	mloop2
			goto	mloop3		;自動変速VRモード
								;↑このモードにするには行を有効にする事

;			手動PS切替VRモード
			call	get_por		;flg_0
			call	get_adc		;flg_1
			movf	flg,W
			iorlw	0h
			btfss	STATUS,Z
			call	put_data
			call	wait100m
			goto	mloop		;

			;プリセットモード
mloop2
			call	get_pre
			movf	flg,W
			iorlw	0h
			btfss	STATUS,Z
			call	put_data
			call	wait100m
			goto	mloop		;
								;

;
;			自動変速VRモード
;
mloop3
			call	get_adc		;ADCデータ取得
			call	rev_tm
			movf	flg,W
			iorlw	0h
			btfss	STATUS,Z
			call	put_data
			call	wait100m
			goto	mloop		;


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
;			動作設定
;
;		
;		使用ワーク
;				動作モード				mode0	VRモード
;									mode1	プリセットモード
;		使用ポート
;		RA1
;				
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

get_mode
			movlb	0h
        	btfss	PORTA,1		;MODEスイッチチェック
			goto	mode1
mode0		clrf	mode		;mode=0
			retlw	00h
mode1      	movlw	1			;
			movwf	mode		;mode=1
			retlw	01h

;
;			ポート（DIPスイッチ)からのデータを取得
;
;		使用変数
;		FRQ0	TMR0設定指示値
;		FRQ1	プリスケーラ設定指示値
;		hex1	取得実データ
;		使用フラグ	flg　ビット0　変更有=1,変更無=0
;
;		使用ポート
;		RA2		data0
;		RA3		data1
;		RA4		data2
;		RA5		data3
;
;		制御出力データ(FRQ1下位3ビット)
;		DIP0	x000	プリスケーラOFF(1/1)
;		DIP1	x001	プリスケーラ1/2
;		DIP2	x010	プリスケーラ1/4
;		DIP3	x011	プリスケーラ1/8
;		DIP4	x100	プリスケーラ1/16
;		DIP5	x101	プリスケーラ1/32
;		DIP6	x110	プリスケーラ1/128
;
;		制御データ変更有無（FRQ1 bit3）
;		FRQ1	0xxx	変更無
;		FRQ1	1xxx	変更有
;	


get_por
			movf	hex1,W
			movwf	tmp0		;現hex1保存

gpor00		call	get_sw		;W=スイッチデータ			
			movwf	tmp1
			call	wait5m		;チャタリング待ち時間
			call	get_sw		;W_REG破壊しないよう注意
			xorwf	tmp1,F		;W XOR tmp1
			btfss	STATUS,Z
			goto	gpor00		;スイッチ安定化待ち
			;hex1新旧比較
			xorwf	tmp0,F		;新旧hex1比較
			btfss	STATUS,Z	;同じなら0,違うと1
			goto	gpor01

			;データ変更無
			bcf		flg,0		;flg_0=0のときデータ変更無
			bcf		FRQ1,3
			return

			;データ変更有
gpor01
			movwf	hex1		;データ更新
			movwf	FRQ1
			bsf		flg,0		;flg_0=1のときデータ変更有
			bsf		FRQ1,3		;
			return



;
;			プリセットモード
;
;		mode=1の時有効
;

get_pre
			movf	hex1,W
			movwf	tmp0		;以前のhex1
gpre00		call	get_sw		;W=スイッチデータ			
			movwf	tmp1
			call	wait5m		;チャタリング待ち時間
			call	get_sw
			xorwf	tmp1,F		;W_REG破壊しないよう注意
			btfss	STATUS,Z
			goto	gpre00		;DIPスイッチ安定化待ち
			;
			xorwf	tmp0,F		;tmp0=以前のhex1
			btfss	STATUS,Z
			goto	gpre01

			;データ変更無
			bcf		flg,0		;
			bcf		FRQ1,3
			return

			;データ変更有
gpre01
			movwf	hex1		;新データ保存
			call	prest		;FRQx設定
			bsf		flg,0
			bsf		FRQ1,3
			return
			
			;Aポート読込　RA2-RA5の4ビットを取得
			;取得データはW_REGに入れてリターン
get_sw		movf	PORTA,W		;ポートデータ取得
			movwf	wrk0
			lsrf	wrk0,F
			lsrf	wrk0,W
			andlw	0fh			;下位4ビットに集約
			return

			;周波数データをFRQ0,FRQ1にセット
			
prest
			movf	hex1,W
 			movwf	tmp0
 			iorlw	0h			;
 			btfsc	STATUS,Z
 			goto	pres00		;プリセット0
			 					;decfはCフラグに反応しない
 			decf	tmp0,F		;
			btfsc	STATUS,Z	;
			goto	pres01		;プリセット1へ行く

 			decf	tmp0,F		;
			btfsc	STATUS,Z	;
			goto	pres02		;プリセット2へ行く

 			decf	tmp0,F		;
			btfsc	STATUS,Z	;
			goto	pres03		;プリセット3へ行く

 			decf	tmp0,F		;
			btfsc	STATUS,Z	;
			goto	pres04		;プリセット4へ行く

 			decf	tmp0,F		;
			btfsc	STATUS,Z	;
			goto	pres05		;プリセット5へ行く

 			decf	tmp0,F		;
			btfsc	STATUS,Z	;
			goto	pres06		;プリセット6へ行く

 			decf	tmp0,F		;
			btfsc	STATUS,Z	;
			goto	pres07		;プリセット7へ行く

 			decf	tmp0,F		;
			btfsc	STATUS,Z	;
			goto	pres08		;プリセット8へ行く

 			decf	tmp0,F		;
			btfsc	STATUS,Z	;
			goto	pres09		;プリセット9へ行く

 			decf	tmp0,F		;
			btfsc	STATUS,Z	;
			goto	pres10		;プリセット10へ行く

 			decf	tmp0,F		;
			btfsc	STATUS,Z	;
			goto	pres11		;プリセット11へ行く

 			decf	tmp0,F		;
			btfsc	STATUS,Z	;
			goto	pres12		;プリセット12へ行く

 			decf	tmp0,F		;
			btfsc	STATUS,Z	;
			goto	pres13		;プリセット13へ行く

 			decf	tmp0,F		;
			btfsc	STATUS,Z	;
			goto	pres14		;プリセット14へ行く

 			decf	tmp0,F		;
			btfsc	STATUS,Z	;
			goto	pres15		;プリセット15へ行く

;
;			プリセットデータ設定
;
;		タイマ0でのウエイト時間以外で1us程度消費する
;
pres00		;プリセット0				f=約100HZ(10ms)
								;計算値313us
			movlw	04h			;プリスケーラ1/16
			movwf	FRQ1
			movlw	064h		;TMR0設定値
			movwf	FRQ0		;タイマ0設定値312us
			return

pres01		;プリセット1				f=約300HZ(3.33ms)
								;計算値104us
			movlw	02h			;プリスケーラ1/4
			movwf	FRQ1
			movlw	032H		;
			movwf	FRQ0		;タイマ0設定値103us
			return

pres02		;プリセット2				f=約500HZ(2ms)
								;計算値62.5us
			movlw	01h			;プリスケーラ1/2
			movwf	FRQ1
			movlw	0ah			;TMR0設定値
			movwf	FRQ0		;タイマ0設定値61.5us
			return

pres03		;プリセット3				f=約800HZ(1.25ms)
								;計算値39us
			movlw	01h			;プリスケーラ1/2
			movwf	FRQ1
			movlw	068h		;TMR0設定値
			movwf	FRQ0		;タイマ0設定値38us
			return

pres04		;プリセット4				f=約1KHZ(1000us)
								;計算値31.25us
			movlw	0h			;プリスケーラ1/1
			movwf	FRQ1
			movlw	0eh			;TMR0設定値
			movwf	FRQ0		;タイマ0設定値30.25us
			return

pres05		;プリセット5				f=約1.3KHZ(769us)
								;計算値24us
			movlw	0h			;プリスケーラ1/1
			movwf	FRQ1
			movlw	048h		;TMR0設定値
			movwf	FRQ0		;タイマ0設定値23us
			return

pres06		;プリセット6				f=約1.5KHZ(666.7us)
								;計算値21us
			movlw	0h			;プリスケーラ1/1
			movwf	FRQ1
			movlw	060h		;TMR0設定値
			movwf	FRQ0		;タイマ0設定値20us
			return

pres07		;プリセット7				f=約1.8KHZ
								;計算値17.36us
			movlw	0h			;プリスケーラ1/1
			movwf	FRQ1
			movlw	07dh		;TMR0設定値
			movwf	FRQ0		;タイマ0設定値16.375us
			return

pres08		;プリセット8				f=約2.0KHZ
								;計算値15.625us
			movlw	0h			;プリスケーラ1/1
			movwf	FRQ1
			movlw	08bh		;TMR0設定値
			movwf	FRQ0		;タイマ0設定値14.625us
			return

pres09		;プリセット9				f=約2.5KHZ
								;計算値12.5us
			movlw	0h			;プリスケーラ1/1
			movwf	FRQ1
			movlw	0a4h		;TMR0設定値
			movwf	FRQ0		;タイマ0設定値11.50us
			return

pres10		;プリセット10				f=約3.0KHZ
								;計算値10.42us
			movlw	0h			;プリスケーラ1/1
			movwf	FRQ1
			movlw	0b5h		;TMR0設定値
			movwf	FRQ0		;タイマ0設定値9.375us
			return

pres11		;プリセット11			f=約3.5KHZ
								;計算値8.9us
			movlw	0h			;プリスケーラ1/1
			movwf	FRQ1
			movlw	0c1h		;TMR0設定値
			movwf	FRQ0		;タイマ0設定値7.875us
			return

pres12		;プリセット12			f=約4.0KHZ
								;計算値7.8us
			movlw	0h			;プリスケーラ1/2
			movwf	FRQ1
			movlw	0cah		;TMR0設定値
			movwf	FRQ0		;タイマ0設定値6.75us
			return

pres13		;プリセット13			f=約5.0KHZ
								;計算値6.25us
			movlw	0h			;プリスケーラ1/1
			movwf	FRQ1
			movlw	0d6h		;TMR0設定値
			movwf	FRQ0		;タイマ0設定値5.25us
			return

pres14		;プリセット14			f=約8.0KHZ
								;計算値3.9us
			movlw	0h			;プリスケーラ1/1
			movwf	FRQ1
			movlw	0e8h		;TMR0設定値
			movwf	FRQ0		;タイマ0設定値3.0us
			return

pres15		;プリセット15			f=約10KHZ
								;目標値3.125us
			movlw	0h			;プリスケーラ1/1
			movwf	FRQ1
			movlw	0eeh		;TMR0設定値
			movwf	FRQ0		;タイマ0設定値2.250us
			return



;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
;			データ最適化サブルーチン
;
;
;		DIPスイッチでPS値を手動変更せず、プログラムで自動変更する
;		hex0のデータ00H-FFHから適する周波数データに修正
;		最適化されたデータはFRQ0,FRQ1に収納
;		このサブルーチンを使用する場合、PS値手動変更を禁止とする事
;
;		入力		hex0	00H-FFH
;		出力		FRQ0	TMR0設定指示値
;				FRQ1	プリスケール値+変更フラグ
;
;		最適化変換表
;		hex0		PS		TMR0
;	高域	ABH-FFH		1/1		A0H-F4H（約2KHZ-12KHZ)
;	中域	54H-ABH		1/2		78H-CFH(約900HZ-2KHZ)
;	低Ａ	38H-53H		1/8		C2H-DDH（約500HZ-900HZ)
;	低Ｂ	10H-37H		1/32	C9H-F0H(約140HZ-500HZ)
;	低Ｃ	00H-0FH		1/128	E2H-F1H（約70HZ-140HZ)
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

rev_tm
;		振分け
			movf	hex0,W
			movwf	tmp0
			sublw	0aah
			btfss	STATUS,C
			goto	thgt		;高域
		
			movf	tmp0,W
			sublw	053h
			btfss	STATUS,C
			goto	tmdl		;中域
		
			movf	tmp0,W
			sublw	037h
			btfss	STATUS,C
			goto	tlla		;低域Ａ
		
			movf	tmp0,W
			sublw	0fh
			btfss	STATUS,C
			goto	tllb		;低域Ｂ

;		低域Ｃ
tllc
			movlw	0e2h		;E2H-F1H（約60HZ-140HZ)
			addwf	tmp0,W		;00H-0FH→E2H-F1H
			movwf	FRQ0		;TMR0値
			movlw	0fH			;00001111B
			movwf	FRQ1		;プリスケーラ分周1/128にセット
			return
		
;		低域Ｂ
tllb
			movlw	0b9h		;C9H-F0H(約140HZ-500HZ)
			addwf	tmp0,W		;10H~37H→C9H~F0H
			movwf	FRQ0		;TMR0値
			movlw	0dH			;00001101B
			movwf	FRQ1		;プリスケーラ分周1/32にセット
			return
			
;		低域Ａ
tlla
			movlw	08ah		;C2H-DDH（約500HZ-900HZ)
			addwf	tmp0,W		;38H~53H→C2H~DDH
			movwf	FRQ0		;TMR0値
			movlw	0bH			;00001011B
			movwf	FRQ1		;プリスケーラ分周1/8にセット
			return
			
;		中域
tmdl
			movlw	024h		;78H-CFH(約900HZ-2KHZ)
			addwf	tmp0,W		;54H-ABH→78H-CFH
			movwf	FRQ0		;TMR0値
			movlw	09H			;00001001B
			movwf	FRQ1		;プリスケーラ分周1/2にセット
			return

;		高域
thgt
			movlw	0bh			;A0H-F4H（約2KHZ-12KHZ)
			subwf	tmp0,W		;ABH-FFH→A0H-F4H
			movwf	FRQ0		;TMR0値
			movlw	08H			;00001000B
			movwf	FRQ1		;プリスケーラ分周1/1にセット
			movlb	0h
			return


;
;			データ送信
;
;		使用変数
;		FRQ0	TMR0設定指示値
;		FRQ1	プリスケーラ設定指示値
;
;		使用ポート
;		RC0		data0
;		RC1		data1
;		RC2		data2
;		RC3		data3
;		RC4		INT/STR トリガ=↓
;		RC5		LED 1=ON
;
;		送信シークエンス
;		FRQ0下位4ビットをRC0-3にセット
;		RC4=↓
;		読込待ち10us
;
;		FRQ0上位4ビットをRC0-3にセット
;		RC4=↑
;		読込待ち5us
;
;		FRQ1下位4ビットをRC0-3にセット
;		RC4=↓
;		読込待ち5us
;		RC4=↑
;		ウエイト10us


put_data
			;TMROデータ下位4ビット
			movf	FRQ0,W
			andlw	0fh			;データ部分
			iorlw	020h		;INT↓、LED_ON
			movlb	02h
			movwf	LATC
			movlb	0h
			call	w10u		;10us wait
			;TMR0データ上位4ビット
			swapf	FRQ0,W
			andlw	0fh			;データ部分
			iorlw	030h		;INT↑,LED_ON
			movlb	02h
			movwf	LATC
			movlb	0h
			call	w05u		;5us wait
			;プリスケーラ制御4ビット
			movf	FRQ1,W
			andlw	0fh			;データ部分
			iorlw	020h		;INT↓,LED_ON
			movlb	02h
			movwf	LATC
			movlb	0h
			call	w05u		;5us wait
			;終了処理
			movlw	010h		;INT↑、LED_OFF
			movlb	02h
			movwf	LATC
			movlb	0h
			call	w10u		;10us wait
			return
			


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
;
;			Ａ／Ｄ変換サブルーチン
;
;		アナログ入力ポート		RA0/AN0/CH0
;		結果格納方法		ADFM=0/左詰め/ADRESHのみ取得
;		出力データ			hex0（上位8ビット）
;		使用フラグ			flg　ビット1　変更有=1,変更無=0
;
;		ADCON0レジスタ（BANK1　09DH)　マニュアル147ページ
;		bit7	Unimplemented(read=0)
;		bit6-2	CHSx	アナログチャンネル指定
;						00000 = AN0/RA0
;						00001 = AN1/RA1
;						00010 = AN2/RA2
;						00011 = AN3/RA3
;						00100 = AN4/RC0(#1)
;						00101 = AN5/RC1(#1)
;						00110 = AN6/RC2(#1)
;						00111 = AN7/RC3(#1)
;						01000 = Reserved.No channel connected
;						    ・
;						11100 = Reserved.No channel connected
;						11101 = 温度表示器(#4)
;						11110 = DAC出力(#2)
;						11111 = FVRバッファ1出力(#3)
;		bit1	GO/DONE	A/D変換ステータスビット
;						1=変換開始指令（１にすると変換動作開始）
;						0=変換完了(変換完了すると０になる）
;		bit0	ADON	A/D変換ステータスビット
;						1=A/Dコンバータ動作
;						0=A/Dコンバータ停止
;
;		(#1)PIC16F1823のみ
;		(#2)ADC入力はDAC出力に接続される。
;		(#3)ADC入力はFVRバッファ1に接続される。
;		(#4)ADC入力は温度表示モジュール出力に接続される。
;
;		ADCON1レジスタ(BANK1　09EH)
;		bit7	ADFM	変換結果格納指定
;						1=右詰
;						0=左詰め
;		bit6-4	ADCS	A/D変換クロック選択ビット
;						000	= Fosc/2
;						001 = Fosc/8
;						010 = Fosc/32
;						011 = Frc
;						100 = Fosc/4
;						101 = Fosc/16
;						110 = Fosc/64
;						111 = Frc
;		bit3-2	Unimplemented(read=0)
;		bit1-0	ADPREF	参照正電圧指定
;						00 = VDD
;						01 = Reserved
;						10 = 外部VREF+ (RA1)
;						11 = 内部FVRモジュール
;
;
;		使用ワーク
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


;			VRによる分圧電圧取得

get_adc
			movf	hex0,W
			movwf	tmp0		;hex0保存
			movlb	01h
			movlw	01h			;00000001b
								;左詰め、基準電圧VDD、
								;AN0(RA0)選択、ADON_ON
			movwf	ADCON0		;電圧サンプリング開始
			call	w10u		;サンプリング電圧安定化待ち
			call	w10u
			movlb	01h
			bsf		ADCON0,GO	;A/D変換開始指令
aloop
			btfsc	ADCON0,GO	;A/D変換完了待ち 
			goto	aloop		;GO=0ならば次へ
			movf	ADRESH,W	;データ上位８ビット
			bcf		ADCON0,ADON	;A/DコンバータOFF
			movlb	0h
			movwf	hex0		;上位８ビットをhex0に保存

			movwf	FRQ0
			xorwf	tmp0,W
			btfss	STATUS,Z
			goto	gad01
			bcf		flg,1		;データ変更無
			return
gad01		bsf		flg,1		;データ変更有
			return


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
;			遅延時間サブルーチン	32MHZ用
;
;		1cycle	= 0.125us
;		使用レジスタ	= cnt2,cnt3
;		BSR		=0(BANK0)
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

wait100u						;呼び出しも含めて、100us
								;call is 2cycles
			movlw	09h			;1
			movwf	cnt2		;1
			movlb	0h
			nop
			nop					;3
w100u		nop					;
			call	w10u		;10*9=90us(ここだけ命令ステップを数えない）
			decfsz	cnt2,F		;4*8+3=31cycles
			goto	w100u
			return				;2+5+31+2=40cycles=20us

wait50u							;呼び出しも含めて、50us
			call	wait25u
wait25u							;呼び出しも含めて、25us
			call	w10u
			call	w10u
			movlw	0bh			;5us=0.125us*40cycles			
			movwf	cnt2		;
w25u		decfsz	cnt2,F		;ループ 2+10*3+2=34cycles
			goto	w25u
			nop
			nop
			return				;2+34+2+2=40cycles=5us

wait5m							; 5ms 
			movlb	0h
			movlw	05h
			movwf	cnt2
w5m			call	w1m
			decfsz	cnt2,F
			goto	w5m
			return

wait10m							; 10ms
			movlb	0h
			movlw	d'10'
			movwf	cnt2
w10m		call	w1m
			decfsz	cnt2,F
			goto	w10m
			return

wait20m							; 20ms
			movlb	0h
			movlw	d'20'
			movwf	cnt2
w20m		call	w1m
			decfsz	cnt2,F
			goto	w20m
			return
wait50m							; 50ms
			movlb	0h
			movlw	d'50'
			movwf	cnt2
w50m		call	w1m
			decfsz	cnt2,F
			goto	w50m
			return

wait100m						; 100ms
			movlb	0h
			movlw	d'100'
			movwf	cnt2
w100m		call	w1m
			decfsz	cnt2,F
			goto	w100m
			return

wait500m						; 500ms
			movlb	0h
			movlw	05h
			movwf	cnt3
w500m		call	wait100m
			decfsz	cnt3,F
			goto	w500m
			return

wait1s							; 1s
			movlb	0h
			movlw	d'10'
			movwf	cnt3
w1s			call	wait100m
			decfsz	cnt3,F
			goto	w1s
			return

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
;			1ms 基本ウェイト
;			呼び出しを含めて1msとなる。 
;
;		clock	= 32MHz(0.03125usec)
;		1cycle	= 0.125usec
;		1ms		= 0.125usec * 8000cycles
;
;			使用変数　cnt0,cnt1
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
w1m
			movlb	0h
			movlw	08h
			movwf	cnt0		;
;			外周ループ
w1m0		movlw	0c7h		;199d
			movwf	cnt1		;
;			内周ループ
w1m1		nop					;
			nop					;5cycles*cnt1
			decfsz	cnt1,F		;2+5*198+4=996c/s
			goto	w1m1		;
;
			decfsz	cnt0,F		;
			goto	w1m0		;2+7*999+998=7993cycles
			nop
			return					;other=(3+4)cycles
									;Total 8000*0.125us=1ms
									

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
;			10us 基本ウェイト
;			呼び出し（call　w10u)も含めて、10usとなる。
;
;		clock	= 32MHZ(0.03125us)
;		1cycle	= 0.125us
;		10us	= 0.125us * 80cycles
;		使用変数　cnt0,cnt1
;		'goto','call','return'は2サイクル消費する
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

w10u
			movlb	0h
			movlw	018h		;18H=24
			movwf	cnt0		;
w10u0		decfsz	cnt0,F		;3*23+2=71
			goto	w10u0		;
			nop
			nop
			return				;2+3+71+2+2=80cycles

w05u		
			movlw	0bh			;5us=0.125us*40cycles			
			movwf	cnt0		;
w05u0		decfsz	cnt0,F		;ループ 2+3*10+2=34cycles
			goto	w05u0
			nop
			nop
			return				;2+34+2+2=40cycles=5us

w02u		
			movlw	04h			;2us=0.125us*16cycles			
			movwf	cnt0		;
w02u0		decfsz	cnt0,F		;2+3*3+2+1+2=16cycles
			goto	w02u0
			nop
			return				;
w01u
			nop					;1us=0.125us*8cycles
			nop					;2+4+2=8cycles
			nop
			nop
			return			
;
			END
			
