車速連動アンプ・ソフトウェア検証

愛車のバイクであるVFR750F(RC36)に、長距離走行中の暇つぶしアイテムである"MP3プレーヤーの搭載"と"アマチュア無線機を搭載"をする作業をノンビリと進めています。
今回は、回路上の中核であるワンチップマイコンに搭載するソフトウェアが完成したので、こちらの意図した通りの動作をきちんとしているのかを確認試験します。

前回の話

https://…/2007/11/22/ 速度連動アンプ・ソフトウェア製作その3

https://…/2007/10/27/ 速度連動アンプ・ソフトウェア製作その2

https://…/2007/10/11/ 速度連動アンプ・ソフトウェア製作その1

既にブレッドボードにはアンプ回路が組まれていますが、完全に動作させるためにはエンジン回転信号を模擬的に作り出して入力してあげなければなりません。

速度連動アンプ回路図
f:id:vfr750f2:20070815230528g:plain

残念ながら信号発振器など持っていないので、タイマーIC NE555を使用した発振回路を仮作成し、エンジン回転信号をシミュレーションします。
VFR750F(RC36)のエンジン回転レッドゾーンは11,500rpmなので、1秒あたりの回転数は

11,500 [回転/分] ÷ 60 [秒] ≒ 192 [回転/秒]

となり、さらに4ストロークエンジンのため点火パルス信号は2回転に1度(RC36のエンジンは4気筒ですが、信号盗み取りをするフューエルカットリレーは1気筒しか監視していません。)となるため、

192 [回転/秒] ÷ 2 [点火周期] = 96 [点火/秒]

となります。したがって模擬回路では 0 [Hz] ~ 100 [Hz] までの可変発振回路を製作します。

f:id:vfr750f2:20071222195252g:plain
・NE555発振回路と周波数変更ボリューム ・NE555発振回路の回路図

回路はNE555チップのデータシートに記載されているサンプルそのままで、時定数Ra,Rb,Cのみ計算しました。発振周波数f[Hz]は以下の計算式で計算します。

f [Hz] = 1.44 ÷ ( (Ra [Ω] + 2 × Rb [Ω]) × C [F])
ただし、Ra=0は禁止

手持ちの部品で賄うため、Excelで計算式を作成し、手持ちの部品の定数を片っ端から入力してツジツマが合う組合せを見つけました。結果は、電解コンデンサC=22[uF]、可変抵抗Rb=0~10[kΩ]、固定抵抗Ra=560[Ω]としてもう一度発振周波数を計算します。

可変抵抗最小値: f [Hz] = 1.44 ÷ ( (560 [Ω] + 2 × 0 [Ω]) × 0.000022 [F]) ≒ 116.8 [Hz]
可変抵抗最大値: f [Hz] = 1.44 ÷ ( (560 [Ω] + 2 × 10,000 [Ω]) × 0.000022 [F]) ≒ 3.1 [Hz]

これでなんとか希望する信号が取り出せそうです。


ワンチップマイコンPIC16F84A上で、ソフトウェアが正しく点火パルス信号を認知しているかを検証するためにソフトウェアをちょこっと変更して、現在の判定ゾーンを外部に出力するようにして、判定ゾーンに応じたLEDが光るようにしました。(ゾーンの考え方は前回の日記を見てください。)
これで、きちんとゾーンを判定しているかかんたんに目視確認できます。
音声入力にMP3プレーヤーを接続し音楽を流しっぱなしにして、スピーカー代わりにヘッドフォンも接続しました。

・ゾーン確認用LED ・MP3プレーヤー ・全体図

さあ、電源をいれます・・・


ゾーンLEDが光ります。そして模擬発振回路の発振周波数をジワジワと上げていくと、ちょっと遅れてゾーンLED表示が切り替わるとともにヘッドフォン音量も切り変わります。


すばらしい~!!大成功です。

今回実験したソフトウェアはコチラです。(まだ完成途上だからこの先変える可能性大ですけど。)
;******************************************************************************
;	PIC 16F84A 速度検知式ヘッドセットアンプ
;------------------------------------------------------------------------------
;	クロック入力	10MHz	1命令4クロック --> 0.4uS/1命令
;******************************************************************************
;
;	10MHz	周期T=1/(10*1000*1000) = 0.0000001 [S] = 0.0001 [mS] = 0.1[uS]
;	1命令4クロック --> 0.4 [uS]
;
	LIST	P=PIC16F84A
	INCLUDE	"P16F84A.INC"

	__config	_CP_OFF & _PWRTE_ON & _WDT_OFF & _HS_OSC


