;計測表示(電圧･電流･気温･油温･時間)		bitメカ工房	2018-01-09(火)
;
;Ver2からの主な変更点は｢LCD→VFD｣
;その他は電流と油温表示の完成｡
;しかし､実走行するとVer2時の｢表示が固まる｣問題を顕著に引き継いでいる｡
;プログラムに欠陥があるような気がするが分からないのでウォッチドックタイマーを
;入れてみる｡
;プログラムは0.5秒ループなので､ｳｫｯﾁﾄﾞｯｸﾀｲﾏｰは約1秒で設定してみる｡
;TMR0のプリスケールをWDT｢64｣に設定する｡(TMR0は未使用だったはず｡)
;ﾌﾟﾘｽｹ0で0.018秒だとﾌﾟﾘｽｹ64で1.152秒になるはず｡
;	↓
;しかし直らない｡表示が固まった感じ｡
;PICは動作中でもVFDがダメなのかも知れないと思い､LED点滅をテストで入れてみる｡
;(ｳｫｯﾁﾄﾞｯｸﾀｲﾏｰはOFFにしてみる｡)
;	↓
;結果:ｾﾙｽﾀｰﾄ時にLED(黄)が点いたまま固まる｡このパターンのみ何回も発生する｡
;	VFDじゃなくて､PICが固まるということが分かった｡
;	↓
;対策:ｳｫｯﾁﾄﾞｯｸﾀｲﾏｰをONにしてみる｡ただし前々回は直らなかったので良く考えてみる｡
;	･ﾃﾞｰﾀｰｼｰﾄを見直すとｳｫｯﾁﾄﾞｯｸﾀｲﾏｰの仕様が他のPICと少し異なる｡
;		思った通り動作していなかったかも知れない｡
;	･ﾃﾞｰﾀｰｼｰﾄを理解して再設定してみる｡
;		31kHz×65536＝2.114秒(OPTION RegisterのPSAはﾀｲﾏｰ0を選択)
;	･LEDが点いたまま固まるので､｢clr wdt｣はLED消灯命令の後ろに入れてみる｡
;	･ｳｫｯﾁﾄﾞｯｸﾀｲﾏｰが発動した場合､発動したことが分かるようにVFDに表示する｡
;		(経過時間の前に｢w｣を表示)
;	↓
;結果:ｳｫｯﾁﾄﾞｯｸﾀｲﾏｰ発動せず！
;	LED消灯したままVFD表示は固まったままとなる｡
;	やや暫くしてから(10秒以上)LEDが1秒ほど点いたり､VFD文字化け表示される
;	こともあり｡
;	なぜｳｫｯﾁﾄﾞｯｸﾀｲﾏｰ発動しないのか？(VFD｢w｣表示されない)
;	↓
;対策:call文多用の影響か？
;	｢clr wdt｣はVFD再表示後命令の後ろに移動してみる｡(call文の中に｡)
;	↓
;結果:変わらない！(ｳｫｯﾁﾄﾞｯｸﾀｲﾏｰ発動せず！)
;	↓
;対策:あきらめてハードリセットボタンを追加するか！？
;	MCLR端子(リセット)のRA3端子は未使用なので､それを使用できるぞ｡
;	それでふと思ったのだが､その端子は入力のみのはず｡
;	出力に設定していたが浮遊してノイズを受けやすくなっていたのでは？
;	MCLRとしてタイヤ設定ボタンの10kΩプルアップに接続してみる｡
;	↓
;結果：MCLRリセット受け付けない！
;	暴走前はMCLRボタンリセットできるが､暴走後はできない｡
;	なぜだか分からない｡制御不能だ｡
;	新品のPICに取替えてみたが同じだ｡
;	リセットボタンを連打しまくるとリセットできる｡なぜ？
;	↓
;	暴走状態をよく観察すると､20秒くらいしてからLEDが数秒間点灯して消えるを
;	繰り返すようだ｡規則性があるようだ？！
;	内蔵クロックの何かか？
;	↓
;対策：クロック変更のプリスケーラ等を見直して少し変更を試してみる｡
;	↓
;結果:変わらない！
;	↓
;	きちんと観察すると､約18秒周期でLEDが点灯する｡
;	LEDは約2秒間点灯して消える｡
;	MCLRボタンは高速連打しなくても､何回か押すとリセットされる｡
;	↓
;対策：オシレーター周波数設定値をメインループプログラム中に書き込んでみる｡
;	と思ったが､その前に31kHzで動作させるとどうなるかやってみた｡
;	LED点滅間隔が1分少々になった｡
;	今度は125kHzにしてみたところ､約16秒になった｡LEDの点灯時間は短い｡
;	いずれも暴走状態とは異なる｡
;	なお､ｳｫｯﾁﾄﾞｯｸﾀｲﾏｰが発動していないことに気付いた｡
;	見直すと､option設定に間違いがあったので修正した｡
;	(長時間設定となっていた｡)
;	よく考えると暴走でプログラムが書き換わらないはず｡
;	周波数繰り返し設定はやめて､各接続配線を外してどうなるかやってみる｡
;	↓
;	何本かずつ外してみたが､よくわからない｡
;	フェライトコアをプラグコード他､思い付くところに付けてみたがダメだった｡
;	↓
;結果:変わらない！
;	↓
;対策：PICを16F785に変更してみる｡
;	↓
;結果:
;
;
;
;[プログラム概要]
;・リアルタイムクロックモジュール(RTC-8564)の現在時刻を表示する｡
;・PICの内蔵RCを使用して､経過時間を表示する｡
;・電圧を表示する｡(単純分圧)　A/D使用
;・電流を表示する｡(電流センサー○○)　オペアンプ+A/D使用
;・気温を表示する｡(温度センサーDS18S20使用)
;・油温を表示する｡(温度センサーLM70)
;・TMR1を使用する｡(経過時間と温度センサーDS18S20)
;・TMR2を使用する｡(温度センサーDS18S20)
;・表示は｢VFD｣にて4ビットモードとする｡
;
;---------------------------------------;
;	  電圧  気温 時:分 経過時間 (PIC内蔵RC)
;	┌────────┐
;	│12.3  23.4 w0:00│←ｳｫｯﾁﾄﾞｯｸﾀｲﾏｰ発動時｢w｣表示
;	│+0.1  100  12:34│
;	└────────┘
;	  電流  油温 時:分 現在時刻 (ﾘｱﾙﾀｲﾑｸﾛｯｸﾓｼﾞｭｰﾙ)
;	  1234567890123456
;---------------------------------------;
;
;(参考)
;・タイマー1のプリスケーラを最長【 8 】にした場合のオーバーフロータイム
;　4.19MHz動作として､1/4194304x4x256x256x[8]=0.5秒 (8はプリスケーラ値)
;　RCを微調整して4.194304MHzに近づける｡
;
;[PIC選定仕様他]
; ･PIC16F785-I/P使用｡(秋月電子通商で160円/個)
; ･オシレーターは内蔵の4MHzを微調整使用する｡
;　(1命令は1/4194304*4=0.000000954秒)
; ･MCLRは外配線を簡略するため内部接続モードとする｡
;
;			     ┌─┰─┐
;	5.0V		 Vdd ┥      ┝ Vcc	GND
;ﾘｱﾙﾀｲﾑｸﾛｯｸﾓｼﾞｭｰﾙ SDA	 RA5 ┥	     ┝*RA0	電流ｾﾝｻｰ
;ﾘｱﾙﾀｲﾑｸﾛｯｸﾓｼﾞｭｰﾙ SCL	 RA4*┥	     ┝*RA1	基準電圧 4.096V
;	MCLR使用	 RA3 ┥	     ┝*RA2	ﾊﾞｯﾃﾘｰ電圧
;	LCD_DB5		 RC5 ┥PIC   ┝*RC0	(LED点滅ﾃｽﾄ)
;	LCD_DB4		 RC4 ┥16F785┝*RC1	LCD_RS
;	LCD_E		 RC3*┥	     ┝*RC2	LCD_R/W
;	LCD_DB6		 RC6*┥	     ┝*RB4	油温ｾﾝｻｰ cs
;	LCD_DB7		 RC7*┥	     ┝*RB5	油温ｾﾝｻｰ sc
;	温度ｾﾝｻｰ	 RB7 ┥	     ┝ RB6	油温ｾﾝｻｰ io
;			     └───┘
;		(*…A/D設定可能ﾋﾟﾝ)　A/D使用はRA0､RA1､RA2｡
;
;[プログラムの流れ概要]
;
;     電源ON
;	↓
;	初期設定
;	↓
;	0.5秒間隔待ち ←←←←←←←←←←←←←┐
;	↓					↑
;	経過時間カウントアップ			↑
;	↓					↑
;	電圧計測(バッテリー)			↑
;	電流計測(　　〃　　)			↑
;	↓					↑
;	現在時刻読み出し			↑
;	↓					↑
;	1秒間隔	→DS18S20(気温)読み取り開始	↑
;	↓	　DS18S20(気温)計測･変換	↑
;	↓	　LM70(油温)読み取り		↑
;	↓		↓			↑
;	VFD表示 ←←←←┘			↑
;	↓					↑
;	└→→→→→→→→→→→→→→→→→→→┘
;
;[凡例] (自分で分かりやすいように目印を付ける)
; m???:メモリー  r???:ラベル  s???:サブルーチン  v???:変数  ★:調整箇所など
;
;======= PICｺﾝﾌｨｷﾞｭﾚｰｼｮﾝ設定 ===========;(CVASM16アセンブラ用記述)

	include	'16f785.inc'

	fuses	_fcmen_off		;フェイルセーフモニター→無効
	fuses	_ieso_off		;内部/外部スイッチオーバーモード？
	fuses	_bor_on			;低電圧リセット→有効
	fuses	_cpd_off		;eepromのコードプロテクト→無効
	fuses	_cp_off			;コードプロテクト→無効
	fuses	_mclre_on		;MCLR端子(リセット)→【設定する】
	fuses	_pwrte_on		;電源投入72ms間リセット→有効
	fuses	_wdt_on			;ウォッチドックタイマー→【有効】
	fuses	_intrc_osc_noclkout	;オシレーター設定→内蔵RC

	id	'0310'			;Ver3.10

