;距離記録計補助用の100mカウンター		bitメカ工房	2017-07-15(土)
;
;*****************************************************************************
;*
;* 12F6xx.incファイルのEEPROM記述が変だ！記述の修正書き換え必要！            *
;*
;*****************************************************************************
;
;メーターVer2をそのまま流用使用する｡
; (GP3(未使用)はタイヤ異径選択切換用に使おうと考えていて基盤配線していたが､
;　現在は異径タイヤに取替えることはないので､面倒なソフトは組み込まない｡
;　GP3は入力ピンに設定｡)
;
;[プログラム概要]
;・ディスクブレーキ板アームの近接スイッチ信号により100mを算出し､100mごとの信号
;　を上位のPICへ送る｡
;
;(参考)
;・180km/hの速度で､タイヤ径を0.696m､9本アームの場合→ 0.004859秒/パルス
;　ON･OFFだと0.002429秒/パルスとなる｡
;　PICの1命令時間は4MHzの場合､0.000001秒(1/4000000x4)
;　アームの有無間で2000命令以上入れても問題無い｡
;・電源ON時のチャタリングと思われるカウントアップ防止として､
;　約1msのウエイトを入れてみる｡
;　タイマー0のプリスケーラを【 4 】にした場合のオーバーフロータイム
;　4Hz動作として､1/4000000x4x256x[4]=0.001024秒 (4はプリスケーラ値)
;
;・上位PICがEEPROM書込動作中だった場合､1桁10ms程度かかるので､最大17桁連続書込
;　の場合､0.17秒通信信号が途絶えると考えておく｡
;　なお､100m進む時間は､180km/hの速度だとしても2秒かかる｡
;
;・回転カウンター値｢mCOUNT_L｣について
;　ピレリーMT-21タイヤ半径【348】mm
;　100m÷(348x2xπ/1000x9)=411.6→412カウントで100m
;　412-256=【156】→当初実測補正して【416】カウントの【160】であった｡
;
;・タイマー1のプリスケーラを【 8 】にした場合のオーバーフロータイム
;　4Hz動作として､1/4000000x4x256x256x[8]=0.524288秒 (8はプリスケーラ値)
;　エラーチェックに使用する｡
;
;・極たまーにだが､キーONで暴走することがある｡停止状態で距離数が高速で
;　カウントアップする｡電源ON時のチャタリングだと思うが､ウォッチドックタイマー
;　を使用してみる｡
;　ウォッチドッグタイマーは何も設定しなければ約20msらしいのでそのまま使用する｡
;　　↓
;　ところが再び発生した｡今度は低電圧リセットを設定したところ大丈夫ようだ｡
;
;・自作メーター2に組み込むに当たり､
;　100mごとにLEDを一瞬点灯させるのを止める｡(薄暗くなると目障りになる)
;
;[PIC選定その他仕様]
; ･PIC12F675-I/P使用｡
; ･動作速度は内蔵4MHz固定｡
; ･MCLRは内部接続モードとする｡
;
;			    ┌─┰─┐
; 5V			VDD ┥      ┝ Vss	GND
; 回転センサー信号	GP5 ┥12F   ┝ GP0	100m記録ボタン
; 上位PIC通信		GP4 ┥  675 ┝ GP1	LED
; (未使用)		GP3 ┥	    ┝ GP2	ゼロリセット(プルアップ)
;			    └───┘
;
;[プログラムの流れ概要]
;
;　電源ON
;	↓
;　100m設定実走記録ボタンONか？→YES 設定モードへジャンプ
;	↓
;　EEPROMを読み出して通常メモリーへコピーする
;	↓
;　<<カウンターリセット割込開始>>
;	↓
;	↓←←←←←←←←←←←←←←←←←←←┐
;	↓					↑
;　回転センサー信号ONまで待つ			↑
;	↓					↑
;　回転センサー信号OFFまで待つ			↑
;	↓					↑
;　カウンターLを+1する				↑
;	↓					↑
;　オーバーフローチェック			↑
;	↓					↑
;　設定カウントか？→NO →→→→→→→→→→→→↑
;	↓YES					↑
;　上位PICへ送信				↑
;	↓					↑
;	└→→→→→→→→→→→→→→→→→→→┘
;
;[凡例] (自分で分かりやすいように目印を付ける)
; mXXX:メモリー  rXXX:ラベル  sXXX:サブルーチン  vXXX:変数  ★:調整箇所など
;
;-------PICコンフィギュレーション設定---;(CVASM16アセンブラ用記述)

	include	'12f675.inc'

	fuses	_cpd_off		;eepromのコードプロテクト→無効
	fuses	_cp_off			;コードプロテクト→無効
	fuses	_boden_on		;☆低電圧リセット(約2V以下)→有り
	fuses	_mclre_off		;MCLR端子(リセット)→設定しない
	fuses	_pwrte_on		;電源投入72ms間リセット→有効
	fuses	_wdt_on			;▼ウォッチドックタイマー→有効
	fuses	_intrc_osc_noclkout	;オシレーター設定→内蔵､外部へ出力無し

	id	'0301'			;Ver1.10