;======	モジュール概要 ========================================================
;	INTピン割り込み
;		ヒューエルカットリレーからのエンジン回転パルスをカウント
;	タイマー割り込み
;		1秒間隔でエンジン回転パルス数を集計しTMP_FCLASTにセット
;			0.4[uS]/1カウンタ * 256[プリスケーラ] = 102.4[uS] / 1タイマーカウント
;			102.4 [uS] * 244 [カウント] = 24985.6 [uS] ≒ 24.985[mS] ≒ 25 [mS]
;
;			1000 [mS] ÷ n = 25[mS] ..... n=40(ソフトウェア分周)
;
;	メイン処理
;		秒間エンジン回転数の変化を検知して、ボリュームセット
;		 1000rpm -->  16.6rps -->   8.3点火パルス/秒	  8
;		 2000rpm -->  33.3rps -->  16.6点火パルス/秒	 16
;		 3000rpm -->  50.0rps -->  25.0点火パルス/秒	 25
;		 4000rpm -->  66.6rps -->  33.3点火パルス/秒	 33
;		 5000rpm -->  83.3rps -->  41.6点火パルス/秒	 41
;		 6000rpm --> 100.0rps -->  50.0点火パルス/秒	 50
;		 7000rpm --> 116.6rps -->  58.3点火パルス/秒	 58
;		 8000rpm --> 133.3rps -->  66.6点火パルス/秒	 66
;		 9000rpm --> 150.0rps -->  75.0点火パルス/秒	 75
;		10000rpm --> 166.6rps -->  83.3点火パルス/秒	 83
;		11000rpm --> 183.3rps -->  91.6点火パルス/秒	 91
;		12000rpm --> 200.0rps --> 100.0点火パルス/秒	100
;
;
;======	定数定義 ==============================================================
CNT_TMR0INT	EQU	d'256'-d'244'	; タイマー0初期値
CNT_SOFTDIV	EQU	d'40'		; ソフトウェア分周比

BIT_PA_SDI	EQU	d'0'		; PGA2310ボリューム制御チップSDI端子
BIT_PA_SCLK	EQU	d'1'		; PGA2310ボリューム制御チップSCLK端子
BIT_PA_CS	EQU	d'2'		; PGA2310ボリューム制御チップ/CS端子
BIT_PA_MUTE	EQU	d'3'		; PGA2310ボリューム制御チップ/MUTE端子
BIT_PA_ZCEN	EQU	d'4'		; PGA2310ボリューム制御チップZCEN端子
BIT_PB_FCUT	EQU	d'0'		; ヒューエルカットリレー入力

BIT_PB_DB3	EQU	d'5'		;@@回転数検知部デバッグ用
BIT_PB_DB2	EQU	d'4'		;@@回転数検知部デバッグ用
BIT_PB_DB1	EQU	d'3'		;@@回転数検知部デバッグ用
BIT_PB_DB0	EQU	d'2'		;@@回転数検知部デバッグ用
BIT_PB_TMR	EQU	d'1'		;@@タイマー割込みデバッグ用


PLUSE_RPM01000	EQU	d'8'		; 01000rpm以上のパルスカウント値
PLUSE_RPM02000	EQU	d'16'		; 02000rpm以上のパルスカウント値
PLUSE_RPM03000	EQU	d'25'		; 03000rpm以上のパルスカウント値
PLUSE_RPM04000	EQU	d'33'		; 04000rpm以上のパルスカウント値
PLUSE_RPM05000	EQU	d'41'		; 05000rpm以上のパルスカウント値
PLUSE_RPM06000	EQU	d'50'		; 06000rpm以上のパルスカウント値
PLUSE_RPM07000	EQU	d'58'		; 07000rpm以上のパルスカウント値
PLUSE_RPM08000	EQU	d'66'		; 08000rpm以上のパルスカウント値
PLUSE_RPM09000	EQU	d'75'		; 09000rpm以上のパルスカウント値
PLUSE_RPM10000	EQU	d'83'		; 10000rpm以上のパルスカウント値
PLUSE_RPM11000	EQU	d'91'		; 11000rpm以上のパルスカウント値
PLUSE_RPM12000	EQU	d'100'		; 12000rpm以上のパルスカウント値

VOL_L_RPM00000	EQU	d'130'		; 01000rpm以下の時の左ボリューム
VOL_L_RPM01000	EQU	d'140'		; 01000rpm以上の時の左ボリューム
VOL_L_RPM02000	EQU	d'150'		; 02000rpm以上の時の左ボリューム
VOL_L_RPM03000	EQU	d'160'		; 03000rpm以上の時の左ボリューム
VOL_L_RPM04000	EQU	d'170'		; 04000rpm以上の時の左ボリューム
VOL_L_RPM05000	EQU	d'180'		; 05000rpm以上の時の左ボリューム
VOL_L_RPM06000	EQU	d'190'		; 06000rpm以上の時の左ボリューム
VOL_L_RPM07000	EQU	d'200'		; 07000rpm以上の時の左ボリューム
VOL_L_RPM08000	EQU	d'210'		; 08000rpm以上の時の左ボリューム
VOL_L_RPM09000	EQU	d'220'		; 09000rpm以上の時の左ボリューム
VOL_L_RPM10000	EQU	d'230'		; 10000rpm以上の時の左ボリューム
VOL_L_RPM11000	EQU	d'240'		; 11000rpm以上の時の左ボリューム
VOL_L_RPM12000	EQU	d'255'		; 12000rpm以上の時の左ボリューム