LCD_RS		=	rc.1		;LCD表示信号用
LCD_RW		=	rc.2		;LCD表示信号用
LCD_E		=	rc.3		;LCD表示信号用

LM70_cs		=	rb.4		;油温計測信号用
LM70_sc		=	rb.5		;油温計測信号用
LM70_io		=	rb.6		;油温計測信号用

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

mFREE_A		=	20h		;汎用カウンター(LCD初期 他)
mFREE_B		=	21h		;汎用カウンター(LCD初期 他)
mFREE_C		=	22h		;LCDビジーチェック他

mLCD_44		=	23h		;LCDデーター分割送信用

mBINA08		=	24h		;BCD計算用
mBINAXX		=	25h		;　　〃
mSHOW08		=	26h		;　　〃
mBCD_1		=	27h		;B→Dの1桁目(一の位)
mBCD_2		=	28h		;B→Dの2桁目(十の位)
mBCD_3		=	29h		;B→Dの3桁目(百の位､表示せず)

mC_05		=	2Ah		;PIC内部0.5秒間隔チェック用
mC_SS		=	2Bh		;秒カウンター
mC_MM		=	2Ch		;分カウンター
mC_HH		=	2Dh		;時カウンター

mC_SX		=	2Eh		;経過時間 秒 1桁目表示用
mC_XS		=	2Fh		;経過時間 秒 2桁目表示用
mC_MX		=	30h		;経過時間 分 1桁目表示用
mC_XM		=	31h		;経過時間 分 2桁目表示用
mC_HX		=	32h		;経過時間 時 1桁目表示用
mC_XH		=	33h		;経過時間 時 2桁目表示用

mT_MX		=	34h		;現在時刻 分 1桁目表示用
mT_XM		=	35h		;現在時刻 分 2桁目表示用
mT_HX		=	36h		;現在時刻 時 1桁目表示用
mT_XH		=	37h		;現在時刻 時 2桁目表示用

mV_VVX		=	38h		;バッテリー電圧
mV_VXV		=	39h		;バッテリー電圧
mV_XVV		=	3Ah		;バッテリー電圧

mA_AAX		=	3Bh		;バッテリー電流
mA_AXA		=	3Ch		;バッテリー電流
mA_XAA		=	3Dh		;バッテリー電流

mBCD_0		=	3Eh		;気温の小数表示用
mSOUSIN		=	3Fh		;DS18S20送信データー用
mDS18_L		=	40h		;DS18S20温度データー下位バイト
mDS18_H		=	41h		;DS18S20温度データー上位バイト
mDATA_2		=	42h		;？(THレジスタまたはユーザー･バイト1)
mDATA_3		=	43h		;？(TLレジスタまたはユーザー･バイト2)
mDATA_4		=	44h		;？(予約済み)
mDATA_5		=	45h		;？(予約済み)
mDATA_6		=	46h		;？(温度変換カウンタ(COUNT REMAIN))
mDATA_7		=	47h		;？(温度変換カウンタ(COUNT PERﾟC))
mDS_CRC		=	48h		;CRC
mSHR1		=	49h		;計算で得たCRC
mDS_TMR		=	4Ah		;DS18S20の時間カウント用
mDS_ERR		=	4Bh		;DS18S20のエラーチェック用
mERROR		=	4Ch		;エラーチェック用

mDS_0XX		=	4Dh		;気温 2桁目表示用
mDS_X0X		=	4Eh		;気温 1桁目表示用
mDS_XX0		=	4Fh		;気温 小数点第1位表示用

mLM70		=	50h		;油温データー格納用
mOIL0XX		=	51h		;油温 3桁目表示用
mOILX0X		=	52h		;油温 2桁目表示用
mOILXX0		=	53h		;油温 1桁目表示用

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

;Bank 0
	clr	ra			;
	setb	ra.5			;ﾘｱﾙﾀｲﾑｸﾛｯｸﾓｼﾞｭｰﾙ SDAをHi(準備)
	setb	ra.4			;ﾘｱﾙﾀｲﾑｸﾛｯｸﾓｼﾞｭｰﾙ SCLをHi(準備)
	clr	rb			;
	setb	LM70_cs			;(rb.4)油温計測信号用
	clr	rc			;

	mov	intcon,#00000000b	;割り込み設定
;	初期状態	0000 000x
	mov	t1con,#10110001b	;
;	初期状態	0000 0000
					;bit7…ゲート正論理
					;bit6…ゲートアクティブの？
					;bit5～4…プリスケールレート【8】
					;bit3…0 タイマー1専用オシレーター
					;bit2…0 外部クロック同期
					;bit1…0 タイマー1クロックソース選択
					;bit0…1 タイマー1オン

	mov	t2con,#00000100b	;プリスケール1:1
;	初期状態	-000 0000

	mov	wdtcon,#00010111b	;Watchdog Timer設定
;	初期状態	---0 1000
					;bit1～4…プリスケールレート【65536】
					;bit0…ｳｫｯﾁﾄﾞｯｸﾀｲﾏｰON

	mov	adcon0,#01001001b	;A/D設定