;-------プログラムメモリー割当----------;(メモリーは20hから)

mTIRE		=	20h		;カウンター｢L｣設定値
mCOUNT_L	=	21h		;下8bitカウント用
mCOUNT_H	=	22h		;キャリーカウント用


;---EEPROM値強制設定--------------------;(PIC書込時のみ)

	eeorg	0			;
	eedata	192			;★(ｶﾙｰ3 予想値)


;=======プログラム開始==================;

	org	0			;
	jmp	rSTART			;


;iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii;
;---ﾘｾｯﾄ時(GP2釦ｶｳﾝﾀｰｾﾞﾛｸﾘｱ)割り込み---
;iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii;

	org	4			;

	clrb	intf			;gp2_INT割込旗解除

	clr	mCOUNT_L		;
	clr	mCOUNT_H		;

	setb	rp0			;ページ変更(Bank 1へ)
	clrb	trisio.4		;出力ピンに変更(上位PIC通信)
	clrb	rp0			;ページ変更(Bank 0へ戻す)
rWEIT
	clr	wdt			;▼
	jnb	gpio.2,rWEIT		;ボタンを離すまで待つ

	reti				;

;iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii;


rSTART
;=======プログラム初期設定==============;
;Bank 0
	clr	gpio			;
	mov	t1con,#00110001b	;プリスケール1:8
	mov	cmcon,#00000111b	;コンパレーターOFF
;Bank 1
	setb	rp0			;ページ変更(Bank 1へ)
	mov	option_reg,#00000001b	;プルアップ､プリスケーラ他
	mov	trisio,#  101101b	;入出力ピン設定
	mov	wpu,#00000100b		;プルアップ有効ピン設定
	mov	ansel,#00000000b	;
	clrb	rp0			;ページ変更(Bank 0へ戻す)

	clr	wdt			;▼


;---------------------------------------;
;100mEEPROMカウント再設定チェック

	jnb	gpio.0,rEEP100		;記録開始するか？ボタン押しチェック


;---------------------------------------;
;電源ON時にEEPROM読み出して通常メモリーへコピーする｡
rSTART_X
	setb	rp0			;ページ変更(Bank 1へ)
	mov	eeadr,#0		;アドレスセット
	setb	rd			;Read Control bit
	mov	w,eedata		;
	clrb	rp0			;ページ変更(Bank 0へ)
	mov	mTIRE,w			;

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

	clr	mCOUNT_L		;
	clr	mCOUNT_H		;キャリーカウント用

	mov	intcon,#11010000b	;割り込み設定


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

rREPEAT
rS_CHK0
	clr	wdt			;▼
	jnb	mCOUNT_H.7,rS_CHK1	;ジャンプノットビット次行
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>;
	call	sP_CHK			;上位PIC通信
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<;
rS_CHK1
	jnb	gpio.5,rS_CHK0		;回転センサー信号｢出る｣まで待つ

	clr	tmr0			;電源ON時のチャタリングカウントアップ
	clrb	t0if			;対策として､ウエイトを入れてみる｡
	jnb	t0if,$			;

rS_CHK2
	clr	wdt			;▼
	jnb	mCOUNT_H.7,rS_CHK3	;ジャンプノットビット次行
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>;
	call	sP_CHK			;上位PIC通信
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<;
rS_CHK3
	jb	gpio.5,rS_CHK2		;回転センサー信号｢消える｣まで待つ

	clr	tmr0			;電源ON時のチャタリングカウントアップ
	clrb	t0if			;対策として､ウエイトを入れてみる｡
	jnb	t0if,$			;

	add	mCOUNT_L,#1		;+1(incはキャリー付かないのでダメ)
	snc				;スキップノットキャリー
	setb	mCOUNT_H.0		;#00000001b

	jnb	mCOUNT_H.0,rREPEAT	;mCOUNT_Lが256回を超えたか？
	cjb	mCOUNT_L,mTIRE,rREPEAT	;設定値未満か？


;100mカウントに達した場合上位PICへ送信ON
	setb	rp0			;ページ変更(Bank 1へ)
	setb	trisio.4		;入力ピンに変更
	clrb	rp0			;ページ変更(Bank 0へ戻す)

	clr	mCOUNT_L		;
	mov	mCOUNT_H,#10000000b	;上位PIC通信確認用

	clr	tmr1l			;タイマー1 下位8bit
	clr	tmr1h			;タイマー1 上位8bit
	clrb	tmr1if			; 〃　通信エラー確認用

;	setb	gpio.1			;★LED

	jmp	rREPEAT			;


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



;---------------------------------------
;*** 100mカウントEEPROM書き込み ***
;---------------------------------------
rEEP100
	setb	gpio.1			;★LED
rEE_WDT0
	clr	wdt			;▼
	jnb	gpio.0,rEE_WDT0		;ボタン離すまで待つ

;　チャタリング防止　約0.5秒
	clr	tmr1l			;タイマー1 下位8bit
	clr	tmr1h			;タイマー1 上位8bit
	clrb	tmr1if			;