VOL_R_RPM00000	EQU	d'130'		; 01000rpm以上の時の左ボリューム
VOL_R_RPM01000	EQU	d'140'		; 01000rpm以上の時の右ボリューム
VOL_R_RPM02000	EQU	d'150'		; 02000rpm以上の時の右ボリューム
VOL_R_RPM03000	EQU	d'160'		; 03000rpm以上の時の右ボリューム
VOL_R_RPM04000	EQU	d'170'		; 04000rpm以上の時の右ボリューム
VOL_R_RPM05000	EQU	d'180'		; 05000rpm以上の時の右ボリューム
VOL_R_RPM06000	EQU	d'190'		; 06000rpm以上の時の右ボリューム
VOL_R_RPM07000	EQU	d'200'		; 07000rpm以上の時の右ボリューム
VOL_R_RPM08000	EQU	d'210'		; 08000rpm以上の時の右ボリューム
VOL_R_RPM09000	EQU	d'220'		; 09000rpm以上の時の右ボリューム
VOL_R_RPM10000	EQU	d'230'		; 10000rpm以上の時の右ボリューム
VOL_R_RPM11000	EQU	d'240'		; 11000rpm以上の時の右ボリューム
VOL_R_RPM12000	EQU	d'255'		; 12000rpm以上の時の右ボリューム


;======	レジスタマップ ========================================================
TMP_FCRELAY	EQU	0x4f		; ヒューエルカットリレーパルスカウント(INT割込みが加算)
TMP_FCLAST	EQU	0x4e		; ヒューエルカットリレー秒間パルス数(タイマー割込みがTMP_FCRELAY値をコピー)

TMP_INTW	EQU	0x3f		; 割込み処理時Wレジスタ退避
TMP_INTSTATUS	EQU	0x3e		; 割込み処理時STATUSレジスタ退避
TMP_SOFTDIV	EQU	0x3d		; ソフトウェア分周カウンタ

TMP_LASTCOMP	EQU	0x38		; [メイン処理]前回のパルスカウント値
TMP_VOL_L	EQU	0x37		; PGA2310送信ボリュームデータ(Lチャネル)
TMP_VOL_R	EQU	0x36		; PGA2310送信ボリュームデータ(Rチャネル)

TMP_LED		EQU	0x30		;@@デバッグ用


;==============================================================================
;======	ブートストラップ ======================================================
;==============================================================================
	ORG	00H			; プログラム配置アドレス指定
	GOTO	BOOTSTRAP

;==============================================================================
;======	割り込み処理 ==========================================================
;==============================================================================
	ORG	04H
INISTART
	MOVWF	TMP_INTW		; Wレジスタ待避

	MOVFW	STATUS			; STATUSレジスタ取り出し
	MOVWF	TMP_INTSTATUS		; STATUSレジスタ退避

INTCHECK1
	BTFSS	INTCON,INTF		; 割込み要因はINTピン割り込み?		1 step
	GOTO	INTCHECK2

	;======	INTピン割り込み処理 ===========================================
	BCF	INTCON,INTF		; 割込み要因をクリア			1 step
	INCF	TMP_FCRELAY,F		; パルスカウンタを加算			1 step

INTCHECK2
	BTFSS	INTCON,T0IF		; 割込み要因はタイマー割り込み?	1 step
	GOTO	INTCHECK3

	;======	タイマー割り込み処理 ==========================================
	BCF	INTCON,T0IF		; 割込み要因をクリア			1 step

	DECFSZ	TMP_SOFTDIV,F		; ソフトウェア分周値を減算
	GOTO	INT2NEXT		; 結果が0より大きいときはジャンプ

	MOVFW	TMP_FCRELAY		; パルスカウンタ値を最終カウンタ値にコピー
	MOVWF	TMP_FCLAST		; 
	CLRF	TMP_FCRELAY		; パルスカウンタをリセット

	BTFSS	TMP_LED,0		;@@Lチャネルビット0はセット?
	GOTO	DB1			;@@
	BCF	PORTB,BIT_PB_TMR	;@@
	BCF	TMP_LED,0		;@@
	GOTO	DB2			;@@
DB1	BSF	PORTB,BIT_PB_TMR	;@@
	BSF	TMP_LED,0		;@@
DB2

	MOVLW	CNT_SOFTDIV		; ソフトウェア分周値
	MOVWF	TMP_SOFTDIV		; ソフトウェア分周値をセット

INT2NEXT
					; 次のタイマーをセット
	MOVLW	CNT_TMR0INT		; タイマー初期値
	MOVWF	TMR0			; タイマー初期値をセット

INTCHECK3
	MOVFW	TMP_INTSTATUS		; STATUSレジスタ退避を取り出す
	MOVWF	STATUS			; STATUSレジスタを復帰
	MOVF	TMP_INTW,W		; Wレジスタ復帰
	RETFIE				; 割込み復帰				2 steps


