;DS18S20オートバイ温度計 Ver 1.12	NAO TECHUNOHUT		2005-11-01(火)
;
;[プログラム概要]
; ･DS18S20デジタル温度センサー使用のオートバイ用外気温度計｡
;　(温度センサーのプログラムについてはHP参照)
; ･3桁7セグメントLED表示とする｡(秋月電子通商で200円/個)
; ･7セグメントLEDはダイナミック駆動とする｡
;
;	　　Ａ
;	　　─
;	Ｆ│Ｇ│Ｂ
;	　　─
;	Ｅ│　│Ｃ
;	　　─　．DP	     E D P C G B F A
;	　　Ｄ		rb,# X X X X X X X X b
;
; ･温度の表示ステップは0.1ﾟC｡
; ･表示例 ｢15.2｣ ｢07.3｣ ｢-2.8｣
; ･マイナス表示は-9.8まで｡それを超えた場合は｢LLL｣表示とする｡
; ･プラス表示は84.7まで｡
; ･85ﾟCの場合は｢---｣表示とする｡(DS18S20立ち上げ直後の初期状態表示不具合防止)
; ･85ﾟCを超えた場合は｢HHH｣表示とする｡
; ･電源ON時は7セグメントLEDを約1秒間全点灯表示させる｡｢8.8.8.｣
; ･電源ON時のみバッテリー電圧を約2秒間表示する｡
; ･DS18S20のエラーチェックは次の分類表示とする｡
;　　断線エラー…｢Er1｣
;　　短絡エラー…｢Er2｣
;　　リセットエラー…｢ER3｣
;　　CRCエラー…｢Er4｣
; ･オシレーターは基本的に内部 RC 4MHzを使用する｡
;　　(DS18S20デジタル温度センサーの通信タイミングを計りやすくするため)
;　　タイマー2(8bit)のプリスケーラを1:1設定にして1カウント当たり1μsにする｡
;　　タイマー1(16bit)もプリスケーラを1:1設定にして1カウント当たり1μsにする｡
;　　タイマー0(8bit)はウォッチドックタイマーに使用する｡(初期設定のままで約2秒)
; ･温度の計測間隔は約1秒とする｡温度計測変換待ち時間に7セグメントLED表示する｡
;　　オシレーターは内部 RC 250kHzに切替え､
;　　　タイマー1のオーバーフローを約1秒の間隔に利用する｡
;　　その場合､7セグメントLEDの桁切替周波数は62,500Hzでありチラツキの問題はない｡
;　　(1命令0.000016秒x8命令分)
;
;
;[PIC選定その他仕様]
; ･PIC16F819-I/P使用｡(秋月電子通商で300円/個)
; ･MCLRは外配線を簡略するため内部接続モードとする｡
;			     ┌─┰─┐
;	7LED_3桁目	 RA2 ┥	     ┝ RA1	DS18S20温度センサー
;	7LED_2桁目	 RA3 ┥	     ┝ RA0	電圧A/D
;	7LED_1桁目	 RA4 ┥	     ┝ RA7	青LED
;	未使用		(#04)┥PIC16 ┝(#15)	未使用
;			 Vss ┥  F819┝ Vdd	5.0V
;	7LED_A		 RB0 ┥	     ┝ RB7	7LED_E
;	7LED_F		 RB1 ┥	     ┝ RB6	7LED_D
;	7LED_B		 RB2 ┥	     ┝ RB5	7LED_DP
;	7LED_G		 RB3 ┥	     ┝ RB4	7LED_C
;			     └───┘
;	※#04(RA5)は入力のみなので注意
;
;-------PIC初期状態確認-----------------;(▲:変更必要)
;Bank 0
;	tmr0		xxxxxxxx	;　タイマー0の状態
;	status		00011xxx	;　Bankセレクト設定､各旗の状態
;	porta		xxx00000	;▲RAピン出力状態(xは不定)
;	portb		xxxxxxxx	;▲RBピン出力状態(xは不定)
;	intcon		0000000x	;　割り込み他､設定
;	pir1		-0--0000	;　旗状態(A/D､タイマー､
;	pir2		---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	;　
;	adresl		xxxxxxxx	;　A/D変換値0～8bit
;	adcon1		00--0000	;▲A/Dピン設定
;Bank 2
;	eedata		xxxxxxxx	;　EEメモリーの状態 Lo？
;	eeadr		xxxxxxxx	;　EEメモリーのアドレス位置 Lo
;	eedath		--xxxxxx	;　EEメモリーの状態 Hi？
;	eeadrh		-----xxx	;　EEメモリーのアドレス位置 Hi
;Bank 3
;	eecon1		x--xx000	;　EEメモリー関係設定
;	eecon2		--------	;　EEメモリー関係設定？
;
;[凡例] (自分で分かりやすいように目印を付ける)
; mXXX:メモリー  rXXX:ラベル  sXXX:サブルーチン  vXXX:変数  ★:調整箇所など
;
; CVASM16アセンブラ用記述
;-------PICコンフィギュレーション設定---;

	include	'16f819.inc'

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

	id	'0112'			;Ver1.12

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

mFREE_A	=	20h			;汎用カウンターなど
mFREE_B	=	21h			;　　〃
mFREE_C	=	22h			;　　〃

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

mBCD_0	=	29h			;少数(0or5)表示用

mSOUSIN	=	2Ah			;DS18S20送信データー用
mDS18_L	=	2Bh			;DS18S20温度データー下位バイト
mDS18_H	=	2Ch			;DS18S20温度データー上位バイト
mDATA_2	=	2Dh			;？(THレジスタまたはユーザー･バイト1)
mDATA_3	=	2Eh			;？(TLレジスタまたはユーザー･バイト2)
mDATA_4	=	2Fh			;？(予約済み)
mDATA_5	=	30h			;？(予約済み)
mDATA_6	=	31h			;？(温度変換カウンタ(COUNT REMAIN))
mDATA_7	=	32h			;？(温度変換カウンタ(COUNT PERﾟC))
mDS_CRC	=	33h			;CRC
mSHR1	=	34h			;計算で得たCRC

mERROR	=	35h			;エラーチェック用
m7SEG_X	=	36h			;7セグメントLED表示変換用


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

	clr	wdt			;ウォッチドックタイマー
	clr	ra			;
	clr	rb			;
	clr	mERROR			;エラーチェック
	setb	ra.1			;DS18S20準備
	mov	adcon0,#11000001b	;ｸﾛｯｸ内蔵RC設定､ﾁｬﾝﾈﾙRA0､A/D有効

	mov	t1con,#00000001b	;プリスケール1:1
	mov	t2con,#00000100b	;プリスケール1:1

	setb	rp0			;ページ変更(Bank 1へ)
;Bank 1
	mov	trisa,#00000001b	;RA0は入力｡他はすべて出力ピンに設定
	mov	trisb,#00000000b	;RBをすべて出力ピンに設定
	mov	osccon,#01100000b	;内蔵オシレーター周波数を4MHzに設定
	mov	adcon1,#00001110b	;A/Dは8bitモードで
;					;RA.0のみA/Dに設定(基準電圧はVdd)
	clrb	rp0			;ページ変更(Bank 0へ戻す)
;Bank 0

;7セグメントLED全点灯準備(電源ON時のみ)
	mov	mBCD_0,#11111111b	;｢8.｣パターンを入れる
	mov	mBCD_1,#11111111b	;｢8.｣パターンを入れる
	mov	mBCD_2,#11111111b	;｢8.｣パターンを入れる
;｢青LED｣の点灯
	setb	ra.7			;☆青LEDのON

;7セグメントLED点灯
	call	s7DYNA1			;7セグメントLEDダイナッミク点灯へ

;｢青LED｣の消灯
	clrb	ra.7			;☆青LEDのOFF


	clr	wdt			;ウォッチドックタイマー

;バッテリー電圧計測(電源ON時のみ表示)

	setb	go_done			;A/D変換開始
	jb	go_done,$		;A/D変換終了まで待つ
rAD2
	mov	mFREE_A,adresh		;8ビットデーターをメモリーへコピー

;少し待つ(0.065536秒くらい)
	clr	tmr1l			;タイマー1Lクリヤー
	clr	tmr1h			;タイマー1Hクリヤー
	clrb	tmr1if			;タイマー1オーバーフロービットクリヤー
	jnb	tmr1if,$		;

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

	cjne	mFREE_A,adresh,rAD2	;先に計測したものと同じか比較する

	clrb	adon			;A/D省電力化

;電圧計測データーをBCD化
	mov	mBINA08,adresh		;
	call	sBCDCAL			;BCD計算へ

;BCD→7セグメントLED表示変換
	mov	m7SEG_X,mBCD_1		;1桁目
	call	s7SEG			;7セグメントLEDパターン変換
	mov	mBCD_0,m7SEG_X		;

	mov	m7SEG_X,mBCD_2		;2桁目
	call	s7SEG			;7セグメントLEDパターン変換
	mov	mBCD_1,m7SEG_X		;
;小数点のDP分を足す
	or	mBCD_1,#00100000b	;☆｢DP｣を点灯

	mov	m7SEG_X,mBCD_3		;3桁目
	call	s7SEG			;7セグメントLEDパターン変換
	mov	mBCD_2,m7SEG_X		;

;7セグメントLED点灯
	call	s7DYNA1			;7セグメントLEDダイナッミク点灯へ



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

rREPEAT
;DS18S20計測開始

	clr	wdt			;ウォッチドックタイマー

	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

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

;データーシートでは変換に0.75秒必要
;その変換待ち時間に7セグメントLEDを表示するようにする
;変換表示時間は約2秒間隔にする

rINDIC

;｢青LED｣の点滅
	clrb	ra.7			;☆青LEDのOFF

;7セグメントLED点灯
	call	s7DYNA1			;7セグメントLEDダイナッミク点灯へ

;｢青LED｣の点滅
	setb	ra.7			;☆青LEDのON

	test	mERROR			;ゼロかどうか
	jnz	rREPEAT			;

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

;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	m7SEG_X,mBCD_0		;少数点第1位
	call	s7SEG			;7セグメントLEDパターン変換
	mov	mBCD_0,m7SEG_X		;

	mov	m7SEG_X,mBCD_1		;1桁目
	call	s7SEG			;7セグメントLEDパターン変換
	mov	mBCD_1,m7SEG_X		;

	mov	m7SEG_X,mBCD_2		;2桁目
	call	s7SEG			;7セグメントLEDパターン変換
	mov	mBCD_2,m7SEG_X		;

;小数点のDP分を足す

	or	mBCD_1,#00100000b	;☆｢DP｣を点灯

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

rBACK
	jmp	rREPEAT			;メインループ最初へ


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



;断線エラーがあった場合｢Er1｣表示
rERROR1
	mov	mBCD_0,#00010100b	;☆｢1｣パターンを入れる
	mov	mBCD_1,#10001000b	;☆｢r｣パターンを入れる
	mov	mBCD_2,#11001011b	;☆｢E｣パターンを入れる
	jmp	rINDIC			;

;短絡エラーがあった場合｢Er2｣表示
rERROR2
	mov	mBCD_0,#11001101b	;☆｢2｣パターンを入れる
	mov	mBCD_1,#10001000b	;☆｢r｣パターンを入れる
	mov	mBCD_2,#11001011b	;☆｢E｣パターンを入れる
	jmp	rINDIC			;

;リセットエラーがあった場合｢Er3｣表示
rERROR3
	mov	mBCD_0,#01011101b	;☆｢3｣パターンを入れる
	mov	mBCD_1,#10001000b	;☆｢r｣パターンを入れる
	mov	mBCD_2,#11001011b	;☆｢E｣パターンを入れる
	jmp	rINDIC			;


;CRCエラーがあった場合｢Er4｣表示
rERROR4
	mov	mBCD_0,#00011110b	;☆｢4｣パターンを入れる
	mov	mBCD_1,#10001000b	;☆｢r｣パターンを入れる
	mov	mBCD_2,#11001011b	;☆｢E｣パターンを入れる
	clrb	mERROR.4		;エラービットクリヤー
	jmp	rBACK			;

;-9.9ﾟCを超えた場合は｢LLL｣表示とする｡
rLOW
	mov	mBCD_0,#11000010b	;☆｢L｣パターンを入れる
	mov	mBCD_1,#11000010b	;
	mov	mBCD_2,#11000010b	;
	jmp	rBACK			;

;85ﾟCの場合は｢---｣表示とする｡
rNNN
	mov	mBCD_0,#00001000b	;☆｢-｣パターンを入れる
	mov	mBCD_1,#00001000b	;
	mov	mBCD_2,#00001000b	;
	jmp	rBACK			;

;85ﾟCを超えた場合は｢HHH｣表示とする｡
rHIGH
	mov	mBCD_0,#10011110b	;☆｢H｣パターンを入れる
	mov	mBCD_1,#10011110b	;
	mov	mBCD_2,#10011110b	;
	jmp	rBACK			;



;sssssss 7セグメントLEDのダイナミック点灯 1秒

s7DYNA1
	setb	rp0			;ページ変更(Bank 1へ)
;Bank 1
	mov	osccon,#00100000b	;内蔵オシレーター周波数を250kHzに設定
	mov	osctune,#00001111b	;★内蔵オシレーター微調整

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

	clr	tmr1l			;タイマー1Lクリヤー
	clr	tmr1h			;タイマー1Hクリヤー
	clrb	tmr1if			;タイマー1オーバーフロービットクリヤー

s7MIC1
	and	ra,#11100011b		;☆FET全OFF(2Cycles)
	mov	rb,mBCD_0		;1桁目準備(2Cycles)
	setb	ra.4			;☆FET1_ON(1Cycles)
	nop				;(1Cycles)
	nop				;(1Cycles)
	nop				;(1Cycles)

	and	ra,#11100011b		;☆FET全OFF(2Cycles)
	mov	rb,mBCD_1		;2桁目準備(2Cycles)
	setb	ra.3			;☆FET2_ON(1Cycles)
	nop				;(1Cycles)
	nop				;(1Cycles)
	nop				;(1Cycles)

	and	ra,#11100011b		;☆FET全OFF(2Cycles)
	mov	rb,mBCD_2		;3桁目準備(2Cycles)
	setb	ra.2			;☆FET3_ON(1Cycles)

	jnb	tmr1if,s7MIC1		;(jmp 3Cycles)

	and	ra,#11100011b		;☆FET全OFF
	clr	rb			;(念のためRB全クリヤー)

	setb	rp0			;ページ変更(Bank 1へ)
;Bank 1
	mov	osctune,#00000000b	;内蔵オシレーター微調整を初期値に戻す
	mov	osccon,#01100000b	;内蔵オシレーター周波数を4MHzに戻す
	clrb	rp0			;ページ変更(Bank 0へ戻す)
;Bank 0
	ret				;リターン(サブルーチン終わり)


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

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

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

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

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

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

	jb	ra.1,$-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	ra.1,$-2		;ビット1まで待つ
	mov	mFREE_A,tmr2		;タイマー2の値をメモリーに格納
	cjbe	mFREE_A,#60,_rERRO3	;リセットエラー判定
	cjae	mFREE_A,#240,_rERRO3	;　　　〃

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

_rERR_r
	setb	ra.1			;あらかじめHiにしておく
	setb	rp0			;ページ変更(Bank 1へ)
	clrb	trisa.1			;◆出力に変更
	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	ra.1			;
	mov	tmr2,#196		;(256-60=196)
	clrb	tmr2if			;
	jnb	tmr2if,$		;60μs待つ
	setb	ra.1			;送信終わりの合図
	rr	mSOUSIN			;
	djnz	mFREE_A,_rSOUSI		;

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

;｢1｣だった場合
_rWRIT1
	clrb	ra.1			;
	setb	ra.1			;
	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	ra.1			;

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

	nop				;
	nop				;
	nop				;

	clc				;クリアキャリー
	snb	ra.1			;
	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	ra.1,$			;ビット立つまで待つ


;｢1｣だった場合(｢0｣だった場合の後処理共通)
rNZERO
	setb	ra.1			;
	setb	rp0			;ページ変更(Bank 1へ)
	clrb	trisa.1			;◆出力に変更
	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	mFREE_C,#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	mFREE_C,_rCRC_L		;
	ret



;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



;sssssss 7セグメントLED変換 ssssssssssss;

s7SEG
	cjne	m7SEG_X,#0,$+6		;(4Words)
	mov	m7SEG_X,#11010111b	;☆0

	cjne	m7SEG_X,#1,$+6		;
	mov	m7SEG_X,#00010100b	;☆1(10100(2進)=20(10進))

	cjne	m7SEG_X,#2,$+6		;
	mov	m7SEG_X,#11001101b	;☆2

	cjne	m7SEG_X,#3,$+6		;
	mov	m7SEG_X,#01011101b	;☆3

	cjne	m7SEG_X,#4,$+6		;
	mov	m7SEG_X,#00011110b	;☆4

	cjne	m7SEG_X,#5,$+6		;
	mov	m7SEG_X,#01011011b	;☆5

	cjne	m7SEG_X,#6,$+6		;
	mov	m7SEG_X,#11011011b	;☆6

	cjne	m7SEG_X,#7,$+6		;
	mov	m7SEG_X,#00010111b	;☆7

	cjne	m7SEG_X,#8,$+6		;
	mov	m7SEG_X,#11011111b	;☆8

	cjne	m7SEG_X,#9,$+6		;
	mov	m7SEG_X,#01011111b	;☆9

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