rEE_WDT1
	clr	wdt			;▼
	jnb	tmr1if,rEE_WDT1		;

;　回転カウンタークリア
	clr	mCOUNT_L		;
	clr	mCOUNT_H		;キャリーカウント用

;　現在の回転センサーアーム位置チェック
	jb	gpio.5,rBB_CHK0		;｢ON｣で+1するか｢OFF｣で+1するかの分岐


;回転センサーアーム信号｢ON｣の場合…次ONで+1
rBA_CHK0
	clr	wdt			;▼
	jnb	gpio.0,r100_CHK		;記録ボタン押しチェック
	jnb	gpio.5,rBA_CHK0		;回転センサー信号出るまで待つ

	clr	tmr0			;電源ON時のチャタリングカウントアップ
	clrb	t0if			;対策として､ウエイトを入れてみる｡
	jnb	t0if,$			;

rBA_CHK1
	clr	wdt			;▼
	jnb	gpio.0,r100_CHK		;記録ボタン押しチェック
	jb	gpio.5,rBA_CHK1		;回転センサー信号消えるまで待つ

	clr	tmr0			;電源ON時のチャタリングカウントアップ
	clrb	t0if			;対策として､ウエイトを入れてみる｡
	jnb	t0if,$			;

	add	mCOUNT_L,#1		;+1(incはキャリー付かないのでダメ)
	snc				;スキップノットキャリー
	inc	mCOUNT_H.0		;+1
	cjae	mCOUNT_H,#2,rERROR	;｢2｣以上はエラー

	jmp	rBA_CHK0		;



;回転センサーアーム信号｢OFF｣の場合…次OFFで+1
rBB_CHK0
	clr	wdt			;▼
	jnb	gpio.0,r100_CHK		;記録ボタン押しチェック
	jb	gpio.5,rBB_CHK0		;回転センサー信号消えるまで待つ

	clr	tmr0			;電源ON時のチャタリングカウントアップ
	clrb	t0if			;対策として､ウエイトを入れてみる｡
	jnb	t0if,$			;

rBB_CHK1
	clr	wdt			;▼
	jnb	gpio.0,r100_CHK		;記録ボタン押しチェック
	jnb	gpio.5,rBB_CHK1		;回転センサー信号出るまで待つ

	clr	tmr0			;電源ON時のチャタリングカウントアップ
	clrb	t0if			;対策として､ウエイトを入れてみる｡
	jnb	t0if,$			;

	add	mCOUNT_L,#1		;+1(incはキャリー付かないのでダメ)
	snc				;スキップノットキャリー
	inc	mCOUNT_H.0		;+1
	cjae	mCOUNT_H,#2,rERROR	;｢2｣以上はエラー

	jmp	rBB_CHK0		;



;　範囲内チェック
r100_CHK
	cjne	mCOUNT_H,#1,rERROR	;｢1｣以外はエラー
	cjb	mCOUNT_L,#130,rERROR	;★｢130｣未満はエラー
	cja	mCOUNT_L,#220,rERROR	;★｢220｣超えるはエラー

;　値をEEPROMに書き込む｡
	setb	rp0			;ページ変更(Bank 1へ)
	mov	eeadr,#0		;アドレスセット
	clrb	rp0			;ページ変更(Bank 0へ)
	mov	w,mCOUNT_L		;
	setb	rp0			;ページ変更(Bank 1へ)
	mov	eedata,w		;
	setb	wren			;EEPROM Write Enable bit
	mov	eecon2,#55h		;
	mov	eecon2,#0AAh		;
	setb	wr			;Write Control bit
	jb	wr,$			;書き込み終了をここで待つ
	clrb	wren			;EEPROM Write Enable bit
	clrb	rp0			;ページ変更(Bank 0へ)

	clrb	gpio.1			;★LED
	jmp	rSTART_X		;


;---------------------------------------
;*** 100m設定エラー停止 ***
;---------------------------------------
rERROR
	mov	t1con,#00010001b	;プリスケール1:2(LED XOR警報に使用)
rE_REPE
	xor	gpio,#00000010b		;LED早い点滅状態にして機能停止
rE_WDT
	clr	wdt			;▼
	jnb	tmr1if,rE_WDT		;永久ループ=電源OFF必要
	clrb	tmr1if			;
	jmp	rE_REPE			;


;---------------------------------------
;sss サブルーチン sss
;---------------------------------------
;sssssss 上位PIC通信 ssssssssssssssssss;
sP_CHK
	snb	gpio.4			;上位PICは吸込(出力｢0｣)状態か？
	ret				;

	setb	rp0			;ページ変更(Bank 1へ)
	clrb	trisio.4		;出力ピンに変更
	clrb	rp0			;ページ変更(Bank 0へ戻す)

	clrb	mCOUNT_H.7		;上位PIC通信確認用

	jb	tmr1if,rE_END		;★通信時間エラー停止

	ret				;

rE_END
	setb	gpio.1			;★LED

	clr	wdt			;▼
	jmp	$-1			;永久停止