;	初期状態	0000 0000
					;bit7…0 左詰
					;bit6…1 基準電圧VREFﾋﾟﾝ使用
					;bit5～2… 0010 A/Dﾋﾟﾝ選択 AN2
					;bit1…0 変換開始(GO/DONE)
					;bit0…1 A/D使用

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

;	mov	option_reg,#00001111b	;
;	初期状態	   #11111111b
					;bit7…RAプルアップ
					;bit6…割り込みエッジ
					;bit5…タイマー0は外付クロック使用
					;bit4…タイマー0エッジ
					;bit3…プリスケーラ割当
					;bit2～0…プリスケールレート

	clrb	not_rapu		;RAプルアップ【有】
	clrb	t0cs			;タイマー0は【内蔵クロック】使用
					;ﾀｲﾏｰ0は使用していないが念のため設定
	clrb	psa			;プリスケーラは【タイマー0】へ割当

	mov	trisa,#00001111b	;RAの入出力ピン設定
;	初期状態	--11 1111
	mov	trisb,#11000000b	;RBの入出力ピン設定
;	初期状態	1111 ----
	mov	trisc,#00000000b	;RCの入出力ピン設定
;	初期状態	1111 1111

;	mov	osccon,#01100101b	;内蔵オシレーター周波数設定他
;	初期状態	-110 q111

;	setb	ircf0			;初期値4MHz
;	clrb	ircf1			;
;	clrb	ircf2			;
;	clrb	scs			;Clock source

	mov	osctune,#00000110b	;★内蔵オシレーター周波数微調整
;	初期状態	---0 0000 MAX 01111 ～ min 10000
;	00110で10分がCASIOで10分02秒､00111で10分がCASIOで9分58.0秒
;	違うPICだと00111で10分がCASIOで9分58.9秒

	mov	ansel0,#00000111b	;アナログorデシタルピン設定
;	初期状態	1111 1111
	mov	ansel1,#00000000b	;アナログorデシタルピン設定
;	初期状態	---- 1111

	mov	wpua,#00110000b		;RAのプルアップ設定
;	初期状態     #--11-111b

;	mov	adcon1,#00000000b	;A/D変換時間設定
;	初期状態	-000 ----

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


;LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL;
;VFD初期設定
	clr	mFREE_A			;
	djnz	mFREE_A,$		;☆VFDは 0.0001 秒待てばOK

	mov	rc,#00101000b		;★4ビットモード､E
	clrb	LCD_E			;これで4ビットモードになる
;↓4
	mov	mLCD_44,#00000000b	;★VFD明度調整
	call	sLCD_RE			;00…200% 01…150% 10…100% 11…50%

	mov	mLCD_44,#00001100b	;表示オン
;	mov	mLCD_44,#00001000b	;表示オフ
	call	sLCD_E_			;
;LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL;

;タイマー1リセット
	clr	tmr1l			;タイマー1 下位8bit
	clr	tmr1h			;タイマー1 上位8bit
	setb	tmr1if			;約0.5秒間隔旗

;経過時間のキー(電源)ONスタート調整

	jnb	not_to,rWDTOUT		;ｳｫｯﾁﾄﾞｯｸﾀｲﾏｰ発動時は経過時間保持

	mov	mC_SS,#59		;
	mov	mC_MM,#59		;
	mov	mC_HH,#255		;
	clr	mC_05			;PIC内部0.5秒間隔チェック用

rWDTOUT

;温度センサーDS18S20の初期表示補正用
	clr	mERROR			;気温計エラーチェック
;	mov	mDS_0XX,#' '		;気温初期表示
;	mov	mDS_X0X,#' '		;気温初期表示
;	mov	mDS_XX0,#' '		;気温初期表示

;温度センサーLM40の初期表示補正用
	clr	mFREE_C			;油温初期表示用


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

;	setb	rp0			;ページ変更(Bank 1へ)
;	clrb	ircf.0			;内蔵オシレーター周波数を4MHzに設定
;	setb	ircf.1			;
;	setb	ircf.2			;
;	clrb	rp0			;ページ変更(Bank 0へ戻す)

	jnb	tmr1if,$		;約0.5秒間隔待ち
	clrb	tmr1if			;約0.5秒間隔旗クリア

	setb	rc.0			;テスト

	call	sCOUNT_T		;経過時間アップカウント

	call	sAD_V			;バッテリー電圧と電流チェック

	call	sT_READ			;現在時刻読み込み

	jnb	mC_05.0,rDS_PASS	;↓は1秒間隔

	call	sDS_READ		;気温読み取り開始
	call	sDS_XXXX		;気温計測･変換開始

	call	sLM70			;油温読み取り開始

rDS_PASS
	call	sLCD_GO			;LCD表示

	clrb	rc.0			;テスト

	jmp	rREPEAT			;


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





;CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC;
;sss 経過時間カウント サブルーチン sss
;CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC;
sCOUNT_T
	inc	mC_05			;+1
	jb	mC_05.0,$+3		;0.5 or 1 秒判定

	ret				;ビット無ければ戻る

	inc	mC_SS			;+1
	cjb	mC_SS,#60,rC_BNC	;
	clr	mC_SS			;

	inc	mC_MM			;+1
	cjb	mC_MM,#60,rC_BNC	;
	clr	mC_MM			;

	inc	mC_HH			;+1

;UPカウント時計の表示変換
rC_BNC
	mov	mBINA08,mC_SS		;【秒】
	call	sBCDCAL			;BCD計算へ
	mov	mC_XS,mBCD_2		;
	mov	mC_SX,mBCD_1		;
	add	mC_XS,#48		;+48
	add	mC_SX,#48		;+48

	mov	mBINA08,mC_MM		;【分】
	call	sBCDCAL			;BCD計算へ
	mov	mC_XM,mBCD_2		;
	mov	mC_MX,mBCD_1		;
	add	mC_XM,#48		;+48
	add	mC_MX,#48		;+48

	mov	mBINA08,mC_HH		;【時】
	call	sBCDCAL			;BCD計算へ
	mov	mC_XH,mBCD_2		;
	mov	mC_HX,mBCD_1		;
	add	mC_XH,#48		;+48
	add	mC_HX,#48		;+48

	ret				;



;ADADADADADADADADADADADADADADADADADADADA;
;sss A/D サブルーチン sss
;ADADADADADADADADADADADADADADADADADADADA;
sAD_V
;【バッテリー電圧】チェック
	setb	go_done			;A/D変換開始
	jb	go_done,$		;A/D変換終了(bit0)まで待つ
	mov	mBINA08,adresh		;


;切換えてからA/D充電に20μs必要なので､ここで切換えておく｡
	clrb	chs1			;AN0に切換

;>>>
	call	sBCDCAL			;BCD計算へ
;<<<

	mov	mV_XVV,mBCD_3		;電圧
	mov	mV_VXV,mBCD_2		;
	mov	mV_VVX,mBCD_1		;

	add	mV_XVV,#48		;
	add	mV_VXV,#48		;
	add	mV_VVX,#48		;


;【バッテリー電流】チェック
	setb	go_done			;A/D変換開始
	jb	go_done,$		;A/D変換終了(bit0)まで待つ
	mov	mBINA08,adresh		;

	cjb	mBINA08,#29,rA_ERRO	;-9.9ｱﾝﾍﾟｱ超判定
	cja	mBINA08,#227,rA_ERRO	;+9.9ｱﾝﾍﾟｱ超判定

	jmp	rA_CAL1			;

rA_ERRO
	mov	mA_XAA,#'*'		;範囲外表示
	mov	mA_AXA,#'*'		;
	mov	mA_AAX,#'*'		;

	setb	chs1			;AN2に切換ておく

	ret				;

