;排気管バルブテスト Ver 2.0		bitメカ工房		2010-08-20(金)
;
;[プログラム概要]
; ･オートバイの自作排気管バルブをラジコンサーボにて､
;　　｢スロットル開度｣により自動開閉及び開度表示するプログラム｡
;
; ･押しボタンによる手動開閉テストがうまく出来たので､第2段階テストとして
;　それを利用した自動開閉を行ってみる｡
;　押しボタンは無効とする｡
;
; ･7セグメントLED【カソードコモン(GND共通)】で表示する｡
; ･設定開度は5ﾟ刻みとする｡(0､5､10､15､20､25､30､35…90)
; ･2桁表示とするが､ダイナミック点灯は使用せず､通常点灯とする｡
; ･1桁目は｢0｣または｢5｣のどちらかなので､1ピン信号で切替表示するように､
;　　米粒6ピンPICで作成する｡
;
; 2桁目のLED配置
;
;	　　Ａ		     - E C D B G A F
;	　　─		rb,# X X X X X X X X b
;	Ｆ│Ｇ│Ｂ	
;	　　─		0/   0 1 1 1 1 0 1 1
;	Ｅ│　│Ｃ	1/   0 0 1 0 1 0 0 0
;	　　─　	2/   0 1 0 1 1 1 1 0
;	　　Ｄ		3/   0 0 1 1 1 1 1 0
;			4/   0 0 1 0 1 1 0 1
;			5/   0 0 1 1 0 1 1 1
;			6/   0 1 1 1 0 1 1 1
;			7/   0 0 1 0 1 0 1 1
;			8/   0 1 1 1 1 1 1 1
;			9/   0 0 1 1 1 1 1 1
;
;
;・4MHzの水晶発信器を使用する｡(1命令時間は1/4000000x4=0.000001秒)
;
;	　 　1.5ms(±0.5ms)	　 1.5ms(±0.5ms)
;	　　 ←→		　 ←→
;　5V	　　┌―┐		　┌―┐
;	　　｜　｜		　｜　｜
;	　　｜　｜		　｜　｜
;　0V ―――┘　└――――――――┘　└――――
;	　　 ←　　　　19ms　　　→
;　tmr1	↑10｜	　　　64　　　↑10｜　　　　64
;	ｽﾛｯﾄﾙ開度ﾁｪｯｸ(A/D)　　ｽﾛｯﾄﾙ開度ﾁｪｯｸ(A/D)
;
;　サーボの1山信号タイミングの少し前にスロットル開度チェックを行う｡
;　参考…A/D変換時間が50μSとしても､タイマー1の1カウント時間(256μS)内である｡
;
;・タイマー1(16bit)のオーバーフローで1パルス周期19ms(0.019秒)をカウントする｡
;　インターネットで検索すると､周期が短いほどトルクがアップするようだが､
;　フタバサーボの実測値(19ms)が掲載されていたので､それを使用することにする｡
;　1/4000000x4x256x【74】=0.018944秒(プリスケールは｢1｣)
;
;・パルス1山時間(1～2mS)はタイマー0でカウントする｡
;　プリスケールを｢8｣とすると､【1.5ms】の場合187.5回になる｡
;　ニュートラルを【187】とする｡
;　1/4000000*4*8*187=0.001496秒
;
;
;[PIC選定その他仕様]
; ･PIC16F88-I/P使用｡(秋月電子通商で230円/個)
;			     ┌─┰─┐
;	サーボ信号	 RA2 ┥	     ┝ RA1	ボタン右
;	ｽﾛｯﾄﾙ開度A/D	 RA3 ┥	     ┝ RA0	ボタン左
;	(未使用)	 RA4 ┥	     ┝ RA7	水晶発信器
;	(未使用)	 RA5 ┥PIC   ┝ RA6	(未使用)
;			 Vss ┥ 16F88┝ Vdd	5.0V
;	7LED_F		 RB0 ┥	     ┝ RB7	7LED_1桁目_ON･OFF
;	7LED_A		 RB1 ┥	     ┝ RB6	7LED_E
;	7LED_G		 RB2 ┥	     ┝ RB5	7LED_C
;	7LED_B		 RB3 ┥	     ┝ RB4	7LED_D
;			     └───┘
;
;[プログラムの基本流れ概要]
;
;　　	16.4msタイミングを待つ
;	↓
;	スロットル開度チェック
;	サーボ信号の1山時間設定及び7LCD角度表示
;	↓
;　　	2.6msタイミングを待つ
;	↓
;　　↑	サーボ信号の1山時間送信
;　　└ リターン
;
;
;[凡例] (自分で分かりやすいように目印を付ける)
; mXXX:メモリー  rXXX:ラベル  sXXX:サブルーチン  vXXX:変数  ★:調整箇所など
;
;-------PICコンフィギュレーション設定---;(CVASM16アセンブラ用記述)

	include	'16f88.inc'

	fuses	_cp_off			;　コードプロテクト→無効
	fuses	_ccp1_rb2		;　PWMピン選定(_rb0or_rb3)