;==============================================================================
;======	[サブルーチン]シリアル通信出力 ========================================
;==============================================================================
SENDVOL					; [入力] TMP_VOL_L/TMP_VOL_Rレジスタに目的のボリュームをセット
	;======	PGA2310チップセレクト信号をアサート
	BCF	PORTA,BIT_PA_CS		

	;======	RチャネルBIT7をシリアルバスに出力
	BTFSS	TMP_VOL_R,7		; Rチャネルビット7はセット?
	GOTO	R7NEG
	BSF	PORTA,BIT_PA_SDI	; シリアルバスに1を出力
	GOTO	R7END
R7NEG	BCF	PORTA,BIT_PA_SDI	; シリアルバスに0を出力
R7END
	BCF	PORTA,BIT_PA_SCLK	; クロック同期信号をアサート
	BSF	PORTA,BIT_PA_SCLK	; クロック同期信号をネゲート

	;======	RチャネルBIT6をシリアルバスに出力
	BTFSS	TMP_VOL_R,6		; Rチャネルビット6はセット?
	GOTO	R6NEG
	BSF	PORTA,BIT_PA_SDI	; シリアルバスに1を出力
	GOTO	R6END
R6NEG	BCF	PORTA,BIT_PA_SDI	; シリアルバスに0を出力
R6END
	BCF	PORTA,BIT_PA_SCLK	; クロック同期信号をアサート
	BSF	PORTA,BIT_PA_SCLK	; クロック同期信号をネゲート

	;======	RチャネルBIT5をシリアルバスに出力
	BTFSS	TMP_VOL_R,5		; Rチャネルビット5はセット?
	GOTO	R5NEG
	BSF	PORTA,BIT_PA_SDI	; シリアルバスに1を出力
	GOTO	R5END
R5NEG	BCF	PORTA,BIT_PA_SDI	; シリアルバスに0を出力
R5END
	BCF	PORTA,BIT_PA_SCLK	; クロック同期信号をアサート
	BSF	PORTA,BIT_PA_SCLK	; クロック同期信号をネゲート

	;======	RチャネルBIT4をシリアルバスに出力
	BTFSS	TMP_VOL_R,4		; Rチャネルビット4はセット?
	GOTO	R4NEG
	BSF	PORTA,BIT_PA_SDI	; シリアルバスに1を出力
	GOTO	R4END
R4NEG	BCF	PORTA,BIT_PA_SDI	; シリアルバスに0を出力
R4END
	BCF	PORTA,BIT_PA_SCLK	; クロック同期信号をアサート
	BSF	PORTA,BIT_PA_SCLK	; クロック同期信号をネゲート

	;======	RチャネルBIT3をシリアルバスに出力
	BTFSS	TMP_VOL_R,3		; Rチャネルビット3はセット?
	GOTO	R3NEG
	BSF	PORTA,BIT_PA_SDI	; シリアルバスに1を出力
	GOTO	R3END
R3NEG	BCF	PORTA,BIT_PA_SDI	; シリアルバスに0を出力
R3END
	BCF	PORTA,BIT_PA_SCLK	; クロック同期信号をアサート
	BSF	PORTA,BIT_PA_SCLK	; クロック同期信号をネゲート

	;======	RチャネルBIT2をシリアルバスに出力
	BTFSS	TMP_VOL_R,2		; Rチャネルビット2はセット?
	GOTO	R2NEG
	BSF	PORTA,BIT_PA_SDI	; シリアルバスに1を出力
	GOTO	R2END
R2NEG	BCF	PORTA,BIT_PA_SDI	; シリアルバスに0を出力
R2END
	BCF	PORTA,BIT_PA_SCLK	; クロック同期信号をアサート
	BSF	PORTA,BIT_PA_SCLK	; クロック同期信号をネゲート

	;======	RチャネルBIT1をシリアルバスに出力
	BTFSS	TMP_VOL_R,1		; Rチャネルビット1はセット?
	GOTO	R1NEG
	BSF	PORTA,BIT_PA_SDI	; シリアルバスに1を出力
	GOTO	R1END
R1NEG	BCF	PORTA,BIT_PA_SDI	; シリアルバスに0を出力
R1END
	BCF	PORTA,BIT_PA_SCLK	; クロック同期信号をアサート
	BSF	PORTA,BIT_PA_SCLK	; クロック同期信号をネゲート

	;======	RチャネルBIT0をシリアルバスに出力
	BTFSS	TMP_VOL_R,0		; Rチャネルビット0はセット?
	GOTO	R0NEG
	BSF	PORTA,BIT_PA_SDI	; シリアルバスに1を出力
	GOTO	R0END
R0NEG	BCF	PORTA,BIT_PA_SDI	; シリアルバスに0を出力
R0END
	BCF	PORTA,BIT_PA_SCLK	; クロック同期信号をアサート
	BSF	PORTA,BIT_PA_SCLK	; クロック同期信号をネゲート

	;======	LチャネルBIT7をシリアルバスに出力
	BTFSS	TMP_VOL_L,7		; Lチャネルビット7はセット?
	GOTO	L7NEG
	BSF	PORTA,BIT_PA_SDI	; シリアルバスに1を出力
	GOTO	L7END