rA_CAL1
	jb	mBINA08.7,rA_CAL2	;マイナス判定

	clr	mFREE_A			;
	sub	mFREE_A,mBINA08		;0-X
	mov	mBINA08,mFREE_A		;計算結果を入れる
	clrb	mBINA08.7		;7ﾋﾞｯﾄ
	mov	mA_XAA,#'-'		;
	jmp	rA_CAL4			;

rA_CAL2
	sub	mBINA08,#128		;-128
	jnz	rA_CAL3			;
	mov	mA_XAA,#' '		;0は符号無
	jmp	rA_CAL4			;
rA_CAL3
	mov	mA_XAA,#'+'		;
rA_CAL4

;>>>
	call	sBCDCAL			;BCD計算へ
;<<<
;	mov	mA_XAA,mBCD_3		;電圧
	mov	mA_AXA,mBCD_2		;
	mov	mA_AAX,mBCD_1		;

;	add	mA_XAA,#48		;
	add	mA_AXA,#48		;
	add	mA_AAX,#48		;


	setb	chs1			;AN2に切換ておく

	ret



;TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT;
;sss 8564時計 サブルーチン sss
;TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT;
sT_READ
;sss 現在時刻読み出し ssssssssssssssssss;

;*** PICから開始条件送信 ***
	clrb	ra.5			;SDAをLoに変化させる
	clrb	ra.4			;*SDLをLoにして1区切りとする

;PICからスレーブアドレスをR/Wビット書き込みモードで送信
;1010 0010b
	call	s8564_W1		;
	call	s8564_W0		;
	call	s8564_W1		;
	call	s8564_W0		;

	call	s8564_W0		;
	call	s8564_W0		;
	call	s8564_W1		;
	call	s8564_W0		;

	call	sACK_A			;アクノリッジ確認

;PICが8564時計から読み出すアドレスを送信
;0000 0011b (分)
	call	s8564_W0		;
	call	s8564_W0		;
	call	s8564_W0		;
	call	s8564_W0		;

	call	s8564_W0		;
	call	s8564_W0		;
	call	s8564_W1		;
	call	s8564_W1		;

	call	sACK_A			;アクノリッジ確認

;*** PICから開始条件｢再｣送信 ***
	setb	ra.5			;SDAをHi(準備)
	setb	ra.4			;SCLをHi(準備)
	clrb	ra.5			;SDAをLoに変化させる
	clrb	ra.4			;*SDLをLoにして1区切りとする

;PICからスレーブアドレスをR/Wビット読み出しモードで送信
;1010 0011b
	call	s8564_W1		;
	call	s8564_W0		;
	call	s8564_W1		;
	call	s8564_W0		;

	call	s8564_W0		;
	call	s8564_W0		;
	call	s8564_W1		;
	call	s8564_W1		;

	call	sACK_A			;アクノリッジ確認

;---------------------------------------;
;ここからPICがレシーバー､8564時計がトランスミッタとなる｡
;---------------------------------------;
	setb	rp0			;ページ変更(Bank 1へ)
;Bank 1
	setb	trisa.5			;｢1｣ RA5を入力に変更
	clrb	rp0			;ページ変更(Bank 0へ戻す)

;---------------------------------------;
;***　｢分｣ 読み出し格納 ***
;---------------------------------------;
	clr	mT_XM			;
	clr	mT_MX			;
;7bit
	setb	ra.4			;SCLをHi(読み出し開始)
	snb	ra.5			;RA5がLoならスキップ
	setb	mT_XM.3			;
	clrb	ra.4			;SCLをLo
;6bit
	nop				;1.3μS確保
	setb	ra.4			;SCLをHi(読み出し開始)
	snb	ra.5			;RA5がLoならスキップ
	setb	mT_XM.2			;
	clrb	ra.4			;SCLをLo
;5bit
	nop				;1.3μS確保
	setb	ra.4			;SCLをHi(読み出し開始)
	snb	ra.5			;RA5がLoならスキップ
	setb	mT_XM.1			;
	clrb	ra.4			;SCLをLo
;4bit
	nop				;1.3μS確保
	setb	ra.4			;SCLをHi(読み出し開始)
	snb	ra.5			;RA5がLoならスキップ
	setb	mT_XM.0			;
	clrb	ra.4			;SCLをLo
;3bit
	nop				;1.3μS確保
	setb	ra.4			;SCLをHi(読み出し開始)
	snb	ra.5			;RA5がLoならスキップ
	setb	mT_MX.3			;
	clrb	ra.4			;SCLをLo
;2bit
	nop				;1.3μS確保
	setb	ra.4			;SCLをHi(読み出し開始)
	snb	ra.5			;RA5がLoならスキップ
	setb	mT_MX.2			;
	clrb	ra.4			;SCLをLo
;1bit
	nop				;1.3μS確保
	setb	ra.4			;SCLをHi(読み出し開始)
	snb	ra.5			;RA5がLoならスキップ
	setb	mT_MX.1			;
	clrb	ra.4			;SCLをLo
;0bit
	nop				;1.3μS確保
	setb	ra.4			;SCLをHi(読み出し開始)
	snb	ra.5			;RA5がLoならスキップ
	setb	mT_MX.0			;
	clrb	ra.4			;SCLをLo

;--- PICからアクノリッジ送信 ---
	clrb	ra.5			;
	setb	rp0			;ページ変更(Bank 1へ)
;Bank 1
	clrb	trisa.5			;｢0｣ RA5を出力(Lo)に変更
	clrb	rp0			;ページ変更(Bank 0へ戻す)

	setb	ra.4			;SCLをHi
	clrb	ra.4			;SCLをLo

	setb	rp0			;ページ変更(Bank 1へ)
;Bank 1
	setb	trisa.5			;｢1｣ RA5を入力に変更
	clrb	rp0			;ページ変更(Bank 0へ戻す)

;---------------------------------------;
;*** ｢時｣ 読み出し格納 ***
;---------------------------------------;
	clr	mT_XH			;
	clr	mT_HX			;
;7bit
	setb	ra.4			;SCLをHi(読み出し開始)
	snb	ra.5			;RA5がLoならスキップ
	setb	mT_XH.3			;
	clrb	ra.4			;SCLをLo
;6bit
	nop				;1.3μS確保
	setb	ra.4			;SCLをHi(読み出し開始)
	nop
	snb	ra.5			;RA5がLoならスキップ
	setb	mT_XH.2			;
	clrb	ra.4			;SCLをLo
;5bit
	nop				;1.3μS確保
	setb	ra.4			;SCLをHi(読み出し開始)
	snb	ra.5			;RA5がLoならスキップ
	setb	mT_XH.1			;
	clrb	ra.4			;SCLをLo
;4bit
	nop				;1.3μS確保
	setb	ra.4			;SCLをHi(読み出し開始)
	snb	ra.5			;RA5がLoならスキップ
	setb	mT_XH.0			;
	clrb	ra.4			;SCLをLo
;3bit
	nop				;1.3μS確保
	setb	ra.4			;SCLをHi(読み出し開始)
	snb	ra.5			;RA5がLoならスキップ
	setb	mT_HX.3			;
	clrb	ra.4			;SCLをLo
;2bit
	nop				;1.3μS確保
	setb	ra.4			;SCLをHi(読み出し開始)
	snb	ra.5			;RA5がLoならスキップ
	setb	mT_HX.2			;
	clrb	ra.4			;SCLをLo
;1bit
	nop				;1.3μS確保
	setb	ra.4			;SCLをHi(読み出し開始)
	snb	ra.5			;RA5がLoならスキップ
	setb	mT_HX.1			;
	clrb	ra.4			;SCLをLo
;0bit
	nop				;1.3μS確保
	setb	ra.4			;SCLをHi(読み出し開始)
	snb	ra.5			;RA5がLoならスキップ
	setb	mT_HX.0			;
	clrb	ra.4			;SCLをLo