;	fuses	_ccp1_rb3		;　PWMピン選定(_rb0or_rb3)
	fuses	_debug_off		;　インサーキットデバックモード→無効
	fuses	_wrt_enable_off		;　eeconのFlashメモリ可能→しない
	fuses	_cpd_off		;　eepromのコードプロテクト→無効
	fuses	_lvp_off		;　低電圧プログミング(5V)→無効
	fuses	_boden_off		;　低電圧リセット(約4V以下)→無効
	fuses	_mclr_off		;　MCLR端子(リセット)→設定しない
	fuses	_pwrte_on		;　電源投入72ms間リセット→有効
	fuses	_wdt_off		;　ウォッチドックタイマー→無効
	fuses	_extclk			;　オシレーター設定→外部発信

;	fuses	_ieso_off		;　内部/外部スイッチオーバーモード？
;	fuses	_fcmen_off		;　フェイルセーフクロックモニター？

;　★★★↑cvasm16+PICkit2では手動設定修正必要あり！★★★

	id	'0203'			;Ver2.03

;-------プログラムメモリー割当----------;

mSERVO		=	20h		;
mAD_THR		=	21h		;


;=======プログラム初期設定==============;

	clr	ra			;
	clr	rb			;

;(Bank 0)
	mov	t1con,#00000001b	;bit7…設定項目無し
					;bit6…0 オシレーター選択
					;bit5～4…プリスケールレート【1】
					;bit3…1 タイマー1オシレーター制御
					;bit2…0 外部クロック同期
					;bit1…0 タイマー1クロックソース選択
					;bit0…1 タイマー1オン

	mov	adcon0,#11011001b	;A/D設定(Channel 3 (RA3/AN3))

	setb	rp0			;ページ変更(Bank 1へ)

;(Bank 1)
	mov	option_reg,#00000010b	;bit7…0 RBプルアップ【無】
					;bit6…割り込みエッジ
					;bit5…0 タイマー0は内蔵クロック使用
					;bit4…タイマー0エッジ
					;bit3…プリスケーラはタイマー0へ割当
					;bit2～0…プリスケールレート【8】

	mov	trisa,#11111011b	;RAの入出力ピン設定
	mov	trisb,#00000000b	;RBの入出力ピン設定
	mov	ansel,#00001000b	;RA3ピン以外はデジタルピンに設定
;	mov	adcon1,#00000000b	;A/D設定(初期設定のままでOK)

	clrb	rp0			;ページ変更(Bank 0へ戻す)


	clr	tmr1l			;
	clrb	tmr1if			;


;電源ON時にｽﾛｯﾄﾙ開度10%以上なら全開固定とする｡
;　スロットル開度チェック
	nop				;A/D充電20μs必要
	nop				;
	nop				;
	nop				;
	nop				;
	nop				;
	nop				;
	nop				;
	nop				;
	nop				;
	nop				;
	nop				;
	nop				;
	nop				;
	nop				;
	nop				;
	nop				;
	nop				;
	nop				;
	nop				;
	setb	go_done			;A/D変換開始
	jb	go_done,$		;A/D変換終了(bit0)まで待つ
	cjae	adresh,#39,rFULL	;

;---------------------------------------;


;サーボ長周期(19ms) 74の内64分を設定
	mov	tmr1h,#192		;256-64=192


;↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓ ;
;***[ メインループ ]********************;

rREPEAT

;16.4ms待ち-----------------------------;
;タイマー1で0.0164秒待つ

	jnb	tmr1if,$		;オーバーフローを待つ
	clrb	tmr1if			;

;サーボ長周期(19ms) 74の内10分を設定
	mov	tmr1h,#246		;256-10=246


;スロットル開度チェック-----------------;

	setb	go_done			;A/D変換開始
	jb	go_done,$		;A/D変換終了(bit0)まで待つ

	mov	mAD_THR,adresh		;

	jmp	rTHROTTL		;スロットル変換テーブルへ
rRETURN

;2.6ms待ち------------------------------;
;タイマー1で0.0026秒待つ

	jnb	tmr1if,$		;オーバーフローを待つ
	clrb	tmr1if			;


;サーボ長周期(19ms) 74の内64分を設定
	mov	tmr1h,#192		;256-64=192


;パルス1山信号--------------------------;
	setb	ra.2			;パルス1山信号 ON