L7NEG	BCF	PORTA,BIT_PA_SDI	; シリアルバスに0を出力
L7END
	BCF	PORTA,BIT_PA_SCLK	; クロック同期信号をアサート
	BSF	PORTA,BIT_PA_SCLK	; クロック同期信号をネゲート

	;======	LチャネルBIT6をシリアルバスに出力
	BTFSS	TMP_VOL_L,6		; Lチャネルビット6はセット?
	GOTO	L6NEG
	BSF	PORTA,BIT_PA_SDI	; シリアルバスに1を出力
	GOTO	L6END
L6NEG	BCF	PORTA,BIT_PA_SDI	; シリアルバスに0を出力
L6END
	BCF	PORTA,BIT_PA_SCLK	; クロック同期信号をアサート
	BSF	PORTA,BIT_PA_SCLK	; クロック同期信号をネゲート

	;======	LチャネルBIT5をシリアルバスに出力
	BTFSS	TMP_VOL_L,5		; Lチャネルビット5はセット?
	GOTO	L5NEG
	BSF	PORTA,BIT_PA_SDI	; シリアルバスに1を出力
	GOTO	L5END
L5NEG	BCF	PORTA,BIT_PA_SDI	; シリアルバスに0を出力
L5END
	BCF	PORTA,BIT_PA_SCLK	; クロック同期信号をアサート
	BSF	PORTA,BIT_PA_SCLK	; クロック同期信号をネゲート

	;======	LチャネルBIT4をシリアルバスに出力
	BTFSS	TMP_VOL_L,4		; Lチャネルビット4はセット?
	GOTO	L4NEG
	BSF	PORTA,BIT_PA_SDI	; シリアルバスに1を出力
	GOTO	L4END
L4NEG	BCF	PORTA,BIT_PA_SDI	; シリアルバスに0を出力
L4END
	BCF	PORTA,BIT_PA_SCLK	; クロック同期信号をアサート
	BSF	PORTA,BIT_PA_SCLK	; クロック同期信号をネゲート

	;======	LチャネルBIT3をシリアルバスに出力
	BTFSS	TMP_VOL_L,3		; Lチャネルビット3はセット?
	GOTO	L3NEG
	BSF	PORTA,BIT_PA_SDI	; シリアルバスに1を出力
	GOTO	L3END
L3NEG	BCF	PORTA,BIT_PA_SDI	; シリアルバスに0を出力
L3END
	BCF	PORTA,BIT_PA_SCLK	; クロック同期信号をアサート
	BSF	PORTA,BIT_PA_SCLK	; クロック同期信号をネゲート

	;======	LチャネルBIT2をシリアルバスに出力
	BTFSS	TMP_VOL_L,2		; Lチャネルビット2はセット?
	GOTO	L2NEG
	BSF	PORTA,BIT_PA_SDI	; シリアルバスに1を出力
	GOTO	L2END
L2NEG	BCF	PORTA,BIT_PA_SDI	; シリアルバスに0を出力
L2END
	BCF	PORTA,BIT_PA_SCLK	; クロック同期信号をアサート
	BSF	PORTA,BIT_PA_SCLK	; クロック同期信号をネゲート

	;======	LチャネルBIT1をシリアルバスに出力
	BTFSS	TMP_VOL_L,1		; Lチャネルビット1はセット?
	GOTO	L1NEG
	BSF	PORTA,BIT_PA_SDI	; シリアルバスに1を出力
	GOTO	L1END
L1NEG	BCF	PORTA,BIT_PA_SDI	; シリアルバスに0を出力
L1END
	BCF	PORTA,BIT_PA_SCLK	; クロック同期信号をアサート
	BSF	PORTA,BIT_PA_SCLK	; クロック同期信号をネゲート

	;======	LチャネルBIT0をシリアルバスに出力
	BTFSS	TMP_VOL_L,0		; Lチャネルビット0はセット?
	GOTO	L0NEG
	BSF	PORTA,BIT_PA_SDI	; シリアルバスに1を出力
	GOTO	L0END
L0NEG	BCF	PORTA,BIT_PA_SDI	; シリアルバスに0を出力
L0END
	BCF	PORTA,BIT_PA_SCLK	; クロック同期信号をアサート
	BSF	PORTA,BIT_PA_SCLK	; クロック同期信号をネゲート

	;======	PGA2310チップセレクト信号をネゲート
	BSF	PORTA,BIT_PA_CS		; 

	RETURN