;--- PICからアクノリッジ｢1｣送信 ---
	setb	ra.5			;
	setb	rp0			;ページ変更(Bank 1へ)
;Bank 1
	clrb	trisa.5			;｢0｣ RA5を出力(Lo)に変更
	clrb	rp0			;ページ変更(Bank 0へ戻す)

	setb	ra.4			;SCLをHi
	clrb	ra.4			;SCLをLo

;*** PICから停止条件送信 ***
	clrb	ra.5			;SDAをLo(準備)
	setb	ra.4			;SCLをHi(準備)
	setb	ra.5			;SDAをHiに変化させる

;=======================================;
;不定ビットのマスク
	and	mT_XM,#00000111b	;読み出し不定ビットマスク
	and	mT_XH,#00000011b	;読み出し不定ビットマスク

;---------------------------------------;
;8564時計のLCD表示変換
	add	mT_XM,#48		;+48
	add	mT_MX,#48		;+48

	add	mT_XH,#48		;+48
	add	mT_HX,#48		;+48

	ret				;

;sssssss bit｢0｣送信 ssssssssssssssssssss;
s8564_W0
	clrb	ra.5			;0(データー)
	setb	ra.4			;SCLをHi(送信)
	clrb	ra.4			;*SDLをLoにして1区切りとする
	ret				;

;sssssss bit｢1｣送信 ssssssssssssssssssss;
s8564_W1
	setb	ra.5			;1(データー)
	setb	ra.4			;SCLをHi(送信)
	clrb	ra.4			;*SDLをLoにして1区切りとする
	ret				;

;sssssss アクノリッジ確認 ssssssssssssss;
sACK_A
	setb	rp0			;ページ変更(Bank 1へ)
;Bank 1
	setb	trisa.5			;｢1｣ RA5を入力に変更
	clrb	rp0			;ページ変更(Bank 0へ戻す)

	setb	ra.4			;SCL

	jnb	ra.5,rNO_ERR		;RA5がLoならジャンプ
;	mov	mERROR,#'E'		;エラー表示
	mov	mT_MX,#'E'		;エラー表示

rNO_ERR
	clrb	ra.4			;*SDLをLoにして1区切りとする

	setb	rp0			;ページ変更(Bank 1へ)
;Bank 1
	clrb	trisa.5			;｢0｣ RA5を出力に変更
	clrb	rp0			;ページ変更(Bank 0へ戻す)

	ret				;



;DSDSDSDSDSDSDSDSDSDSDSDSDSDSDSDSDSDSDSD;
;sss 気温計測 サブルーチン sss
;DSDSDSDSDSDSDSDSDSDSDSDSDSDSDSDSDSDSDSD;

sDS_XXXX

	call	sDRESET			;DS18S20/RESET送信

	jb	mERROR.1,rERROR1	;断線エラー
	jb	mERROR.2,rERROR2	;短絡エラー
	jb	mERROR.3,rERROR3	;リセットエラー

	mov	mSOUSIN,#0CCh		;スキップROMコード(CCh)送信
	call	sSOUSIN			;11001100b
	mov	mSOUSIN,#44h		;コンバートTコード(44h)送信
	call	sSOUSIN			;01000100b

	ret
;---------------------------------------;
;　↑
;データーシートでは変換に0.75秒必要となっている
;　↓
;---------------------------------------;

sDS_READ

;DS18S20データー読み取り開始

	call	sDRESET			;DS18S20/RESET送信

	mov	mSOUSIN,#0CCh		;スキップROMコード(CCh)送信
	call	sSOUSIN			;11001100b
	mov	mSOUSIN,#0BEh		;リード･スクラッチ･パッド･コード(BEh)
	call	sSOUSIN			;送信10111110b
	call	sREAD_9			;スクラッチ･パットのデーターを読む
	call	s9BCRC			;CRC計算とエラー判定


;-------エラー判定と表示ジャンプ

	jb	mERROR.4,rERROR4	;CRCエラーがあった場合｢Er4｣表示へ

;-------温度計算------------------------;

;マイナス判定とマイナス処理

;-0.1ﾟC～-0.3ﾟCをチェックする｡
	test	mDS18_L			;ゼロかどうか
	jnz	rHMINUS			;ゼロでなければパス

	cjbe	mDATA_6,#012,rHMINUS	;データー(6)が012以下はパス
	setb	mDS18_H.0		;マイナス符号付加用
	jmp	rTABLE_			;マイナステーブルへ


rHMINUS
	jnb	mDS18_H.7,rPLUS		;mDS18_Hの7ビット目でマイナス判定

	clr	mFREE_A			;ゼロ化
	sub	mFREE_A,mDS18_L		;0-mDS18_L
	mov	mDS18_L,mFREE_A		;

;-9.8ﾟCを超えたか？
	cjae	mDS18_L,#020,rLOW	;｢LLL｣表示へ

rTABLE_

;小数点第一位表示(表示ステップ0.1ﾟC)マイナスの場合

	cje	mDATA_6,#001,rXX3	;
	cje	mDATA_6,#002,rXX4	;
	cje	mDATA_6,#003,rXX4	;
	cje	mDATA_6,#004,rXX5	;
	cje	mDATA_6,#005,rXX6	;
	cje	mDATA_6,#006,rXX6	;
	cje	mDATA_6,#007,rXX7	;
	cje	mDATA_6,#008,rXX8	;

	cje	mDATA_6,#009,rXX8D	;
	cje	mDATA_6,#010,rXX9D	;
	cje	mDATA_6,#011,rXX9D	;

	cje	mDATA_6,#012,rXX0	;
	cje	mDATA_6,#013,rXX1	;
	cje	mDATA_6,#014,rXX1	;
	cje	mDATA_6,#015,rXX2	;
	cje	mDATA_6,#016,rXX3	;

	jmp	rNNN			;エラーとして｢---｣表示


rPLUS

;+85ﾟCか？
	cje	mDS18_L,#170,rNNN	;立ち上げ直後の初期状態｢---｣

;+85ﾟC超えているか？
	cja	mDS18_L,#170,rHIGH	;｢HHH｣

;小数点第一位表示(表示ステップ0.1ﾟC)プラスの場合

	cje	mDATA_6,#001,rXX7	;
	cje	mDATA_6,#002,rXX6	;
	cje	mDATA_6,#003,rXX6	;
	cje	mDATA_6,#004,rXX5	;
	cje	mDATA_6,#005,rXX4	;
	cje	mDATA_6,#006,rXX4	;
	cje	mDATA_6,#007,rXX3	;
	cje	mDATA_6,#008,rXX3	;
	cje	mDATA_6,#009,rXX2	;
	cje	mDATA_6,#010,rXX1	;
	cje	mDATA_6,#011,rXX1	;
	cje	mDATA_6,#012,rXX0	;

	cje	mDATA_6,#013,rXX9D	;
	cje	mDATA_6,#014,rXX9D	;
	cje	mDATA_6,#015,rXX8D	;
	cje	mDATA_6,#016,rXX8D	;

	jmp	rNNN			;エラーとして｢---｣表示

rXX0	mov	mBCD_0,#0		;
	jmp	rBCD7			;
rXX1	mov	mBCD_0,#1		;
	jmp	rBCD7			;
rXX2	mov	mBCD_0,#2		;
	jmp	rBCD7			;
rXX3	mov	mBCD_0,#3		;
	jmp	rBCD7			;
rXX4	mov	mBCD_0,#4		;
	jmp	rBCD7			;
rXX5	mov	mBCD_0,#5		;
	jmp	rBCD7			;
rXX6	mov	mBCD_0,#6		;
	jmp	rBCD7			;