;タイマー0で待つ(1カウントは0.000008秒)

	clr	tmr0			;
	cjbe	tmr0,mSERVO,$		;★時間までここで待つ

	clrb	ra.2			;パルス1山信号 OFF

;---------------------------------------;

	jmp	rREPEAT			;


;***[ メインループここまで ]************;
;↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑ ;



;---------------------------------------;
;*** A/D→ｽﾛｯﾄﾙ開度変換ﾃｰﾌﾞﾙと7LED表示 ***
;---------------------------------------;
rTHROTTL
	cja	mAD_THR,#28,rNEXT85	;A/D値【28】=【4%】以下
	mov	mSERVO,#246		;90ﾟ
	mov	rb,#00111111b		;7LED ｢90｣表示
	jmp	rRETURN			;
rNEXT85
	cja	mAD_THR,#35,rNEXT80	;A/D値【35】=【8%】以下
	mov	mSERVO,#239		;85ﾟ
	mov	rb,#11111111b		;7LED ｢85｣表示
	jmp	rRETURN			;
rNEXT80
	cja	mAD_THR,#42,rNEXT75	;A/D値【42】=【12%】以下
	mov	mSERVO,#233		;80ﾟ
	mov	rb,#01111111b		;7LED ｢80｣表示
	jmp	rRETURN			;
rNEXT75
	cja	mAD_THR,#50,rNEXT70	;A/D値【50】=【16%】以下
	mov	mSERVO,#226		;75ﾟ
	mov	rb,#10101011b		;7LED ｢75｣表示
	jmp	rRETURN			;
rNEXT70
	cja	mAD_THR,#57,rNEXT65	;A/D値【57】=【20%】以下
	mov	mSERVO,#220		;70ﾟ
	mov	rb,#00101011b		;7LED ｢70｣表示
	jmp	rRETURN			;
rNEXT65
	cja	mAD_THR,#64,rNEXT60	;A/D値【64】=【24%】以下
	mov	mSERVO,#213		;65ﾟ
	mov	rb,#11110111b		;7LED ｢65｣表示
	jmp	rRETURN			;
rNEXT60
	cja	mAD_THR,#72,rNEXT55	;A/D値【72】=【28%】以下
	mov	mSERVO,#207		;60ﾟ
	mov	rb,#01110111b		;7LED ｢60｣表示
	jmp	rRETURN			;
rNEXT55
	cja	mAD_THR,#79,rNEXT50	;A/D値【79】=【32%】以下
	mov	mSERVO,#200		;55ﾟ
	mov	rb,#10110111b		;7LED ｢55｣表示
	jmp	rRETURN			;
rNEXT50
	cja	mAD_THR,#86,rNEXT45	;A/D値【86】=【36%】以下
	mov	mSERVO,#194		;50ﾟ
	mov	rb,#00110111b		;7LED ｢50｣表示
	jmp	rRETURN			;
rNEXT45
	cja	mAD_THR,#94,rNEXT40	;A/D値【94】=【40%】以下
	mov	mSERVO,#187		;45ﾟ
	mov	rb,#10101101b		;7LED ｢45｣表示
	jmp	rRETURN			;
rNEXT40
	cja	mAD_THR,#101,rNEXT35	;A/D値【101】=【44%】以下
	mov	mSERVO,#180		;40ﾟ
	mov	rb,#00101101b		;7LED ｢40｣表示
	jmp	rRETURN			;
rNEXT35
	cja	mAD_THR,#109,rNEXT30	;A/D値【109】=【48%】以下
	mov	mSERVO,#174		;35ﾟ
	mov	rb,#10111110b		;7LED ｢35｣表示
	jmp	rRETURN			;
rNEXT30
	cja	mAD_THR,#116,rNEXT25	;A/D値【116】=【52%】以下
	mov	mSERVO,#167		;30ﾟ
	mov	rb,#00111110b		;7LED ｢30｣表示
	jmp	rRETURN			;
rNEXT25
	cja	mAD_THR,#123,rNEXT20	;A/D値【123】=【56%】以下
	mov	mSERVO,#161		;25ﾟ
	mov	rb,#11011110b		;7LED ｢25｣表示
	jmp	rRETURN			;
rNEXT20
	cja	mAD_THR,#131,rNEXT15	;A/D値【131】=【60%】以下
	mov	mSERVO,#154		;20ﾟ
	mov	rb,#01011110b		;7LED ｢20｣表示
	jmp	rRETURN			;
rNEXT15
	cja	mAD_THR,#149,rNEXT10	;A/D値【149】=【70%】以下
	mov	mSERVO,#148		;15ﾟ
	mov	rb,#10101000b		;7LED ｢15｣表示
	jmp	rRETURN			;