;==============================================================================
;======	システム初期化処理 ====================================================
;==============================================================================
BOOTSTRAP
	;======	ページ1 =======================================================
	BSF	STATUS,RP0		; ページ1に切り替え

					; OPTION_REG
					; bit7 = /PBRU..0	ポートBプルアップ使用可否:1=不使用/0=使用
					; bit6 = INTEDG.0	割込みエッジ選択:1=立ち上がり検知/0=立下り検知
					; bit5 = T0CS...0	TMR0ソース選択:1=RA4/TOCKIより/0=内部クロック
					; bit4 = T0SE...0	TMR0ソースエッジ:1=立ち下がり検知/0=立上がり検知
					; bit3 = PSA....0	プリスケーラ使用先:1=WDT/0=TMR0
					; bit2 = PS2....1	プリスケーラレート:000..x2  011..x16 110..x128
					; bit1 = PS1....1	プリスケーラレート:001..x4  100..x32 111..x256
					; bit0 = PS0....1	プリスケーラレート:010..x8  101..x64 
	MOVLW	b'00000111'		; プリスケーラ256カウント
	MOVWF	OPTION_REG		; 

	MOVLW	b'00000000'		; ポートA入出力方向指定	1で入力
	MOVWF	TRISA			; 
	MOVLW	b'00000001'		; ポートB入出力方向指定	1で入力
	MOVWF	TRISB			; 

	;======	ページ0 =======================================================
	BCF	STATUS,RP0		; ページ0に戻す

	MOVLW	CNT_TMR0INT		; タイマー初期値
	MOVWF	TMR0			; タイマー初期値をセット
	MOVLW	CNT_SOFTDIV		; ソフトウェア分周値
	MOVWF	TMP_SOFTDIV		; ソフトウェア分周値をセット


;======	ユーザー初期化処理 ====================================================
	BCF	PORTA,BIT_PA_ZCEN	; PGA2310 ZCENネゲート
	BSF	PORTA,BIT_PA_MUTE	; PGA2310 MUTEネゲート
	BSF	PORTA,BIT_PA_CS		; PGA2310 CSネゲート
	BCF	PORTA,BIT_PA_SCLK	; PGA2310 SCLKネゲート
	BSF	PORTA,BIT_PA_SDI	; PGA2310 SDネゲート

	NOP
	NOP
	NOP
	NOP

	CLRF	TMP_LASTCOMP		; [メイン処理]前回のパルスカウント値をクリア
	CLRF	TMP_VOL_L		; PGA2310 左チャネルのボリューム値をセット
	CLRF	TMP_VOL_R		; PGA2310 右チャネルのボリューム値をセット
	CALL	SENDVOL			; PGA2310へデータ送信

	CLRF	TMP_LED			;@@
	BCF	PORTB,BIT_PB_TMR	;@@

	BCF	PORTB,BIT_PB_DB3	;@@
	BCF	PORTB,BIT_PB_DB2	;@@
	BCF	PORTB,BIT_PB_DB1	;@@
	BCF	PORTB,BIT_PB_DB0	;@@


;======	割込み許可 ============================================================
					; 割込み条件の設定
	BSF	INTCON,INTE		; INTピン割込み許可
	BSF	INTCON,T0IE		; タイマー割込み許可
	BSF	INTCON,GIE		; 全割込み許可


;==============================================================================
;======	メイン処理 ============================================================
;==============================================================================
MAIN
;	MOVLW	d'255'
;	MOVWF	TMP_VOL_L
;	MOVWF	TMP_VOL_R
;	CALL	SENDVOL
MAIN2

					; ボリュームデータの変化検出
	MOVFW	TMP_LASTCOMP		; [メイン処理]前回のパルスカウント値
	SUBWF	TMP_FCLAST,W		; パルスカウント値 - [メイン処理]前回のパルスカウント値
	BTFSC	STATUS,Z		; 結果が0以外ならスキップ
	GOTO	MAIN

	MOVFW	TMP_FCLAST		;
	MOVWF	TMP_LASTCOMP		; [メイン処理]前回のパルスカウント値を今回値に更新


	; 回転数判断 12000rpm~
RPM12000
	MOVFW	TMP_FCLAST		; パルスカウント値
	SUBLW	PLUSE_RPM12000		; リテラル - TMP_FCLAST
	BTFSC	STATUS,C		; リテラル値の方が小さい?
	GOTO	RPM11000

	MOVLW	VOL_L_RPM12000		; 左ボリュームデータをセット
	MOVWF	TMP_VOL_L		;
	MOVLW	VOL_R_RPM12000		; 右ボリュームデータをセット
	MOVWF	TMP_VOL_R		;
	CALL	SENDVOL			; PGA2310にボリュームデータを送信
	BSF	PORTB,BIT_PB_DB3	;@@
	BSF	PORTB,BIT_PB_DB2	;@@
	BCF	PORTB,BIT_PB_DB1	;@@
	BSF	PORTB,BIT_PB_DB0	;@@
	GOTO	MAIN

	; 回転数判断 11000rpm~12000rpm
RPM11000
	MOVFW	TMP_FCLAST		; パルスカウント値
	SUBLW	PLUSE_RPM11000		; リテラル - TMP_FCLAST
	BTFSC	STATUS,C		; リテラル値の方が小さい?
	GOTO	RPM10000

	MOVLW	VOL_L_RPM11000		; 左ボリュームデータをセット
	MOVWF	TMP_VOL_L		;
	MOVLW	VOL_R_RPM11000		; 右ボリュームデータをセット
	MOVWF	TMP_VOL_R		;
	CALL	SENDVOL			; PGA2310にボリュームデータを送信
	BSF	PORTB,BIT_PB_DB3	;@@
	BSF	PORTB,BIT_PB_DB2	;@@
	BCF	PORTB,BIT_PB_DB1	;@@
	BCF	PORTB,BIT_PB_DB0	;@@
	GOTO	MAIN

	; 回転数判断 10000rpm~11000rpm