rXX7	mov	mBCD_0,#7		;
	jmp	rBCD7			;
rXX8	mov	mBCD_0,#8		;
	jmp	rBCD7			;
rXX8D	mov	mBCD_0,#8		;
	dec	mDS18_L			;-1補正
	jmp	rBCD7			;
rXX9D	mov	mBCD_0,#9		;
	dec	mDS18_L			;-1補正

rBCD7

;温度データー÷2計算
	clc				;クリアキャリー
	rr	mDS18_L			;÷2

	mov	mBINA08,mDS18_L		;温度計測データーをBCD化
	call	sBCDCAL			;BCD計算へ


;BCD→7セグメントLED表示変換

	mov	mDS_0XX,mBCD_2		;2桁目
	mov	mDS_X0X,mBCD_1		;1桁目
	mov	mDS_XX0,mBCD_0		;少数点第1位

	add	mDS_0XX,#48		;
	add	mDS_X0X,#48		;
	add	mDS_XX0,#48		;


;マイナスの場合マイナス符号表示
	jnb	mDS18_H.0,$+4		;mDS18_Hの1ビット目でマイナス判定
	mov	mDS_0XX,#'-'		;☆｢-｣パターンを入れる

	ret



;断線エラーがあった場合｢Er1｣表示
rERROR1
	mov	mDS_0XX,#'E'		;
	mov	mDS_X0X,#'r'		;
	mov	mDS_XX0,#'1'		;
	ret

;短絡エラーがあった場合｢Er2｣表示
rERROR2
	mov	mDS_0XX,#'E'		;
	mov	mDS_X0X,#'r'		;
	mov	mDS_XX0,#'2'		;
	ret

;リセットエラーがあった場合｢Er3｣表示
rERROR3
	mov	mDS_0XX,#'E'		;
	mov	mDS_X0X,#'r'		;
	mov	mDS_XX0,#'3'		;
	ret


;CRCエラーがあった場合｢Er4｣表示
rERROR4
	mov	mDS_0XX,#'E'		;
	mov	mDS_X0X,#'r'		;
	mov	mDS_XX0,#'4'		;
	clrb	mERROR.4		;エラービットクリヤー
	ret

;-9.9ﾟCを超えた場合は｢LLL｣表示とする｡
rLOW
	mov	mDS_0XX,#'L'		;
	mov	mDS_X0X,#'L'		;
	mov	mDS_XX0,#'L'		;
	ret

;85ﾟCの場合は｢---｣表示とする｡
rNNN
	mov	mDS_0XX,#'*'		;
	mov	mDS_X0X,#'*'		;
	mov	mDS_XX0,#'*'		;
	ret				;

;85ﾟCを超えた場合は｢HHH｣表示とする｡
rHIGH
	mov	mDS_0XX,#'H'		;
	mov	mDS_X0X,#'H'		;
	mov	mDS_XX0,#'H'		;
	ret



;sssssss RESET送信及びエラーチェック sss;DS18S20
sDRESET
	clr	mERROR			;

	clrb	rb.7			;☆Lo

;	mov	tmr1h,#0FDh		;480μs x1.5=720μsの待ちを作る
;	mov	tmr1l,#30h		;(16ビットで0-720(10進)=FD30(16進))
;	clrb	tmr1if			;
;	jnb	tmr1if,$		;

;　tmr1lの1カウント時間は　1/32768x2=0.00006103515625秒
;　720μsであれば､0.00072/0.00006103515625=11.8

;　tmr1lの1カウント時間は　1/4194304x4x8=0.00000762912秒
;　720μsであれば､0.00072/0.00000762912=94.4
	mov	mDS_TMR,tmr1l		;
	add	mDS_TMR,#95		;☆
	cjne	tmr1l,mDS_TMR,$		;


	setb	rp0			;ページ変更(Bank 1へ)
	setb	trisb.7			;☆入力に変更
	clrb	rp0			;ページ変更(Bank 0へ戻す)

;	mov	tmr1h,#0FDh		;480μs x1.5=720μs設定
;	mov	tmr1l,#30h		;(16ビットで0-720(10進)=FD30(16進))
;	clrb	tmr1if			;

	mov	mDS_TMR,tmr1l		;480μs x1.5=720μs設定
	add	mDS_TMR,#95		;☆↓


;---Waits計測開始(15-60μs)
	clr	tmr2			;タイマー2の値クリア
	clrb	tmr2if			;タイマー2のオーバーフロー旗クリア

	jb	tmr2if,_rERRO1		;255μs超えの場合は断線エラーと判定する

	jb	rb.7,$-2		;☆ビット0まで待つ
	mov	mFREE_A,tmr2		;タイマー2の値をメモリーに格納
	cjbe	mFREE_A,#15,_rERRO2	;15μs未満の場合は短絡エラーと判定する
	cjae	mFREE_A,#60,_rERRO3	;リセットエラー判定

;---pulse計測開始(60-240μs)
	clr	tmr2			;タイマー2の値クリア
	clrb	tmr2if			;タイマー2のオーバーフロー旗クリア

	jb	tmr2if,_rERRO3		;リセットエラー判定

	jnb	rb.7,$-2		;☆ビット1まで待つ
	mov	mFREE_A,tmr2		;タイマー2の値をメモリーに格納
	cjbe	mFREE_A,#60,_rERRO3	;リセットエラー判定
	cjae	mFREE_A,#240,_rERRO3	;　　　〃

;	jb	tmr1if,$		;設定しておいた720μsになるまで待つ
	cjne	tmr1l,mDS_TMR,$		;


_rERR_r
	setb	rb.7			;☆あらかじめHiにしておく
	setb	rp0			;ページ変更(Bank 1へ)
	clrb	trisb.7			;☆出力に変更
	clrb	rp0			;ページ変更(Bank 0へ戻す)

	ret				;リターン(サブルーチン終わり)


;RESETエラー処理
_rERRO1
	setb	mERROR.1		;
	jmp	_rERR_r			;
_rERRO2
	setb	mERROR.2		;
	jmp	_rERR_r			;
_rERRO3
	setb	mERROR.3		;
	jmp	_rERR_r			;


;sssssss 送信パターン｢0｣か｢1｣ ssssssssss;DS18S20

sSOUSIN
	mov	mFREE_A,#8		;8ビット分
_rSOUSI
	jb	mSOUSIN.0,_rWRIT1	;｢0｣か｢1｣の判定
;｢0｣だった場合
	clrb	rb.7			;☆
	mov	tmr2,#196		;(256-60=196)
	clrb	tmr2if			;
	jnb	tmr2if,$		;60μs待つ
	setb	rb.7			;☆送信終わりの合図
	rr	mSOUSIN			;
	djnz	mFREE_A,_rSOUSI		;

	ret				;リターン(サブルーチン終わり)

;｢1｣だった場合
_rWRIT1
	clrb	rb.7			;☆
	setb	rb.7			;☆
	mov	tmr2,#196		;(256-60=196)
	clrb	tmr2if			;
	jnb	tmr2if,$		;60μs待つ

	rr	mSOUSIN			;
	djnz	mFREE_A,_rSOUSI		;

	ret				;リターン(サブルーチン終わり)

;sssssss データー受信 ssssssssssssssssss;DS18S20
sREAD_9
	call	ssREAD9			;
	mov	mDS18_L,mFREE_A		;温度データー下位バイト
	call	ssREAD9			;
	mov	mDS18_H,mFREE_A		;温度データー上位バイト
	call	ssREAD9			;
	mov	mDATA_2,mFREE_A		;(THレジスタまたはユーザー･バイト1)
	call	ssREAD9			;
	mov	mDATA_3,mFREE_A		;(TLレジスタまたはユーザー･バイト2)
	call	ssREAD9			;
	mov	mDATA_4,mFREE_A		;(予約済み)
	call	ssREAD9			;
	mov	mDATA_5,mFREE_A		;(予約済み)
	call	ssREAD9			;
	mov	mDATA_6,mFREE_A		;(温度変換カウンタ(COUNT REMAIN))
	call	ssREAD9			;
	mov	mDATA_7,mFREE_A		;(温度変換カウンタ(COUNT PERﾟC))
	call	ssREAD9			;
	mov	mDS_CRC,mFREE_A		;CRC

	ret				;リターン(サブルーチン終わり)