rNEXT10
	cja	mAD_THR,#167,rNEXT05	;A/D値【167】=【80%】以下
	mov	mSERVO,#141		;10ﾟ
	mov	rb,#00101000b		;7LED ｢10｣表示
	jmp	rRETURN			;
rNEXT05
	cja	mAD_THR,#186,rNEXT00	;A/D値【186】=【90%】以下
	mov	mSERVO,#135		;05ﾟ
	mov	rb,#10000000b		;7LED ｢ 5｣表示
	jmp	rRETURN			;
rNEXT00
	mov	mSERVO,#128		;00ﾟ
	mov	rb,#00000000b		;7LED ｢ 0｣表示
	jmp	rRETURN			;


;---------------------------------------;
;*** 強制全開固定モード ***
;---------------------------------------;
rFULL
;　サーボ長周期(19ms) 74を設定
	mov	tmr1h,#182		;256-74=182
;	mov	rb,#00000000b		;7LED ｢ 0｣表示


rREPE_F
;19ms待ち-------------------------------;
;　タイマー1で0.019秒待つ
	jnb	tmr1if,$		;オーバーフローを待つ
	clrb	tmr1if			;

;　サーボ長周期(19ms) 74を設定
	mov	tmr1h,#182		;256-74=182

;パルス1山信号--------------------------;
	setb	ra.2			;パルス1山信号 ON
;　タイマー0で待つ(1カウントは0.000008秒)
	clr	tmr0			;
	cjbe	tmr0,#128,$		;★時間までここで待つ
	clrb	ra.2			;パルス1山信号 OFF

	jmp	rREPE_F			;

;---------------------------------------;
;---------------------------------------;



;-------PIC16F88初期状態確認(参考)------;(△:変更必要)
;Bank 0
;	tmr0		xxxxxxxx	;　タイマー0の状態
;	status		00011xxx	;　Bankセレクト設定､各旗の状態
;	porta		xxx00000	;△RAピン出力状態(xは不定)
;	portb		00xxxxxx	;△RBピン出力状態(xは不定)
;	intcon		0000000x	;△割り込み他､設定
;	pir1		-0000000	;　旗状態(A/D､タイマー､
;	pir2		00-0----	;　EEメモリー､他)
;	tmr1l		xxxxxxxx	;　タイマー1下位8bitの状態
;	tmr1h		xxxxxxxx	;　タイマー1上位8bitの状態
;	t1con		--000000	;△タイマー1コントロール関係設定
;	tmr2		00000000	;　タイマー2の状態
;	t2con		-0000000	;　タイマー2コントロール関係設定
;	sspbuf		xxxxxxxx	;　装置内通信SPI通信機能
;	sspcon		00000000	;　
;	ccpr1l		xxxxxxxx	;　
;	ccpr1h		xxxxxxxx	;　
;	ccp1con		--000000	;　キャプチャ/コンペア/PWM
;	adresh		xxxxxxxx	;　A/D変換値9､10bit？
;	adcon0		000000-0	;　A/Dコントロール関係設定
;Bank 1
;	option_reg	11111111	;△プルアップ､プリスケーラー比率他､設定
;	trisa		11111111	;△RAピンI/O制御設定(1は入力)
;	trisb		11111111	;△RBピンI/O制御設定(1は入力)
;	pie1		-0--0000	;　A/D､CCP､タイマー､EEメモリーの
;	pie2		---0----	;　割り込み使用するしない設定
;	pcon		------qq	;　パワーオン､低電圧リセットの？
;	osccon		-000-0--	;　内部RCオシレーター周波数設定
;	osctune		--000000	;　内蔵RCオシレーター微調整
;	pr2		11111111	;　
;	sspadd		00000000	;　
;	sspstat		00000000	;　
;	txsta		0000-010	;　
;	spbrg		00000000	;　
;	ansel		-1111111	;△アナログorデジタルI/O設定
;	cmcon		00000111	;　
;	cvrcon		000-0000	;　
;	adresl		xxxxxxxx	;　A/D変換値0～8bit
;	adcon1		0000----	;　A/Dコントロール関係設定
;Bank 2
;	wdtcon		---01000	;△ウォッチドックタイマー分周
;	eedata		xxxxxxxx	;　EEメモリーの状態 Lo？
;	eeadr		xxxxxxxx	;　EEメモリーのアドレス位置 Lo
;	eedath		--xxxxxx	;　EEメモリーの状態 Hi？
;	eeadrh		-----xxx	;　EEメモリーのアドレス位置 Hi
;Bank 3
;	eecon1		x--xx000	;　EEメモリー関係設定
;	eecon2		--------	;　EEメモリー関係設定？