RPM10000
	MOVFW	TMP_FCLAST		; パルスカウント値
	SUBLW	PLUSE_RPM10000		; リテラル - TMP_FCLAST
	BTFSC	STATUS,C		; リテラル値の方が小さい?
	GOTO	RPM09000

	MOVLW	VOL_L_RPM10000		; 左ボリュームデータをセット
	MOVWF	TMP_VOL_L		;
	MOVLW	VOL_R_RPM10000		; 右ボリュームデータをセット
	MOVWF	TMP_VOL_R		;
	CALL	SENDVOL			; PGA2310にボリュームデータを送信
	BSF	PORTB,BIT_PB_DB3	;@@
	BCF	PORTB,BIT_PB_DB2	;@@
	BSF	PORTB,BIT_PB_DB1	;@@
	BSF	PORTB,BIT_PB_DB0	;@@
	GOTO	MAIN

	; 回転数判断 09000rpm~10000rpm
RPM09000
	MOVFW	TMP_FCLAST		; パルスカウント値
	SUBLW	PLUSE_RPM09000		; リテラル - TMP_FCLAST
	BTFSC	STATUS,C		; リテラル値の方が小さい?
	GOTO	RPM08000

	MOVLW	VOL_L_RPM09000		; 左ボリュームデータをセット
	MOVWF	TMP_VOL_L		;
	MOVLW	VOL_R_RPM09000		; 右ボリュームデータをセット
	MOVWF	TMP_VOL_R		;
	CALL	SENDVOL			; PGA2310にボリュームデータを送信
	BSF	PORTB,BIT_PB_DB3	;@@
	BCF	PORTB,BIT_PB_DB2	;@@
	BSF	PORTB,BIT_PB_DB1	;@@
	BCF	PORTB,BIT_PB_DB0	;@@
	GOTO	MAIN

	; 回転数判断 08000rpm~09000rpm
RPM08000
	MOVFW	TMP_FCLAST		; パルスカウント値
	SUBLW	PLUSE_RPM08000		; リテラル - TMP_FCLAST
	BTFSC	STATUS,C		; リテラル値の方が小さい?
	GOTO	RPM07000

	MOVLW	VOL_L_RPM08000		; 左ボリュームデータをセット
	MOVWF	TMP_VOL_L		;
	MOVLW	VOL_R_RPM08000		; 右ボリュームデータをセット
	MOVWF	TMP_VOL_R		;
	CALL	SENDVOL			; PGA2310にボリュームデータを送信
	BSF	PORTB,BIT_PB_DB3	;@@
	BCF	PORTB,BIT_PB_DB2	;@@
	BCF	PORTB,BIT_PB_DB1	;@@
	BSF	PORTB,BIT_PB_DB0	;@@
	GOTO	MAIN

	; 回転数判断 07000rpm~08000rpm
RPM07000
	MOVFW	TMP_FCLAST		; パルスカウント値
	SUBLW	PLUSE_RPM07000		; リテラル - TMP_FCLAST
	BTFSC	STATUS,C		; リテラル値の方が小さい?
	GOTO	RPM06000

	MOVLW	VOL_L_RPM07000		; 左ボリュームデータをセット
	MOVWF	TMP_VOL_L		;
	MOVLW	VOL_R_RPM07000		; 右ボリュームデータをセット
	MOVWF	TMP_VOL_R		;
	CALL	SENDVOL			; PGA2310にボリュームデータを送信
	BSF	PORTB,BIT_PB_DB3	;@@
	BCF	PORTB,BIT_PB_DB2	;@@
	BCF	PORTB,BIT_PB_DB1	;@@
	BCF	PORTB,BIT_PB_DB0	;@@
	GOTO	MAIN

	; 回転数判断 06000rpm~07000rpm
RPM06000
	MOVFW	TMP_FCLAST		; パルスカウント値
	SUBLW	PLUSE_RPM06000		; リテラル - TMP_FCLAST
	BTFSC	STATUS,C		; リテラル値の方が小さい?
	GOTO	RPM05000

	MOVLW	VOL_L_RPM06000		; 左ボリュームデータをセット
	MOVWF	TMP_VOL_L		;
	MOVLW	VOL_R_RPM06000		; 右ボリュームデータをセット
	MOVWF	TMP_VOL_R		;
	CALL	SENDVOL			; PGA2310にボリュームデータを送信
	BCF	PORTB,BIT_PB_DB3	;@@
	BSF	PORTB,BIT_PB_DB2	;@@
	BSF	PORTB,BIT_PB_DB1	;@@
	BSF	PORTB,BIT_PB_DB0	;@@
	GOTO	MAIN

	; 回転数判断 05000rpm~06000rpm