;サブルーチンのサブルーチン
ssREAD9
	mov	mFREE_B,#8		;8ビット分
_rREAD9
	clrb	rb.7			;☆

	setb	rp0			;ページ変更(Bank 1へ)
	setb	trisb.7			;☆入力に変更
	clrb	rp0			;ページ変更(Bank 0へ戻す)

	nop				;
	nop				;
	nop				;

	clc				;クリアキャリー
	snb	rb.7			;☆
	stc				;セットキャリー
	rr	mFREE_A			;データーを7ビット目に入れる
	nop				;
	nop				;
	nop				;
	nop				;
	nop				;
	nop				;
	nop				;
	nop				;
	nop				;
	nop				;
	jb	mFREE_A.7,rNZERO	;

;｢0｣だった場合
	mov	tmr2,#196		;(256-60=196)
	clrb	tmr2if			;
	jnb	tmr2if,$		;60μs待つ

;	jnb	rb.7,$			;☆ビット立つまで待つ


;｢1｣だった場合(｢0｣だった場合の後処理共通)
rNZERO
	setb	rb.7			;☆
	setb	rp0			;ページ変更(Bank 1へ)
	clrb	trisb.7			;☆出力に変更
	clrb	rp0			;ページ変更(Bank 0へ戻す)

	djnz	mFREE_B,_rREAD9		;

	ret				;リターン(サブルーチン終わり)


;sssssss CRC計算 sssssssssssssssssssssss;DS18S20
;
;CRCの計算方法についてはよく分からないので､この部分は､
;｢トラ技2003年12月号の272P～280P PIC16F84を使った温度コントローラの製作
;<前編>DS18S20を使いこなそう! 軸丸 哲也 氏作成｣
;を､ほぼそのまま転用した｡
;
;8バイトデーターからCRCを計算
s9BCRC
	clr	mSHR1			;
	mov	w,mDS18_L		;
	call	ssCRC			;
	mov	w,mDS18_H		;
	call	ssCRC			;
	mov	w,mDATA_2		;
	call	ssCRC			;
	mov	w,mDATA_3		;
	call	ssCRC			;
	mov	w,mDATA_4		;
	call	ssCRC			;
	mov	w,mDATA_5		;
	call	ssCRC			;
	mov	w,mDATA_6		;
	call	ssCRC			;
	mov	w,mDATA_7		;
	call	ssCRC			;
;CRCエラー判定
	mov	mFREE_A,mDS_CRC		;
	sub	mFREE_A,mSHR1		;CRC-計算CRC
	jz	$+3			;↑の計算結果がゼロならOK(Words2)
	setb	mERROR.4		;(Words1)

	ret				;リターン(サブルーチン終わり)


;サブルーチンのサブルーチン
ssCRC
	mov	mFREE_A,w		;
	mov	mDS_ERR,#8		;(汎用回数カウント)
_rCRC_L
	mov	w,mFREE_A		;
	xor	w,mSHR1			;mSHR1 = 計算で得たCRC
	mov	mFREE_B,w		;
	jnb	mFREE_B.0,_rZCRC	;
	xor	mSHR1,#11000b		;？0001 1000(生成多項式による)
_rZCRC
	rr	mFREE_B			;
	rr	mSHR1			;
	rr	mFREE_A			;
	djnz	mDS_ERR,_rCRC_L		;

	ret



;LMLMLMLMLMLMLMLMLMLMLMLMLMLMLMLMLMLMLML;
;sss 油温計測 サブルーチン sss
;LMLMLMLMLMLMLMLMLMLMLMLMLMLMLMLMLMLMLML;

sLM70
	jb	mFREE_C.0,rOIL_GO	;電源ON直後用

	mov	mOIL0XX,#'*'		;
	mov	mOILX0X,#'*'		;
	mov	mOILXX0,#'*'		;

	setb	mFREE_C.0		;

	ret				;

rOIL_GO
	clr	mFREE_A			;
	clr	mLM70			;

	clrb	LM70_cs			;温度データー格納開始

	snb	LM70_io			;
	setb	mFREE_A.7		;

	setb	LM70_sc			;
	clrb	LM70_sc			;
	snb	LM70_io			;
	setb	mLM70.7			;

	setb	LM70_sc			;
	clrb	LM70_sc			;
	snb	LM70_io			;
	setb	mLM70.6			;

	setb	LM70_sc			;
	clrb	LM70_sc			;
	snb	LM70_io			;
	setb	mLM70.5			;

	setb	LM70_sc			;
	clrb	LM70_sc			;
	snb	LM70_io			;
	setb	mLM70.4			;

	setb	LM70_sc			;
	clrb	LM70_sc			;
	snb	LM70_io			;
	setb	mLM70.3			;

	setb	LM70_sc			;
	clrb	LM70_sc			;
	snb	LM70_io			;
	setb	mLM70.2			;

	setb	LM70_sc			;
	clrb	LM70_sc			;
	snb	LM70_io			;
	setb	mLM70.1			;

	setb	LM70_sc			;
	clrb	LM70_sc			;
	snb	LM70_io			;
	setb	mLM70.0			;

	setb	LM70_cs			;温度データー格納終了


	jnb	mFREE_A.7,rLM_CAL	;ﾋﾞｯﾄがあればﾏｲﾅｽ温度

	clr	mFREE_A			;
	sub	mFREE_A,mLM70		;0-X
	mov	mBINA08,mFREE_A		;計算結果を入れる
;>>>
	call	sBCDCAL			;BCD計算へ
;<<<
	mov	mOIL0XX,#'-'		;油温
	mov	mOILX0X,mBCD_2		;
	mov	mOILXX0,mBCD_1		;

	add	mOILX0X,#48		;
	add	mOILXX0,#48		;

	ret				;


rLM_CAL
	mov	mBINA08,mLM70		;

;>>>
	call	sBCDCAL			;BCD計算へ
;<<<

	mov	mOIL0XX,mBCD_3		;油温
	mov	mOILX0X,mBCD_2		;
	mov	mOILXX0,mBCD_1		;

	add	mOIL0XX,#48		;
	add	mOILX0X,#48		;
	add	mOILXX0,#48		;

	ret				;



;---------------------------------------;
;sss その他サブルーチン sss
;---------------------------------------;

;sssssss BCD割り算(8bit÷10) ssssssssss;
sBCDCAL
	call	sBCDZAN			;1桁目
	mov	mBCD_1,mBINAXX		;余りを入れる

	mov	mBINA08,mSHOW08		;商を入れる
	call	sBCDZAN			;2桁目
	mov	mBCD_2,mBINAXX		;余りを入れる
	mov	mBCD_3,mSHOW08		;商を入れる

;結果は1桁目→mBCD_1､2桁目→mBCD_2､3桁目→mBCD_3

	ret				;リターン(サブルーチン終わり)


;サブルーチンのサブルーチン
;---桁移動比較---
sBCDZAN
	mov	mFREE_A,#8		;ループ数設定
	clr	mBINAXX			;
rBCD_0	rl	mBINA08			;
	rl	mBINAXX			;

	jc	rBCD_2			;比較8ビット超判定
	cjae	mBINAXX,#10,rBCD_1	;勝ち負け判定
	clrb	c			;キャリー0
	jmp	rWARI_4			;