RPM05000
	MOVFW	TMP_FCLAST		; パルスカウント値
	SUBLW	PLUSE_RPM05000		; リテラル - TMP_FCLAST
	BTFSC	STATUS,C		; リテラル値の方が小さい?
	GOTO	RPM04000

	MOVLW	VOL_L_RPM05000		; 左ボリュームデータをセット
	MOVWF	TMP_VOL_L		;
	MOVLW	VOL_R_RPM05000		; 右ボリュームデータをセット
	MOVWF	TMP_VOL_R		;
	CALL	SENDVOL			; PGA2310にボリュームデータを送信
	BCF	PORTB,BIT_PB_DB3	;@@
	BSF	PORTB,BIT_PB_DB2	;@@
	BSF	PORTB,BIT_PB_DB1	;@@
	BCF	PORTB,BIT_PB_DB0	;@@
	GOTO	MAIN

	; 回転数判断 04000rpm~05000rpm
RPM04000
	MOVFW	TMP_FCLAST		; パルスカウント値
	SUBLW	PLUSE_RPM04000		; リテラル - TMP_FCLAST
	BTFSC	STATUS,C		; リテラル値の方が小さい?
	GOTO	RPM03000

	MOVLW	VOL_L_RPM04000		; 左ボリュームデータをセット
	MOVWF	TMP_VOL_L		;
	MOVLW	VOL_R_RPM04000		; 右ボリュームデータをセット
	MOVWF	TMP_VOL_R		;
	CALL	SENDVOL			; PGA2310にボリュームデータを送信
	BCF	PORTB,BIT_PB_DB3	;@@
	BSF	PORTB,BIT_PB_DB2	;@@
	BCF	PORTB,BIT_PB_DB1	;@@
	BSF	PORTB,BIT_PB_DB0	;@@
	GOTO	MAIN

	; 回転数判断 03000rpm~04000rpm
RPM03000
	MOVFW	TMP_FCLAST		; パルスカウント値
	SUBLW	PLUSE_RPM03000		; リテラル - TMP_FCLAST
	BTFSC	STATUS,C		; リテラル値の方が小さい?
	GOTO	RPM02000

	MOVLW	VOL_L_RPM03000		; 左ボリュームデータをセット
	MOVWF	TMP_VOL_L		;
	MOVLW	VOL_R_RPM03000		; 右ボリュームデータをセット
	MOVWF	TMP_VOL_R		;
	CALL	SENDVOL			; PGA2310にボリュームデータを送信
	BCF	PORTB,BIT_PB_DB3	;@@
	BSF	PORTB,BIT_PB_DB2	;@@
	BCF	PORTB,BIT_PB_DB1	;@@
	BCF	PORTB,BIT_PB_DB0	;@@
	GOTO	MAIN

	; 回転数判断 02000rpm~03000rpm
RPM02000
	MOVFW	TMP_FCLAST		; パルスカウント値
	SUBLW	PLUSE_RPM02000		; リテラル - TMP_FCLAST
	BTFSC	STATUS,C		; リテラル値の方が小さい?
	GOTO	RPM01000

	MOVLW	VOL_L_RPM02000		; 左ボリュームデータをセット
	MOVWF	TMP_VOL_L		;
	MOVLW	VOL_R_RPM02000		; 右ボリュームデータをセット
	MOVWF	TMP_VOL_R		;
	CALL	SENDVOL			; PGA2310にボリュームデータを送信
	BCF	PORTB,BIT_PB_DB3	;@@
	BCF	PORTB,BIT_PB_DB2	;@@
	BSF	PORTB,BIT_PB_DB1	;@@
	BSF	PORTB,BIT_PB_DB0	;@@
	GOTO	MAIN

	; 回転数判断 01000rpm~02000rpm
RPM01000
	MOVFW	TMP_FCLAST		; パルスカウント値
	SUBLW	PLUSE_RPM01000		; リテラル - TMP_FCLAST
	BTFSC	STATUS,C		; リテラル値の方が小さい?
	GOTO	RPM00000

	MOVLW	VOL_L_RPM01000		; 左ボリュームデータをセット
	MOVWF	TMP_VOL_L		;
	MOVLW	VOL_R_RPM01000		; 右ボリュームデータをセット
	MOVWF	TMP_VOL_R		;
	CALL	SENDVOL			; PGA2310にボリュームデータを送信
	BCF	PORTB,BIT_PB_DB3	;@@
	BCF	PORTB,BIT_PB_DB2	;@@
	BSF	PORTB,BIT_PB_DB1	;@@
	BCF	PORTB,BIT_PB_DB0	;@@
	GOTO	MAIN

	; 回転数判断 ~01000rpm
RPM00000
	MOVLW	VOL_L_RPM00000		; 左ボリュームデータをセット
	MOVWF	TMP_VOL_L		;
	MOVLW	VOL_R_RPM00000		; 右ボリュームデータをセット
	MOVWF	TMP_VOL_R		;
	CALL	SENDVOL			; PGA2310にボリュームデータを送信
	BCF	PORTB,BIT_PB_DB3	;@@
	BCF	PORTB,BIT_PB_DB2	;@@
	BCF	PORTB,BIT_PB_DB1	;@@
	BSF	PORTB,BIT_PB_DB0	;@@
	GOTO	MAIN


	END
;*end*

ただし、デジタル回路のノイズがアナログ回路に回りこんで音質がイマイチだなぁ・・・