rBCD_1	sub	mBINAXX,#10		;引き算(余りはここに残る)
	jmp	rBCD_3			;
rBCD_2	clr	mFREE_B			;0にする
	sub	mFREE_B,#10		;
	add	mBINAXX,mFREE_B		;
rBCD_3	setb	c			;キャリー1

;---計算結果入れ---
rWARI_4	rl	mSHOW08			;計算結果を入れる
	djnz	mFREE_A,rBCD_0		;ループ継続判定

	ret				;



;LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL;
;sss LCDサブルーチン sss
;LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL;

;(LCD自作キャラクター登録…無し)
;[LCD文字位置] (16進)
;　   |01|02|03|04|05|06|07|08|09|10|11|12|13|14|15|16|
;　---+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
;　01 |80|81|82|83|84|85|86|87|88|89|8A|8B|8C|8D|8E|8F|
;　---+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
;　02 |C0|C1|C2|C3|C4|C5|C6|C7|C8|C9|CA|CB|CC|CD|CE|CF|
;　---+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
;LCDキャラクターコード送信(表示)

sLCD_GO
	mov	mLCD_44,#80h		;1行目1桁目
	call	sLCD_E_			;
	mov	mLCD_44,mV_XVV		;1 電圧
	call	sLCD_RE			;
	mov	mLCD_44,mV_VXV		;2
	call	sLCD_RE			;
	mov	mLCD_44,#'.'		;3
	call	sLCD_RE			;
	mov	mLCD_44,mV_VVX		;4
	call	sLCD_RE			;
	mov	mLCD_44,#' '		;5
	call	sLCD_RE			;
	mov	mLCD_44,#' '		;6
	call	sLCD_RE			;
	mov	mLCD_44,mDS_0XX		;7 気温
	call	sLCD_RE			;
	mov	mLCD_44,mDS_X0X		;8
	call	sLCD_RE			;
	mov	mLCD_44,#'.'		;9
	call	sLCD_RE			;
	mov	mLCD_44,mDS_XX0		;10
	call	sLCD_RE			;
	mov	mLCD_44,#' '		;11
	call	sLCD_RE			;

	jb	not_to,rWDT01		;ｳｫｯﾁﾄﾞｯｸﾀｲﾏｰ発動チェック
	mov	mLCD_44,#'w'		;12 ｳｫｯﾁﾄﾞｯｸﾀｲﾏｰが発動した場合
	jmp	rWDT02			;
rWDT01
	mov	mLCD_44,#' '		;12 経過時間
;	mov	mLCD_44,mC_XH		;
;	mov	mLCD_44,mC_XS		;経過｢秒｣ 調整時用
rWDT02
	call	sLCD_RE			;


	mov	mLCD_44,mC_HX		;13
;	mov	mLCD_44,mC_SX		;経過｢秒｣ 調整時用
	call	sLCD_RE			;

	mov	mLCD_44,#':'		;14
	call	sLCD_RE			;
	mov	mLCD_44,mC_XM		;15
	call	sLCD_RE			;
	mov	mLCD_44,mC_MX		;16
	call	sLCD_RE			;

	mov	mLCD_44,#0C0h		;2行目1桁目
	call	sLCD_E_			;

	mov	mLCD_44,mA_XAA		;1 アンペア
	call	sLCD_RE			;
	mov	mLCD_44,mA_AXA		;2
	call	sLCD_RE			;
	mov	mLCD_44,#'.'		;3
	call	sLCD_RE			;
	mov	mLCD_44,mA_AAX		;4
	call	sLCD_RE			;
	mov	mLCD_44,#' '		;5
	call	sLCD_RE			;
	mov	mLCD_44,#' '		;6
	call	sLCD_RE			;
	mov	mLCD_44,mOIL0XX		;7 油温
	call	sLCD_RE			;
	mov	mLCD_44,mOILX0X		;8
	call	sLCD_RE			;
	mov	mLCD_44,mOILXX0		;9
	call	sLCD_RE			;
	mov	mLCD_44,#' '		;10
	call	sLCD_RE			;
	mov	mLCD_44,#' '		;11
	call	sLCD_RE			;
	mov	mLCD_44,mT_XH		;12 時計
	call	sLCD_RE			;
	mov	mLCD_44,mT_HX		;13
	call	sLCD_RE			;
	mov	mLCD_44,#':'		;14
	call	sLCD_RE			;
	mov	mLCD_44,mT_XM		;15
	call	sLCD_RE			;
	mov	mLCD_44,mT_MX		;16
	call	sLCD_RE			;

	clr	wdt			;▼

	ret				;

;sssssss LCD E 送信関係 ssssssssssssssss;
sLCD_E_
	call	sBUSY7			;LCD受付OKになるまで待つ

	setb	LCD_E			;

	and	rc,#00001111b		;RC4～7クリア

	snb	mLCD_44.7		;
	setb	rc.7			;
	snb	mLCD_44.6		;
	setb	rc.6			;
	snb	mLCD_44.5		;
	setb	rc.5			;
	snb	mLCD_44.4		;
	setb	rc.4			;

	clrb	LCD_E			;


	setb	LCD_E			;

	and	rc,#00001111b		;RC4～7クリア

	snb	mLCD_44.3		;
	setb	rc.7			;
	snb	mLCD_44.2		;
	setb	rc.6			;
	snb	mLCD_44.1		;
	setb	rc.5			;
	snb	mLCD_44.0		;
	setb	rc.4			;

	clrb	LCD_E			;

	ret				;リターン(サブルーチン終わり)

;sssssss LCDキャラクター表示 sssssssssss;
sLCD_RE
	call	sBUSY7			;LCD受付OKになるまで待つ

	setb	LCD_RS			;
	setb	LCD_E			;

	and	rc,#00001111b		;RC4～7クリア

	snb	mLCD_44.7		;
	setb	rc.7			;
	snb	mLCD_44.6		;
	setb	rc.6			;
	snb	mLCD_44.5		;
	setb	rc.5			;
	snb	mLCD_44.4		;
	setb	rc.4			;

	clrb	LCD_E			;
	clrb	LCD_RS			;


	setb	LCD_RS			;
	setb	LCD_E			;

	and	rc,#00001111b		;RC4～7クリア

	snb	mLCD_44.3		;
	setb	rc.7			;
	snb	mLCD_44.2		;
	setb	rc.6			;
	snb	mLCD_44.1		;
	setb	rc.5			;
	snb	mLCD_44.0		;
	setb	rc.4			;

	clrb	LCD_E			;
	clrb	LCD_RS			;

	ret				;リターン(サブルーチン終わり)

;sssssss LCDビジーチェック sssssssssssss;

sBUSY7
	setb	rp0			;ページ変更(Bank 1へ)
;Bank 1
	setb	trisc.7			;RC7を入力に変更
	clrb	rp0			;ページ変更(Bank 0へ戻す)

rL_BUSY
;	clrb	mFREE_C.7		;

	setb	LCD_RW			;
	setb	LCD_E			;

;	snb	rc.7			;
;	setb	mFREE_C.7		;

	jb	rc.7,$			;ビジー信号が消えるまでここで待つ

	clrb	LCD_E			;4bitの下位半分を受信したことにする
	setb	LCD_E			;

	clrb	LCD_E			;
	clrb	LCD_RW			;

;	jb	mFREE_C.7,rL_BUSY	;ビジー信号があれば繰り返す

	setb	rp0			;ページ変更(Bank 1へ)
;Bank 1
	clrb	trisc.7			;RC7を出力に変更
	clrb	rp0			;ページ変更(Bank 0へ戻す)

	ret				;リターン(サブルーチン終わり)
